feat(admin-panel): responsive branches, workshops, products and orders

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
s.esmaeili
2026-10-13 09:14:28 +03:30
co-authored by Cursor
parent 0a2466ca0c
commit c1b3e90b9b
13 changed files with 194 additions and 39 deletions
@@ -29,7 +29,7 @@
column on ProductImage and is dropped, same as the other schema-less fields
noted above.
-->
<div id="page-user-view">
<div id="page-user-view" class="page-card">
<a-form layout="vertical" @submit.prevent="handleSubmit">
<a-spin :spinning="loading">
<a-card title="تصاویر محصول" class="mb-base">
@@ -150,7 +150,7 @@
</a-card>
<!-- تنوع ها -->
<a-card v-if="hasPermission('product.list.variants')" class="mb-8 overflow-auto">
<a-card v-if="hasPermission('product.list.variants')" class="mb-8 overflow-auto table-scroll">
<template #title>
<div class="flex">
<div class="flex-1">تنوع ها</div>
@@ -199,7 +199,7 @@
</a-card>
<div>
<a-button type="primary" class="mr-4" @click="handleSubmit">ثبت اطلاعات</a-button>
<a-button type="primary" class="mr-4 form-submit" @click="handleSubmit">ثبت اطلاعات</a-button>
</div>
</a-spin>
</a-form>
@@ -583,4 +583,10 @@ onMounted(async () => {
.overflow-auto {
overflow: auto;
}
@media (max-width: 575px) {
.mb-8 {
margin-bottom: 12px;
}
}
</style>
@@ -5,7 +5,7 @@
wage percentage to all of them. Farsi copy preserved.
-->
<div id="page-user-list">
<a-card title="تغییر درصد محصولات">
<a-card title="تغییر درصد محصولات" class="page-card">
<a-form layout="vertical">
<div class="grid-3">
<a-form-item label="دسته بندی">
@@ -53,7 +53,7 @@
cancel-text="خیر"
@confirm="applyChange"
>
<a-button type="primary" :loading="changeLoading">اعمال تغییرات</a-button>
<a-button type="primary" class="form-submit" :loading="changeLoading">اعمال تغییرات</a-button>
</a-popconfirm>
</a-form>
</a-card>
@@ -5,18 +5,19 @@
preserved. The commented-out "تنوع ها" action stays absent, as in legacy.
-->
<div id="page-user-list">
<a-card title="لیست محصولات">
<a-card title="لیست محصولات" class="page-card">
<template #extra>
<!-- D27 §12: کارساخته و موجودی از حسابداری -->
<AccountingSyncButton v-if="hasPermission('product.list')" endpoint="admin/products/accounting-sync" @done="tblProducts?.fetch()" />
</template>
<h6>تعداد {{ selectedRows.length }} محصول انتخاب شده است.</h6>
<h6 class="selected-count">تعداد {{ selectedRows.length }} محصول انتخاب شده است.</h6>
<XTable
ref="tblProducts"
v-model="selectedRows"
:model="model"
:has-selection="true"
mobile-cards
>
<template #image="{ record }">
<img
@@ -72,9 +73,9 @@
</XTable>
<!-- اطلاعات جامع -->
<a-modal v-model:open="visibleProduct" title="اطلاعات جامع محصول" width="70%">
<a-modal v-model:open="visibleProduct" title="اطلاعات جامع محصول" width="70%" wrap-class-name="detail-modal">
<div v-if="tempRow">
<a-descriptions bordered size="small" :column="2">
<a-descriptions bordered size="small" :column="{ xxl: 2, xl: 2, lg: 2, md: 2, sm: 2, xs: 1 }">
<a-descriptions-item label="نام محصول">{{ tempRow.title }}</a-descriptions-item>
<a-descriptions-item label="کد محصول">{{ tempRow.product_code || '-' }}</a-descriptions-item>
<a-descriptions-item label="برند">{{ tempRow.brand?.title || '-' }}</a-descriptions-item>
@@ -182,4 +183,15 @@ function toEdit(id: string) {
object-fit: cover;
border-radius: 4px;
}
@media (max-width: 575px) {
/* the actions sit in the card header on phones; a fixed 12rem would crowd the title */
.w-48 {
width: auto;
}
.selected-count {
font-size: 12px;
margin-bottom: 8px;
}
}
</style>
@@ -52,7 +52,7 @@
<!-- route-based fallback for direct links to /branch/add and /branch/edit/:id -->
<a-spin v-else :spinning="loading">
<a-form layout="vertical" @submit.prevent="handleSubmit">
<a-card :title="id ? 'ویرایش شعبه' : 'افزودن شعبه'" class="mb-base">
<a-card :title="id ? 'ویرایش شعبه' : 'افزودن شعبه'" class="mb-base page-card">
<div class="grid-2">
<a-form-item label="نام شعبه" :validate-status="err.name ? 'error' : ''" :help="err.name">
<a-input v-model:value="form.name" />
@@ -81,7 +81,7 @@
<a-textarea v-model:value="form.address" :auto-size="{ minRows: 2, maxRows: 5 }" />
</a-form-item>
<a-button type="primary" @click="handleSubmit">ثبت اطلاعات</a-button>
<a-button type="primary" class="form-submit" @click="handleSubmit">ثبت اطلاعات</a-button>
</a-card>
</a-form>
</a-spin>
@@ -15,8 +15,8 @@
workshop use different forms), so this component stays generic instead of
growing a v-if per caller.
-->
<a-card :title="title">
<XTable ref="tbl" :model="model">
<a-card :title="title" class="page-card">
<XTable ref="tbl" :model="model" mobile-cards>
<template v-if="addRid" #add>
<ListPageHeader :rid="addRid" :add-label="addLabel" @add="openAdd()" />
</template>
+4 -4
View File
@@ -6,8 +6,8 @@
syntax becomes Vue 3 named slots.
-->
<div id="page-user-list">
<a-card :title="is_branch ? 'لیست سفارش' : 'لیست سفارش های تک فروشی'">
<XTable ref="tbl" :model="model">
<a-card :title="is_branch ? 'لیست سفارش' : 'لیست سفارش های تک فروشی'" class="page-card">
<XTable ref="tbl" :model="model" mobile-cards>
<template #opt="{ record }">
<div class="flex">
<TooltipBtn
@@ -51,7 +51,7 @@
</XTable>
<!-- وضعیت سفارش -->
<a-modal v-model:open="visibleSts" title="وضعیت سفارش">
<a-modal v-model:open="visibleSts" title="وضعیت سفارش" wrap-class-name="detail-modal">
<a-timeline v-if="tempRow">
<a-timeline-item
v-for="(item, index) in tempRow.activity"
@@ -93,7 +93,7 @@
</a-modal>
<!-- مشاهده سفارش -->
<a-modal v-model:open="visibleList" title="مشاهده سفارش" width="80%">
<a-modal v-model:open="visibleList" title="مشاهده سفارش" width="80%" wrap-class-name="detail-modal">
<div v-if="tempRow">
<a-descriptions>
<a-descriptions-item label="مشتری">
+14 -3
View File
@@ -6,8 +6,8 @@
delete action and the report link are COMMENTED OUT in legacy and stay absent.
-->
<div id="page-user-list">
<a-card title="سفارش های ساختنی">
<XTable ref="tbl" :model="model">
<a-card title="سفارش های ساختنی" class="page-card">
<XTable ref="tbl" :model="model" mobile-cards>
<template #name="{ record }">
{{ record.customer?.name }}
</template>
@@ -41,6 +41,7 @@
v-model:open="visibleList"
title="مشاهده سفارش"
width="80%"
wrap-class-name="detail-modal"
@cancel="onCloseDetail"
>
<div v-if="tempRow">
@@ -69,7 +70,7 @@
</div>
</template>
<div class="flex gap-8">
<div class="flex gap-8 make-detail">
<div>
<img
v-if="tempRow.designImageUrl"
@@ -220,4 +221,14 @@ function onCloseDetail() {
.mr-3 {
margin-left: 0.75rem;
}
@media (max-width: 575px) {
.make-detail {
flex-direction: column;
gap: 12px;
}
.make-detail > .flex {
min-width: 0;
}
}
</style>
@@ -6,8 +6,8 @@
report endpoint directly) but now points at the new API.
-->
<div id="page-user-list">
<a-card title="لیست سفارش های عمده">
<XTable ref="tbl" :model="model">
<a-card title="لیست سفارش های عمده" class="page-card">
<XTable ref="tbl" :model="model" mobile-cards>
<template #city="{ text }">
<div v-if="text">{{ getCity(text) }}</div>
<div v-else>-</div>
@@ -55,7 +55,7 @@
</XTable>
<!-- وضعیت سفارش -->
<a-modal v-model:open="visibleSts" title="وضعیت سفارش">
<a-modal v-model:open="visibleSts" title="وضعیت سفارش" wrap-class-name="detail-modal">
<a-timeline v-if="tempRow">
<a-timeline-item
v-for="(item, index) in tempRow.activity"
@@ -97,7 +97,7 @@
</a-modal>
<!-- مشاهده سفارش -->
<a-modal v-model:open="visibleList" title="مشاهده سفارش" width="80%">
<a-modal v-model:open="visibleList" title="مشاهده سفارش" width="80%" wrap-class-name="detail-modal">
<div v-if="tempRow">
<a-descriptions>
<a-descriptions-item label="مشتری">
@@ -7,8 +7,8 @@
the legacy markup but is COMMENTED OUT — preserved as absent, not re-added.
-->
<div id="page-user-list">
<a-card title="لیست سفارش های عمده">
<XTable ref="tbl" :model="model">
<a-card title="لیست سفارش های عمده" class="page-card">
<XTable ref="tbl" :model="model" mobile-cards>
<template #opt="{ record }">
<div class="flex">
<TooltipBtn
@@ -42,7 +42,7 @@
</XTable>
<!-- وضعیت سفارش -->
<a-modal v-model:open="visibleSts" title="وضعیت سفارش">
<a-modal v-model:open="visibleSts" title="وضعیت سفارش" wrap-class-name="detail-modal">
<a-timeline v-if="tempRow">
<a-timeline-item
v-for="(item, index) in tempRow.activity"
@@ -84,7 +84,7 @@
</a-modal>
<!-- مشاهده سفارش -->
<a-modal v-model:open="visibleList" title="مشاهده سفارش" width="80%">
<a-modal v-model:open="visibleList" title="مشاهده سفارش" width="80%" wrap-class-name="detail-modal">
<div v-if="tempRow">
<a-descriptions>
<a-descriptions-item label="مشتری">
+34 -4
View File
@@ -13,8 +13,8 @@
inventing a Rial figure — see docs/ADMIN-PORT-PLAN.md.
-->
<a-spin v-if="hasPermission('order.create')" :spinning="loading">
<a-card title="لیست محصولات">
<XTable ref="tblProducts" :model="cols">
<a-card title="لیست محصولات" class="page-card">
<XTable ref="tblProducts" :model="cols" mobile-cards>
<template #image="{ record }">
<img
width="90px"
@@ -42,7 +42,15 @@
</XTable>
<a-card v-if="items.length > 0" title="ثبت سفارش" class="mt-5">
<a-table :columns="columns" :data-source="items" bordered :pagination="false" row-key="vid">
<a-table
:columns="columns"
:data-source="items"
bordered
:pagination="false"
row-key="vid"
:size="layout.isMobile ? 'small' : 'middle'"
:scroll="layout.isSmallScreen ? { x: 'max-content' } : undefined"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'delete'">
<CloseOutlined class="cursor-pointer" @click="cart.remove(record)" />
@@ -170,7 +178,7 @@
<a-button
type="primary"
class="mt-4"
class="mt-4 form-submit"
:disabled="!items || items.length < 1"
@click="submitOrder"
>
@@ -197,9 +205,11 @@ import { buildProductListModel } from '../apps/product/productListModel';
import { useCartStore, type CartItem, type CartVariant } from '../../stores/cart';
import { useUsersStore } from '../../stores/users';
import { useAuthStore } from '../../stores/auth';
import { useLayoutStore } from '../../stores/layout';
import api from '../../api/client';
const router = useRouter();
const layout = useLayoutStore();
const users = useUsersStore();
const auth = useAuthStore();
const cart = useCartStore();
@@ -421,4 +431,24 @@ onMounted(async () => {
.totals {
margin: 1rem 0;
}
@media (max-width: 575px) {
.grid-5 {
grid-template-columns: 1fr 1fr;
column-gap: 12px;
row-gap: 0;
}
.grid-5 > :first-child {
grid-column: 1 / -1;
}
.mt-5 {
margin-top: 12px;
}
.mt-4 {
margin-top: 12px;
}
.totals {
margin: 0 0 12px;
}
}
</style>
@@ -61,7 +61,7 @@
<!-- route-based fallback for direct links to /workshop/add and /workshop/edit/:id -->
<a-spin v-else :spinning="loading">
<a-form layout="vertical" @submit.prevent="handleSubmit">
<a-card :title="id ? 'ویرایش کارگاه' : 'افزودن کارگاه'" class="mb-base">
<a-card :title="id ? 'ویرایش کارگاه' : 'افزودن کارگاه'" class="mb-base page-card">
<div class="grid-3">
<a-form-item
label="نام کارگاه"
@@ -96,7 +96,7 @@
<a-textarea v-model:value="form.workshop_address" :auto-size="{ minRows: 2, maxRows: 5 }" />
</a-form-item>
<a-button type="primary" @click="handleSubmit">ثبت اطلاعات</a-button>
<a-button type="primary" class="form-submit" @click="handleSubmit">ثبت اطلاعات</a-button>
</a-card>
</a-form>
</a-spin>