803 lines
21 KiB
Vue
803 lines
21 KiB
Vue
<script setup lang="ts">
|
||
import { computed, onMounted, ref } from 'vue'
|
||
import { useRouter } from 'vue-router'
|
||
import { useAuthStore } from '@/stores/auth'
|
||
import { useOrderStore } from '@/stores/order'
|
||
import { useCrmStore } from '@/stores/crm'
|
||
import { useNotificationStore } from '@/stores/notification'
|
||
import { fetchAgentProfile, type AgentProfileDto } from '@/services/agentApi'
|
||
import type { CatalogProductCard } from '@/types/crm'
|
||
import { formatDate, formatNumber } from '@/utils/format'
|
||
import { ORDER_STATUS_LABELS, STATUS_BADGE_VARIANT } from '@/utils/constants'
|
||
import IconBell from '@/components/icons/IconBell.vue'
|
||
import IconSettings from '@/components/icons/IconSettings.vue'
|
||
import IconChevronLeft from '@/components/icons/IconChevronLeft.vue'
|
||
import IconCart from '@/components/icons/IconCart.vue'
|
||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||
import PageSkeleton from '@/components/ui/PageSkeleton.vue'
|
||
import UserAvatar from '@/components/ui/UserAvatar.vue'
|
||
|
||
const SAMPLE_PRODUCT: CatalogProductCard = {
|
||
id: 'sample-base-price',
|
||
name: 'پارچه فاستونی ایتالیایی',
|
||
code: 'DF-1204',
|
||
categoryId: '',
|
||
season: 'all_season',
|
||
widthCm: 160,
|
||
composition: '',
|
||
colors: ['1', '2', '3', '4', '5', '6'],
|
||
tags: [],
|
||
isNew: false,
|
||
rollMeters: 0,
|
||
basePrice: 380_000,
|
||
}
|
||
|
||
const router = useRouter()
|
||
const auth = useAuthStore()
|
||
const orderStore = useOrderStore()
|
||
const crm = useCrmStore()
|
||
const notificationStore = useNotificationStore()
|
||
const profile = ref<AgentProfileDto | null>(null)
|
||
const sampleProduct = ref<CatalogProductCard>(SAMPLE_PRODUCT)
|
||
const loading = ref(false)
|
||
|
||
/** مطابق موکاپ ۱۱ — بدون gate نقش */
|
||
const quickActions = [
|
||
{ label: 'ثبت مشتری جدید', to: '/customers', icon: 'vuesax-linear:add' },
|
||
{ label: 'سفارشها', to: '/orders', icon: 'vuesax-linear:document-text' },
|
||
{ label: 'مشتریان من', to: '/customers', icon: 'vuesax-linear:people' },
|
||
{ label: 'گزارشها', to: '/reminders', icon: 'vuesax-linear:chart-2' },
|
||
{ label: 'درخواست کالیته', to: '/catalog-request', icon: 'vuesax-linear:category' },
|
||
{ label: 'قیمتگذاری', to: '/categories', icon: 'vuesax-linear:money-4' },
|
||
] as const
|
||
|
||
const recentOrders = computed(() =>
|
||
[...orderStore.orders]
|
||
.sort((a, b) => String(b.createdAt).localeCompare(String(a.createdAt)))
|
||
.slice(0, 3)
|
||
.map((o) => {
|
||
const variant = STATUS_BADGE_VARIANT[o.status] ?? 'info'
|
||
const tone =
|
||
variant === 'danger' || variant === 'neutral'
|
||
? 'danger'
|
||
: variant === 'success'
|
||
? 'success'
|
||
: variant === 'warning'
|
||
? 'warning'
|
||
: 'info'
|
||
return {
|
||
id: o.id,
|
||
title: `سفارش #${o.orderNumber}`,
|
||
date: o.createdAt ? formatDate(o.createdAt) : '',
|
||
customer: o.companyName || '',
|
||
statusLabel: ORDER_STATUS_LABELS[o.status] || o.status,
|
||
statusTone: tone as 'warning' | 'success' | 'info' | 'danger',
|
||
}
|
||
}),
|
||
)
|
||
|
||
const displayName = computed(() => auth.fullName || 'کاربر')
|
||
const code = computed(() => profile.value?.code || auth.user?.agentCode || '—')
|
||
const levelLabel = computed(
|
||
() => profile.value?.levelLabel || auth.user?.levelLabel || 'برنزی',
|
||
)
|
||
const nextLevelLabel = computed(
|
||
() => profile.value?.nextLevelLabel || auth.user?.nextLevelLabel || 'نقرهای',
|
||
)
|
||
const pointsToNext = computed(
|
||
() => profile.value?.pointsToNext ?? auth.user?.pointsToNext ?? 0,
|
||
)
|
||
const periodLabel = computed(() => profile.value?.periodLabel || '۳۰ روز اخیر')
|
||
const customersCount = computed(() => profile.value?.customersCount ?? 0)
|
||
const ordersCount = computed(() => profile.value?.ordersCount ?? orderStore.orders.length)
|
||
const salesVolume = computed(() => profile.value?.salesVolumeToman ?? 0)
|
||
const profit = computed(() => profile.value?.profitToman ?? 0)
|
||
const levelProgress = computed(
|
||
() => profile.value?.levelProgress ?? auth.user?.levelProgress ?? 72,
|
||
)
|
||
const unreadLabel = computed(() =>
|
||
notificationStore.unreadCount > 9 ? '9+' : String(notificationStore.unreadCount),
|
||
)
|
||
const samplePrice = computed(() => sampleProduct.value.basePrice ?? SAMPLE_PRODUCT.basePrice ?? 0)
|
||
|
||
onMounted(async () => {
|
||
loading.value = true
|
||
try {
|
||
void notificationStore.hydrate()
|
||
try {
|
||
profile.value = await fetchAgentProfile()
|
||
} catch {
|
||
profile.value = null
|
||
}
|
||
try {
|
||
const products = await crm.loadBrowseProducts()
|
||
const first = products[0]
|
||
sampleProduct.value = first
|
||
? { ...SAMPLE_PRODUCT, ...first, basePrice: first.basePrice ?? SAMPLE_PRODUCT.basePrice }
|
||
: SAMPLE_PRODUCT
|
||
} catch {
|
||
sampleProduct.value = SAMPLE_PRODUCT
|
||
}
|
||
if (!orderStore.orders.length) await orderStore.hydrate()
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<div class="page profile-page">
|
||
<div class="page__scroll page__scroll--with-nav profile-scroll">
|
||
<header class="hero">
|
||
<div class="hero__pin">
|
||
<div class="hero__top">
|
||
<button
|
||
type="button"
|
||
class="icon-btn"
|
||
aria-label="تنظیمات"
|
||
@click="router.push('/profile/display')"
|
||
>
|
||
<IconSettings :size="20" color="#ffffff" />
|
||
</button>
|
||
<h1>پروفایل من</h1>
|
||
<button
|
||
type="button"
|
||
class="icon-btn"
|
||
aria-label="اعلانها"
|
||
@click="router.push('/profile/notifications')"
|
||
>
|
||
<IconBell :size="20" color="#ffffff" />
|
||
<span
|
||
v-if="notificationStore.hasUnread"
|
||
class="icon-btn__badge"
|
||
:aria-label="`${notificationStore.unreadCount} اعلان خواندهنشده`"
|
||
>
|
||
{{ unreadLabel }}
|
||
</span>
|
||
</button>
|
||
</div>
|
||
<UserAvatar
|
||
class="hero__avatar"
|
||
:src="auth.user?.avatarUrl"
|
||
:initials="displayName.charAt(0)"
|
||
:size="84"
|
||
/>
|
||
</div>
|
||
<div class="hero__meta">
|
||
<h2>{{ displayName }}</h2>
|
||
<p>کد واسطه: {{ code }}</p>
|
||
<span class="level-pill">
|
||
<svg class="level-pill__crown" viewBox="0 0 24 24" aria-hidden="true">
|
||
<path
|
||
fill="currentColor"
|
||
d="M3.5 17.5h17l-1.2-8.2a1 1 0 0 0-1.5-.7L14 11l-2.5-5.2a1 1 0 0 0-1.8 0L7.2 11 4.2 8.6a1 1 0 0 0-1.5.7L3.5 17.5Zm1.7 1.5h13.6v1.2H5.2V19Z"
|
||
/>
|
||
</svg>
|
||
سطح: {{ levelLabel }}
|
||
</span>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="profile-sheet">
|
||
<PageSkeleton v-if="loading" variant="profile" />
|
||
<template v-else>
|
||
<section class="panel">
|
||
<div class="panel__head">
|
||
<h3>خلاصه عملکرد</h3>
|
||
<span class="panel__period">
|
||
{{ periodLabel }}
|
||
<BasicIcon icon="vuesax-linear:arrow-down" :size="14" :stroke-width="1.5" />
|
||
</span>
|
||
</div>
|
||
<div class="stats">
|
||
<div class="stat-card">
|
||
<div class="stat-card__text">
|
||
<span class="stat-card__label">سفارشها</span>
|
||
<strong class="stat-card__value">{{ formatNumber(ordersCount) }}</strong>
|
||
<em class="stat-card__hint">سفارش</em>
|
||
</div>
|
||
<span class="stat-card__icon stat-card__icon--orders">
|
||
<IconCart :size="18" />
|
||
</span>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-card__text">
|
||
<span class="stat-card__label">مشتریان من</span>
|
||
<strong class="stat-card__value">{{ formatNumber(customersCount) }}</strong>
|
||
<em class="stat-card__hint">مشتری فعال</em>
|
||
</div>
|
||
<span class="stat-card__icon stat-card__icon--customers">
|
||
<BasicIcon icon="vuesax-linear:people" :size="18" :stroke-width="1.5" />
|
||
</span>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-card__text">
|
||
<span class="stat-card__label">سود شما (ریال)</span>
|
||
<strong class="stat-card__value">{{ formatNumber(profit) }}</strong>
|
||
<em class="stat-card__hint">تومان</em>
|
||
</div>
|
||
<span class="stat-card__icon stat-card__icon--profit">
|
||
<BasicIcon icon="vuesax-linear:chart-2" :size="18" :stroke-width="1.5" />
|
||
</span>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-card__text">
|
||
<span class="stat-card__label">حجم فروش (ریال)</span>
|
||
<strong class="stat-card__value">{{ formatNumber(salesVolume) }}</strong>
|
||
<em class="stat-card__hint">تومان</em>
|
||
</div>
|
||
<span class="stat-card__icon stat-card__icon--sales">
|
||
<BasicIcon icon="vuesax-linear:wallet" :size="18" :stroke-width="1.5" />
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="loyalty">
|
||
<div class="loyalty__row">
|
||
<div class="loyalty__crown" aria-hidden="true">
|
||
<svg viewBox="0 0 48 48" width="40" height="40">
|
||
<path
|
||
fill="#E0C35A"
|
||
d="M8 34h32l-2.4-16.2a2 2 0 0 0-3-.1L28 24l-4.8-10a2 2 0 0 0-3.6 0L14.8 24 9.4 17.7a2 2 0 0 0-3.1.1L8 34Z"
|
||
/>
|
||
<path fill="#C9A227" d="M10 36h28v3H10z" />
|
||
<circle cx="24" cy="28" r="3" fill="#F7E7A1" />
|
||
</svg>
|
||
</div>
|
||
<p class="loyalty__text">
|
||
شما در سطح {{ levelLabel }} قرار دارید. تا سطح
|
||
{{ nextLevelLabel }} فقط
|
||
{{ formatNumber(pointsToNext) }} تومان فروش دیگر نیاز دارید.
|
||
</p>
|
||
</div>
|
||
<div class="loyalty__bar">
|
||
<span :style="{ width: `${Math.min(100, Math.max(0, levelProgress))}%` }" />
|
||
</div>
|
||
</section>
|
||
|
||
<section>
|
||
<h3 class="section-title">دسترسی سریع</h3>
|
||
<div class="quick-grid">
|
||
<button
|
||
v-for="item in quickActions"
|
||
:key="item.label"
|
||
type="button"
|
||
class="quick-item"
|
||
@click="router.push(item.to)"
|
||
>
|
||
<span class="quick-item__icon">
|
||
<BasicIcon :icon="item.icon" :size="22" :stroke-width="1.5" />
|
||
</span>
|
||
{{ item.label }}
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="orders-box">
|
||
<div class="section-head">
|
||
<h3>آخرین سفارشها</h3>
|
||
<button type="button" class="link" @click="router.push('/orders')">مشاهده همه</button>
|
||
</div>
|
||
<article
|
||
v-for="order in recentOrders"
|
||
:key="order.id"
|
||
class="order-row"
|
||
role="button"
|
||
tabindex="0"
|
||
@click="router.push({ path: '/order', query: { id: order.id } })"
|
||
@keydown.enter="router.push({ path: '/order', query: { id: order.id } })"
|
||
>
|
||
<div class="order-row__meta">
|
||
<span class="order-row__date">{{ order.date }}</span>
|
||
<strong class="order-row__title">{{ order.title }}</strong>
|
||
<p v-if="order.customer" class="order-row__customer">مشتری: {{ order.customer }}</p>
|
||
</div>
|
||
<span class="tone" :class="`tone--${order.statusTone}`">{{ order.statusLabel }}</span>
|
||
<IconChevronLeft :size="16" class="order-row__chevron" />
|
||
</article>
|
||
<button type="button" class="orders-all" @click="router.push('/orders')">
|
||
مشاهده همه سفارشها
|
||
</button>
|
||
</section>
|
||
|
||
<section class="price-section">
|
||
<h3 class="section-title">قیمتهای پایه (نمونه)</h3>
|
||
<div class="price-card">
|
||
<div class="price-card__body">
|
||
<div class="price-card__info">
|
||
<strong>{{ sampleProduct.name }}</strong>
|
||
<p>کد: {{ sampleProduct.code }}</p>
|
||
<p>عرض: {{ formatNumber(sampleProduct.widthCm) }} سانتیمتر</p>
|
||
<p>رنگها: {{ formatNumber(sampleProduct.colors.length) }} رنگ</p>
|
||
</div>
|
||
<div
|
||
class="price-card__image"
|
||
:style="
|
||
sampleProduct.imageUrl
|
||
? { backgroundImage: `url(${sampleProduct.imageUrl})` }
|
||
: undefined
|
||
"
|
||
/>
|
||
</div>
|
||
<footer>قیمت پایه به شما: {{ formatNumber(samplePrice) }} تومان / متر</footer>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.profile-page {
|
||
background: var(--color-primary);
|
||
}
|
||
|
||
.hero {
|
||
color: #fff;
|
||
padding: 0 0 28px;
|
||
text-align: center;
|
||
background: linear-gradient(
|
||
145deg,
|
||
var(--color-primary) 0%,
|
||
color-mix(in srgb, var(--color-primary) 78%, #0a1f18) 100%
|
||
);
|
||
}
|
||
|
||
.hero__pin {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 3;
|
||
padding: 12px var(--page-padding) 10px;
|
||
background: linear-gradient(
|
||
145deg,
|
||
var(--color-primary) 0%,
|
||
color-mix(in srgb, var(--color-primary) 78%, #0a1f18) 100%
|
||
);
|
||
}
|
||
|
||
.hero__top {
|
||
display: grid;
|
||
grid-template-columns: 40px 1fr 40px;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.hero__top h1 {
|
||
margin: 0;
|
||
font-size: 1rem;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.icon-btn {
|
||
position: relative;
|
||
width: 40px;
|
||
height: 40px;
|
||
border: none;
|
||
background: transparent;
|
||
display: grid;
|
||
place-items: center;
|
||
cursor: pointer;
|
||
color: #fff;
|
||
}
|
||
|
||
.icon-btn__badge {
|
||
position: absolute;
|
||
top: 4px;
|
||
inset-inline-start: 4px;
|
||
min-width: 16px;
|
||
height: 16px;
|
||
padding: 0 4px;
|
||
border-radius: 999px;
|
||
background: #f59e0b;
|
||
color: #fff;
|
||
font-size: 0.625rem;
|
||
font-weight: 700;
|
||
line-height: 16px;
|
||
text-align: center;
|
||
}
|
||
|
||
.hero__avatar {
|
||
margin: 0 auto;
|
||
border: 3px solid rgba(255, 255, 255, 0.35);
|
||
color: #fff;
|
||
}
|
||
|
||
.hero__meta {
|
||
padding: 10px var(--page-padding) 0;
|
||
}
|
||
|
||
.hero h2 {
|
||
margin: 0;
|
||
font-size: 1.2rem;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.hero p {
|
||
margin: 6px 0 12px;
|
||
opacity: 0.88;
|
||
font-size: 0.85rem;
|
||
}
|
||
|
||
.level-pill {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
border: 1px solid var(--color-level-gold);
|
||
border-radius: 999px;
|
||
padding: 5px 14px;
|
||
font-size: 0.8125rem;
|
||
background: color-mix(in srgb, var(--color-level-gold) 16%, transparent);
|
||
color: #fff;
|
||
}
|
||
|
||
.level-pill__crown {
|
||
width: 14px;
|
||
height: 14px;
|
||
color: var(--color-level-gold);
|
||
}
|
||
|
||
.profile-scroll {
|
||
flex: 1;
|
||
min-height: 0;
|
||
background: transparent;
|
||
padding: 0;
|
||
}
|
||
|
||
.profile-sheet {
|
||
position: relative;
|
||
z-index: 1;
|
||
margin-top: -20px;
|
||
padding: 20px var(--page-padding) 24px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 18px;
|
||
background: var(--color-bg);
|
||
border-radius: 24px 24px 0 0;
|
||
box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.profile-sheet > * {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.panel__head,
|
||
.section-head {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.panel__head h3,
|
||
.section-head h3,
|
||
.section-title {
|
||
margin: 0;
|
||
font-size: 0.95rem;
|
||
font-weight: 700;
|
||
color: var(--color-text);
|
||
}
|
||
|
||
.section-title {
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.panel__period {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 2px;
|
||
color: var(--color-text-muted);
|
||
font-size: 0.8rem;
|
||
}
|
||
|
||
.link {
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--color-primary);
|
||
font-weight: 600;
|
||
font-size: 0.8rem;
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
}
|
||
|
||
.stats {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 10px;
|
||
}
|
||
|
||
.stat-card {
|
||
background: var(--color-surface);
|
||
border-radius: 14px;
|
||
padding: 12px;
|
||
box-shadow: var(--shadow-sm);
|
||
border: 1px solid var(--color-border);
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 10px;
|
||
}
|
||
|
||
.stat-card__text {
|
||
min-width: 0;
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
text-align: start;
|
||
}
|
||
|
||
.stat-card__icon {
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: 10px;
|
||
display: grid;
|
||
place-items: center;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.stat-card__icon--orders,
|
||
.stat-card__icon--customers {
|
||
background: color-mix(in srgb, var(--color-success) 14%, transparent);
|
||
color: var(--color-success);
|
||
}
|
||
|
||
.stat-card__icon--profit {
|
||
background: color-mix(in srgb, var(--color-info) 14%, transparent);
|
||
color: var(--color-info);
|
||
}
|
||
|
||
.stat-card__icon--sales {
|
||
background: color-mix(in srgb, var(--color-level-gold) 22%, transparent);
|
||
color: #b8860b;
|
||
}
|
||
|
||
.stat-card__label {
|
||
font-size: 0.75rem;
|
||
color: var(--color-text-muted);
|
||
}
|
||
|
||
.stat-card__value {
|
||
font-size: 1.05rem;
|
||
font-weight: 700;
|
||
color: var(--color-text);
|
||
line-height: 1.3;
|
||
}
|
||
|
||
.stat-card__hint {
|
||
font-size: 0.7rem;
|
||
font-style: normal;
|
||
color: var(--color-text-muted);
|
||
}
|
||
|
||
.loyalty {
|
||
background: var(--color-primary-soft);
|
||
border-radius: 14px;
|
||
padding: 14px;
|
||
}
|
||
|
||
.loyalty__row {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 12px;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.loyalty__crown {
|
||
flex-shrink: 0;
|
||
width: 40px;
|
||
height: 40px;
|
||
display: grid;
|
||
place-items: center;
|
||
}
|
||
|
||
.loyalty__text {
|
||
margin: 0;
|
||
font-size: 0.8125rem;
|
||
line-height: 1.75;
|
||
color: var(--color-text);
|
||
text-align: start;
|
||
}
|
||
|
||
.loyalty__bar {
|
||
height: 8px;
|
||
border-radius: 999px;
|
||
background: rgba(var(--color-primary-rgb), 0.15);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.loyalty__bar span {
|
||
display: block;
|
||
height: 100%;
|
||
background: var(--color-primary);
|
||
border-radius: inherit;
|
||
}
|
||
|
||
.quick-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 10px;
|
||
}
|
||
|
||
.quick-item {
|
||
border: 1px solid var(--color-border);
|
||
background: var(--color-surface);
|
||
border-radius: 14px;
|
||
padding: 14px 8px 12px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 8px;
|
||
font-size: 0.72rem;
|
||
color: var(--color-text);
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
text-align: center;
|
||
line-height: 1.4;
|
||
min-height: 88px;
|
||
}
|
||
|
||
.quick-item__icon {
|
||
width: 40px;
|
||
height: 40px;
|
||
color: var(--color-primary);
|
||
display: grid;
|
||
place-items: center;
|
||
}
|
||
|
||
.orders-box {
|
||
flex-shrink: 0;
|
||
background: var(--color-surface);
|
||
border: 1px solid var(--color-border);
|
||
border-radius: 14px;
|
||
overflow: hidden;
|
||
padding: 4px 0 0;
|
||
}
|
||
|
||
.orders-box .section-head {
|
||
margin: 0;
|
||
padding: 12px 14px 10px;
|
||
}
|
||
|
||
.order-row {
|
||
display: grid;
|
||
grid-template-columns: 1fr auto 16px;
|
||
gap: 8px;
|
||
align-items: center;
|
||
background: transparent;
|
||
border: none;
|
||
border-top: 1px solid var(--color-border);
|
||
border-radius: 0;
|
||
padding: 12px 14px;
|
||
margin: 0;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.orders-all {
|
||
width: 100%;
|
||
margin: 0;
|
||
padding: 12px 14px;
|
||
border: none;
|
||
border-top: 1px solid var(--color-border);
|
||
border-radius: 0;
|
||
background: transparent;
|
||
color: var(--color-primary);
|
||
font: inherit;
|
||
font-weight: 600;
|
||
font-size: 0.875rem;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.order-row__meta {
|
||
min-width: 0;
|
||
text-align: start;
|
||
}
|
||
|
||
.order-row__date {
|
||
display: block;
|
||
font-size: 0.75rem;
|
||
color: var(--color-text-muted);
|
||
margin-bottom: 2px;
|
||
}
|
||
|
||
.order-row__title {
|
||
display: block;
|
||
font-size: 0.875rem;
|
||
}
|
||
|
||
.order-row__customer {
|
||
margin: 2px 0 0;
|
||
color: var(--color-text-muted);
|
||
font-size: 0.75rem;
|
||
}
|
||
|
||
.order-row__chevron {
|
||
color: var(--color-text-muted);
|
||
}
|
||
|
||
.tone {
|
||
border-radius: 999px;
|
||
padding: 4px 10px;
|
||
font-size: 0.7rem;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.tone--warning {
|
||
background: var(--color-warning-light);
|
||
color: #b45309;
|
||
}
|
||
|
||
.tone--success {
|
||
background: var(--color-success-light);
|
||
color: var(--color-success);
|
||
}
|
||
|
||
.tone--info {
|
||
background: var(--color-info-light);
|
||
color: var(--color-info);
|
||
}
|
||
|
||
.tone--danger {
|
||
background: var(--color-danger-light);
|
||
color: var(--color-danger);
|
||
}
|
||
|
||
.price-section {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.price-section .section-title {
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.price-card {
|
||
background: var(--color-surface);
|
||
border: 1px solid var(--color-border);
|
||
border-radius: 14px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.price-card__body {
|
||
display: grid;
|
||
grid-template-columns: 1fr 88px;
|
||
gap: 12px;
|
||
padding: 12px;
|
||
align-items: start;
|
||
}
|
||
|
||
.price-card__image {
|
||
border-radius: 12px;
|
||
background: linear-gradient(145deg, var(--color-primary), var(--color-primary-dark));
|
||
background-size: cover;
|
||
background-position: center;
|
||
min-height: 88px;
|
||
}
|
||
|
||
.price-card__info {
|
||
text-align: start;
|
||
}
|
||
|
||
.price-card__info strong {
|
||
display: block;
|
||
font-size: 0.9rem;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.price-card__info p {
|
||
margin: 2px 0 0;
|
||
color: var(--color-text-muted);
|
||
font-size: 0.75rem;
|
||
}
|
||
|
||
.price-card footer {
|
||
border-top: 1px solid var(--color-border);
|
||
padding: 10px 12px;
|
||
font-size: 0.8rem;
|
||
font-weight: 600;
|
||
background: var(--color-elevated);
|
||
text-align: start;
|
||
}
|
||
</style>
|