Files
fabric_trade_user/src/views/cart/components/MobileCartPage.vue
T

252 lines
5.8 KiB
Vue

<script setup lang="ts">
import BaseButton from '@/components/ui/BaseButton.vue'
import IconCart from '@/components/icons/IconCart.vue'
import IconTrash from '@/components/icons/IconTrash.vue'
import IconChevronBack from '@/components/icons/IconChevronBack.vue'
import { formatMeterage, formatNumber } from '@/utils/format'
import type { CartItem } from '@/types'
defineProps<{
items: CartItem[]
companyName: string
totalMeterage: number
maxMeterage: number
remainingCapacity: number
isEmpty: boolean
}>()
const emit = defineEmits<{
back: []
remove: [id: string]
checkout: []
selectCompany: []
}>()
</script>
<template>
<div class="cart-mobile-page">
<header class="cart-mobile-page__nav">
<button type="button" class="nav-btn" aria-label="بازگشت" @click="emit('back')">
<IconChevronBack :size="20" />
</button>
<h1 class="cart-mobile-page__title">سبد خرید</h1>
<button type="button" class="nav-btn nav-btn--ghost" aria-hidden="true" tabindex="-1">
<IconChevronBack :size="18" class="nav-btn__flip" />
</button>
</header>
<div v-if="!isEmpty" class="cart-mobile-page__body">
<p class="cart-mobile-page__company">
{{ companyName ? `شرکت‌ها: ${companyName}` : 'سبد خرید مشترک' }}
</p>
<div class="cart-mobile-page__scroll">
<div class="cart-mobile-table">
<div class="cart-mobile-table__head">
<span>محصول</span>
<span>متراژ (متر)</span>
<span>حذف</span>
</div>
<div v-for="item in items" :key="item.id" class="cart-mobile-table__row">
<div class="col-product">
<strong>{{ item.productName }}</strong>
<span>کد: {{ item.productCode }}</span>
<span v-if="item.companyName" class="col-product__company">{{ item.companyName }}</span>
</div>
<div class="col-meterage">{{ formatNumber(item.meterage) }}</div>
<div class="col-delete">
<button type="button" aria-label="حذف" @click="emit('remove', item.id)">
<IconTrash :size="20" />
</button>
</div>
</div>
</div>
</div>
<div class="cart-mobile-page__footer">
<div class="cart-mobile-summary">
<div class="cart-mobile-summary__row">
<span>جمع متراژ</span>
<strong>{{ formatMeterage(totalMeterage) }}</strong>
</div>
<div class="cart-mobile-summary__row">
<span>حداکثر مجاز</span>
<strong>{{ formatMeterage(maxMeterage) }}</strong>
</div>
<div class="cart-mobile-summary__row">
<span>باقی مانده</span>
<strong>{{ formatMeterage(remainingCapacity) }}</strong>
</div>
</div>
<BaseButton block @click="emit('checkout')">ادامه و انتخاب نوع تسویه</BaseButton>
</div>
</div>
<div v-else class="cart-mobile-page__empty">
<IconCart :size="56" />
<p>سبد خرید خالی است</p>
<BaseButton @click="emit('selectCompany')">انتخاب شرکت</BaseButton>
</div>
</div>
</template>
<style scoped>
.cart-mobile-page {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
background: #fff;
padding: 12px 0 0;
}
.cart-mobile-page__nav {
display: grid;
grid-template-columns: 40px 1fr 40px;
align-items: center;
margin-bottom: 12px;
}
.cart-mobile-page__title {
margin: 0;
font-size: 1.0625rem;
font-weight: 700;
text-align: center;
}
.nav-btn {
width: 40px;
height: 40px;
border: none;
background: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.nav-btn--ghost {
visibility: hidden;
}
.nav-btn__flip {
transform: scaleX(-1);
}
.cart-mobile-page__body {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
.cart-mobile-page__company {
margin: 0 0 16px;
font-size: 0.875rem;
color: var(--color-text-muted);
}
.cart-mobile-page__scroll {
flex: 1;
min-height: 0;
overflow-y: auto;
}
.cart-mobile-table {
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
overflow: hidden;
}
.cart-mobile-table__head,
.cart-mobile-table__row {
display: grid;
grid-template-columns: 1fr 88px 52px;
gap: 8px;
padding: 10px 12px;
align-items: center;
}
.cart-mobile-table__head {
background: #f1f5f9;
font-size: 0.75rem;
font-weight: 600;
color: var(--color-text-muted);
}
.cart-mobile-table__row {
border-top: 1px solid var(--color-border);
}
.col-product strong {
display: block;
font-size: 0.875rem;
}
.col-product span {
display: block;
font-size: 0.75rem;
color: var(--color-text-muted);
}
.col-product__company {
margin-top: 2px;
color: var(--color-primary) !important;
font-weight: 600;
}
.col-meterage {
text-align: center;
font-weight: 700;
}
.col-delete {
display: flex;
justify-content: center;
}
.col-delete button {
border: none;
background: none;
cursor: pointer;
color: #64748b;
}
.cart-mobile-page__footer {
flex-shrink: 0;
margin: 0 calc(-1 * var(--page-padding));
padding: 12px var(--page-padding);
border-top: 1px solid var(--color-border);
box-shadow: 0 -4px 16px rgba(15, 23, 42, 0.06);
background: #fff;
}
.cart-mobile-summary {
margin-bottom: 12px;
padding: 14px 16px;
background: #eef2f7;
border-radius: var(--radius-md);
}
.cart-mobile-summary__row {
display: flex;
justify-content: space-between;
padding: 8px 0;
font-size: 0.875rem;
}
.cart-mobile-summary__row:not(:last-child) {
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.cart-mobile-page__empty {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 16px;
color: var(--color-text-muted);
}
</style>