Fix wholesale app orders, polish admin/user chrome, and harden order detail UX.
Customer placements now store WHOLESALE (with a migration for prior RETAIL rows), order status opens in a right drawer, logout asks for confirm, and the dashboard profile nudge plus IRANSans panel typeface are tightened for readability. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -32,11 +32,7 @@
|
||||
<Spinner :spinning="cartData.loadingPage" tip="درحال دریافت اطلاعات">
|
||||
<container class="cart__body">
|
||||
<!-- Step 1: the basket -->
|
||||
<PullRefresh v-if="cartData.step === 1" v-model="refreshing" @refresh="onRefresh">
|
||||
<template #pulling><Loading size="18" /></template>
|
||||
<template #loosing><Loading size="18" /></template>
|
||||
<template #loading><Loading size="18" /></template>
|
||||
<template #success><span /></template>
|
||||
<AppPullRefresh v-if="cartData.step === 1" v-model="refreshing" @refresh="onRefresh">
|
||||
<template v-if="cart.items.length">
|
||||
<div class="cart__items" :class="{ 'is-revealed': revealed }">
|
||||
<CartItem
|
||||
@@ -62,7 +58,7 @@
|
||||
دیدن محصولات
|
||||
</button>
|
||||
</section>
|
||||
</PullRefresh>
|
||||
</AppPullRefresh>
|
||||
|
||||
<!-- Step 2: submitted -->
|
||||
<section v-else class="cart__done">
|
||||
@@ -153,7 +149,7 @@
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Drawer, Form, FormItem, Textarea } from 'ant-design-vue'
|
||||
import { Loading, PullRefresh } from 'vant'
|
||||
import AppPullRefresh from '../components/ui/AppPullRefresh.vue'
|
||||
import dialogEmpty4 from '../assets/img/empty/dialogEmpty4.svg'
|
||||
import loginDialogImage from '../assets/img/empty/dialogLogin.svg'
|
||||
import Icon from '../components/icon/Icon.vue'
|
||||
@@ -218,6 +214,9 @@ const submitOrder = async () => {
|
||||
// Ignored by the server, which takes the customer from the token; still
|
||||
// sent so older builds keep validating. Removed in Phase 2.
|
||||
customerId: session.customerId ?? undefined,
|
||||
// Wholesale (عمده) — same as legacy mobile; server also forces this for
|
||||
// customer placements so admin omde list shows the order.
|
||||
channel: 'WHOLESALE',
|
||||
items: cart.items.map((item) => {
|
||||
const variant = cart.variant(item)
|
||||
return {
|
||||
|
||||
@@ -34,11 +34,7 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<PullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<template #pulling><Loading size="18" /></template>
|
||||
<template #loosing><Loading size="18" /></template>
|
||||
<template #loading><Loading size="18" /></template>
|
||||
<template #success><span /></template>
|
||||
<AppPullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<container class="home__body" :class="{ 'is-revealed': revealed }">
|
||||
<RateStrip :quote="goldPrice" class="home__rate reveal" :style="revealDelay(0)" />
|
||||
|
||||
@@ -103,7 +99,7 @@
|
||||
</section>
|
||||
|
||||
</container>
|
||||
</PullRefresh>
|
||||
</AppPullRefresh>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -111,7 +107,7 @@
|
||||
import { brand } from '../brand'
|
||||
import { computed, onActivated, onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Loading, PullRefresh } from 'vant'
|
||||
import AppPullRefresh from '../components/ui/AppPullRefresh.vue'
|
||||
import Icon from '../components/icon/Icon.vue'
|
||||
import RateStrip from '../components/home/RateStrip.vue'
|
||||
import type { ShowcaseSlide } from '../components/home/ShowcaseSlider.vue'
|
||||
|
||||
@@ -36,11 +36,7 @@
|
||||
</PageBar>
|
||||
|
||||
<Spinner :spinning="loading && !rows.length" tip="درحال دریافت اطلاعات">
|
||||
<PullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<template #pulling><Loading size="18" /></template>
|
||||
<template #loosing><Loading size="18" /></template>
|
||||
<template #loading><Loading size="18" /></template>
|
||||
<template #success><span /></template>
|
||||
<AppPullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<container class="cho__body">
|
||||
<template v-if="rows.length">
|
||||
<div class="cho__list">
|
||||
@@ -99,7 +95,7 @@
|
||||
<!-- Sentinel for the infinite scroll, as the reference used (:216). -->
|
||||
<div ref="sentinel" class="cho__sentinel" />
|
||||
</container>
|
||||
</PullRefresh>
|
||||
</AppPullRefresh>
|
||||
</Spinner>
|
||||
|
||||
<Drawer
|
||||
@@ -146,7 +142,7 @@
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { Drawer } from 'ant-design-vue'
|
||||
import { Loading, PullRefresh } from 'vant'
|
||||
import AppPullRefresh from '../../components/ui/AppPullRefresh.vue'
|
||||
import Icon from '../../components/icon/Icon.vue'
|
||||
import PageBar from '../../components/ui/PageBar.vue'
|
||||
import Spinner from '../../components/Spinner.vue'
|
||||
|
||||
@@ -40,11 +40,7 @@
|
||||
</PageBar>
|
||||
|
||||
<Spinner :spinning="loading && !rows.length" tip="درحال دریافت اطلاعات">
|
||||
<PullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<template #pulling><Loading size="18" /></template>
|
||||
<template #loosing><Loading size="18" /></template>
|
||||
<template #loading><Loading size="18" /></template>
|
||||
<template #success><span /></template>
|
||||
<AppPullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<container class="cch__body">
|
||||
<div v-if="rows.length" class="cch__list">
|
||||
<article
|
||||
@@ -88,7 +84,7 @@
|
||||
<button type="button" class="cch__retry" @click="load">تلاش دوباره</button>
|
||||
</section>
|
||||
</container>
|
||||
</PullRefresh>
|
||||
</AppPullRefresh>
|
||||
</Spinner>
|
||||
|
||||
<Drawer
|
||||
@@ -143,7 +139,7 @@
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Drawer } from 'ant-design-vue'
|
||||
import { Loading, PullRefresh } from 'vant'
|
||||
import AppPullRefresh from '../../components/ui/AppPullRefresh.vue'
|
||||
import Icon from '../../components/icon/Icon.vue'
|
||||
import PageBar from '../../components/ui/PageBar.vue'
|
||||
import Spinner from '../../components/Spinner.vue'
|
||||
|
||||
@@ -52,11 +52,7 @@
|
||||
</PageBar>
|
||||
|
||||
<Spinner :spinning="loading && !rows.length && !details.length" tip="درحال دریافت اطلاعات">
|
||||
<PullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<template #pulling><Loading size="18" /></template>
|
||||
<template #loosing><Loading size="18" /></template>
|
||||
<template #loading><Loading size="18" /></template>
|
||||
<template #success><span /></template>
|
||||
<AppPullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<container class="rep__body">
|
||||
<!-- ── کلیات حساب ─────────────────────────────────────────── -->
|
||||
<template v-if="activeKey === '1'">
|
||||
@@ -124,7 +120,7 @@
|
||||
<div v-if="loading && (rows.length || details.length)" class="rep__more">در حال دریافت…</div>
|
||||
<div ref="sentinel" class="rep__sentinel" />
|
||||
</container>
|
||||
</PullRefresh>
|
||||
</AppPullRefresh>
|
||||
</Spinner>
|
||||
|
||||
<Drawer
|
||||
@@ -151,7 +147,7 @@
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { Drawer } from 'ant-design-vue'
|
||||
import { Loading, PullRefresh } from 'vant'
|
||||
import AppPullRefresh from '../../components/ui/AppPullRefresh.vue'
|
||||
import Icon from '../../components/icon/Icon.vue'
|
||||
import PageBar from '../../components/ui/PageBar.vue'
|
||||
import Spinner from '../../components/Spinner.vue'
|
||||
|
||||
@@ -61,11 +61,7 @@
|
||||
indicator, over the results already on screen.
|
||||
-->
|
||||
<div>
|
||||
<PullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<template #pulling><Loading size="18" /></template>
|
||||
<template #loosing><Loading size="18" /></template>
|
||||
<template #loading><Loading size="18" /></template>
|
||||
<template #success><span /></template>
|
||||
<AppPullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<container class="search__body">
|
||||
<div v-if="loadingPage && !allProducts.length" class="search__skeleton" aria-hidden="true">
|
||||
<div class="search__skHead">
|
||||
@@ -117,7 +113,7 @@
|
||||
<p>محصولی با این مشخصات پیدا نشد.</p>
|
||||
</section>
|
||||
</container>
|
||||
</PullRefresh>
|
||||
</AppPullRefresh>
|
||||
</div>
|
||||
|
||||
<!-- A bottom sheet over a see-through backdrop (teleported to <body>);
|
||||
@@ -133,7 +129,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { Loading, PullRefresh } from 'vant'
|
||||
import AppPullRefresh from '../../components/ui/AppPullRefresh.vue'
|
||||
import Icon from '../../components/icon/Icon.vue'
|
||||
import PageBar from '../../components/ui/PageBar.vue'
|
||||
import Spinner from '../../components/Spinner.vue'
|
||||
|
||||
@@ -48,15 +48,36 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<PullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<template #pulling><Loading size="18" /></template>
|
||||
<template #loosing><Loading size="18" /></template>
|
||||
<template #loading><Loading size="18" /></template>
|
||||
<template #success><span /></template>
|
||||
<AppPullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<container class="dash__body" :class="{ 'is-revealed': revealed }">
|
||||
<!-- Signed in: real position from GET /customers/:id -->
|
||||
<template v-if="customer">
|
||||
<section class="dash__balance reveal" :style="revealDelay(0)">
|
||||
<!--
|
||||
Incomplete profile notice — same gate as ProfileView's
|
||||
"تکمیل پروفایل" button (docs/plans/2026-10-16-dashboard-incomplete-profile-banner-design.md).
|
||||
-->
|
||||
<section
|
||||
v-if="needsProfileComplete"
|
||||
class="dash__profileNudge reveal"
|
||||
:style="revealDelay(0)"
|
||||
>
|
||||
<div class="dash__profileNudgeIcon" aria-hidden="true">
|
||||
<Icon icon="vuesax-linear:info-circle" size="16" />
|
||||
</div>
|
||||
<div class="dash__profileNudgeCopy">
|
||||
<h3>پروفایل شما تکمیل نشده است</h3>
|
||||
<p>برای ادامه، مدارک پروفایل را بارگذاری کنید.</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="dash__profileNudgeCta"
|
||||
@click="router.push({ name: 'completeProfile' })"
|
||||
>
|
||||
تکمیل پروفایل
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section class="dash__balance reveal" :style="revealDelay(needsProfileComplete ? 1 : 0)">
|
||||
<div class="dash__balanceHead">
|
||||
<div>
|
||||
<div class="dash__eyebrow">{{ remainText }}</div>
|
||||
@@ -97,7 +118,7 @@
|
||||
</section>
|
||||
|
||||
<!-- Nav grid -->
|
||||
<section class="dash__section reveal" :style="revealDelay(1)">
|
||||
<section class="dash__section reveal" :style="revealDelay(customer && needsProfileComplete ? 2 : 1)">
|
||||
<div class="dash__access">
|
||||
<button
|
||||
v-for="item in list"
|
||||
@@ -119,12 +140,12 @@
|
||||
</section>
|
||||
|
||||
<!-- Live 18k rate — same strip the home screen uses -->
|
||||
<section class="dash__section reveal" :style="revealDelay(2)">
|
||||
<section class="dash__section reveal" :style="revealDelay(customer && needsProfileComplete ? 3 : 2)">
|
||||
<SectionHead title="نرخ روز" subtitle="آخرین نرخ اعلامشده" />
|
||||
<RateStrip :quote="goldPrice" />
|
||||
</section>
|
||||
</container>
|
||||
</PullRefresh>
|
||||
</AppPullRefresh>
|
||||
|
||||
<DialogVant :timeOut="-1" v-model:show="data.notify" :closeOnClickOverlay="true">
|
||||
<template v-slot:img>
|
||||
@@ -159,7 +180,7 @@
|
||||
import { brand } from '../../brand'
|
||||
import { computed, onActivated, onMounted, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Loading, PullRefresh } from 'vant'
|
||||
import AppPullRefresh from '../../components/ui/AppPullRefresh.vue'
|
||||
import Icon from '../../components/icon/Icon.vue'
|
||||
import SectionHead from '../../components/home/SectionHead.vue'
|
||||
import RateStrip from '../../components/home/RateStrip.vue'
|
||||
@@ -190,6 +211,15 @@ const grams = computed(() =>
|
||||
customer.value ? Math.abs(parseFloat(customer.value.goldDebtGrams)) : 0,
|
||||
)
|
||||
|
||||
/**
|
||||
* Same gate as ProfileView's "تکمیل پروفایل" CTA: show while documents have
|
||||
* not been submitted (STEP_TWO_SUBMITTED) or approved (VERIFIED).
|
||||
*/
|
||||
const needsProfileComplete = computed(() => {
|
||||
const step = customer.value?.verificationStep
|
||||
return Boolean(step) && step !== 'VERIFIED' && step !== 'STEP_TWO_SUBMITTED'
|
||||
})
|
||||
|
||||
const data = reactive({ notify: false, loginNotify: false })
|
||||
|
||||
const BASE_TILES = [
|
||||
@@ -370,6 +400,68 @@ onMounted(async () => {
|
||||
padding-bottom: 90px;
|
||||
}
|
||||
|
||||
.dash__profileNudge {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 12px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid alpha(@wine, 16%);
|
||||
background: @wineWash;
|
||||
}
|
||||
|
||||
.dash__profileNudgeIcon {
|
||||
flex: 0 0 auto;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 9px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: @wine;
|
||||
background: alpha(@wine, 10%);
|
||||
}
|
||||
|
||||
.dash__profileNudgeCopy {
|
||||
flex: 1 1 140px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dash__profileNudgeCopy h3 {
|
||||
margin: 0;
|
||||
font-size: 12.5px;
|
||||
font-weight: 500;
|
||||
color: @ink;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.dash__profileNudgeCopy p {
|
||||
margin: 2px 0 0;
|
||||
font-size: 11.5px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
color: @inkMuted;
|
||||
}
|
||||
|
||||
.dash__profileNudgeCta {
|
||||
flex: 0 0 auto;
|
||||
margin-inline-start: auto;
|
||||
padding: 7px 11px;
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
font-size: 11.5px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
background: @primary;
|
||||
}
|
||||
|
||||
.dash__profileNudgeCta:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.dash__balance {
|
||||
padding: 16px;
|
||||
border-radius: 20px;
|
||||
|
||||
@@ -48,11 +48,7 @@
|
||||
</PageBar>
|
||||
|
||||
<Spinner :spinning="loading" tip="درحال دریافت اطلاعات">
|
||||
<PullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<template #pulling><Loading size="18" /></template>
|
||||
<template #loosing><Loading size="18" /></template>
|
||||
<template #loading><Loading size="18" /></template>
|
||||
<template #success><span /></template>
|
||||
<AppPullRefresh v-model="refreshing" @refresh="onRefresh">
|
||||
<container class="ord__body">
|
||||
<template v-if="filteredOrders.length">
|
||||
<div class="ord__list">
|
||||
@@ -65,7 +61,7 @@
|
||||
<p>سفارشی با این مشخصات پیدا نشد.</p>
|
||||
</section>
|
||||
</container>
|
||||
</PullRefresh>
|
||||
</AppPullRefresh>
|
||||
</Spinner>
|
||||
|
||||
<Drawer
|
||||
@@ -73,22 +69,22 @@
|
||||
placement="bottom"
|
||||
v-if="viewData.item"
|
||||
:closable="false"
|
||||
height="100vh"
|
||||
class="rtl"
|
||||
:bodyStyle="{ padding: 0, position: 'relative' }"
|
||||
height="100%"
|
||||
:z-index="2000"
|
||||
class="rtl orders-detail-drawer"
|
||||
:bodyStyle="{ padding: 0, height: '100%', overflow: 'hidden' }"
|
||||
>
|
||||
<div class="detail">
|
||||
<header class="detail__bar">
|
||||
<button type="button" class="detail__close" aria-label="بستن" @click="viewData.model = false">
|
||||
<button type="button" class="detail__close" aria-label="بستن" @click="closeDetail">
|
||||
<Icon icon="vuesax-linear:arrow-right-1" size="20" />
|
||||
</button>
|
||||
<h2 class="detail__title">جزئیات سفارش</h2>
|
||||
<span class="detail__spacer" aria-hidden="true" />
|
||||
</header>
|
||||
|
||||
<div class="detail__scroll">
|
||||
<!-- Progress -->
|
||||
<section class="detail__block">
|
||||
<!-- Progress — real OrderStatus pipeline (not the old 4-step collapse) -->
|
||||
<section v-if="currentStep >= 0" class="detail__block">
|
||||
<div class="detail__steps">
|
||||
<div
|
||||
v-for="(step, index) in ORDER_STEPS"
|
||||
@@ -147,9 +143,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onActivated, onMounted, reactive, ref } from 'vue'
|
||||
import { computed, onActivated, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { Drawer } from 'ant-design-vue'
|
||||
import { Loading, PullRefresh } from 'vant'
|
||||
import AppPullRefresh from '../../components/ui/AppPullRefresh.vue'
|
||||
import Icon from '../../components/icon/Icon.vue'
|
||||
import PageBar from '../../components/ui/PageBar.vue'
|
||||
import Spinner from '../../components/Spinner.vue'
|
||||
@@ -164,11 +160,13 @@ import {
|
||||
} from '../../utils/orderStatus'
|
||||
import { jdate } from '../../utils/filters'
|
||||
import { useSessionStore } from '../../stores/session'
|
||||
import { useNavStore } from '../../stores/navStore'
|
||||
import type { OrderDetail } from '../../api/client'
|
||||
import { useCachedReads } from '../../api/cachedReads'
|
||||
import { KEYS } from '../../stores/queryCache'
|
||||
|
||||
const session = useSessionStore()
|
||||
const nav = useNavStore()
|
||||
const reads = useCachedReads()
|
||||
|
||||
const tabs = [
|
||||
@@ -227,6 +225,23 @@ function openDetail(item: OrderDetail) {
|
||||
viewData.model = true
|
||||
}
|
||||
|
||||
function closeDetail() {
|
||||
viewData.model = false
|
||||
}
|
||||
|
||||
// Full-screen detail must own the viewport: hide the tab bar so it cannot
|
||||
// cover the sheet, and restore it when the drawer closes (or this view leaves).
|
||||
watch(
|
||||
() => viewData.model,
|
||||
(open) => {
|
||||
nav.setNavVisibility(!open)
|
||||
},
|
||||
)
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (!nav.showNav) nav.setNavVisibility(true)
|
||||
})
|
||||
|
||||
async function onRefresh() {
|
||||
await loadOrders(true)
|
||||
refreshing.value = false
|
||||
@@ -339,32 +354,44 @@ onActivated(() => {
|
||||
|
||||
/* ── Detail drawer ─────────────────────────────────────────────────── */
|
||||
.detail {
|
||||
height: 100vh;
|
||||
// Fill the drawer body — never 100vh: on mobile browsers that unit is
|
||||
// taller than the visible viewport, so a bottom sheet's header sat above
|
||||
// the screen and the close control was unreachable.
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: @canvas;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.detail__bar {
|
||||
flex: 0 0 auto;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 11px 16px;
|
||||
padding: calc(11px + env(safe-area-inset-top, 0px)) 16px 11px;
|
||||
border-bottom: 1px solid @hairline;
|
||||
background: alpha(@canvas, 92%);
|
||||
background: alpha(@canvas, 96%);
|
||||
backdrop-filter: blur(14px);
|
||||
}
|
||||
|
||||
.detail__title {
|
||||
margin: 0;
|
||||
flex: 1 1 auto;
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
color: @ink;
|
||||
text-align: center;
|
||||
/* Balance the close button so the title sits visually centered. */
|
||||
padding-inline-end: 38px;
|
||||
}
|
||||
|
||||
.detail__close {
|
||||
flex: 0 0 auto;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border: 0;
|
||||
@@ -376,17 +403,17 @@ onActivated(() => {
|
||||
background: @hairlineSoft;
|
||||
}
|
||||
|
||||
.detail__spacer {
|
||||
display: block;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
.detail__close:active {
|
||||
transform: scale(0.94);
|
||||
}
|
||||
|
||||
.detail__scroll {
|
||||
flex: 1;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 16px;
|
||||
padding-bottom: 40px;
|
||||
padding-bottom: calc(40px + env(safe-area-inset-bottom, 0px));
|
||||
}
|
||||
|
||||
.detail__block {
|
||||
@@ -476,11 +503,13 @@ onActivated(() => {
|
||||
|
||||
.detail__status {
|
||||
flex: 0 0 auto;
|
||||
padding: 5px 12px;
|
||||
padding: 6px 14px;
|
||||
border-radius: 999px;
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
font-size: 11.5px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.01em;
|
||||
white-space: nowrap;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.detail__specs {
|
||||
@@ -522,3 +551,22 @@ onActivated(() => {
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Drawer teleports to <body> — viewport lock must live outside scoped CSS. -->
|
||||
<style lang="less">
|
||||
.orders-detail-drawer.ant-drawer-bottom .ant-drawer-content-wrapper {
|
||||
// Prefer the dynamic viewport so the sheet never taller than what the user
|
||||
// can see (classic 100vh / mobile URL-bar bug that hid the close bar).
|
||||
height: 100% !important;
|
||||
max-height: 100vh !important;
|
||||
max-height: 100dvh !important;
|
||||
}
|
||||
|
||||
.orders-detail-drawer .ant-drawer-content,
|
||||
.orders-detail-drawer .ant-drawer-wrapper-body,
|
||||
.orders-detail-drawer .ant-drawer-body {
|
||||
height: 100% !important;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user