From a7abf5db26ff8888a5319d891ae469de1407ca79 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Wed, 25 Feb 2026 15:54:44 +0330 Subject: [PATCH] detail order --- src/pages/order/OrderDetail.tsx | 203 +++++++++++++++++++++--- src/pages/order/service/OrderService.ts | 2 +- src/pages/order/types/Types.ts | 51 +++++- 3 files changed, 230 insertions(+), 26 deletions(-) diff --git a/src/pages/order/OrderDetail.tsx b/src/pages/order/OrderDetail.tsx index c0314f0..dcb255a 100644 --- a/src/pages/order/OrderDetail.tsx +++ b/src/pages/order/OrderDetail.tsx @@ -1,40 +1,203 @@ import { type FC } from 'react' import { useParams } from 'react-router-dom' +import moment from 'moment-jalaali' +import { User } from 'iconsax-react' import { useGetOrderDetails } from './hooks/useOrderData' import TicketSection from './components/TicketSection' import OrderItem from './components/OrderItem' +import type { OrderDetailDataType, OrderItemType } from './types/Types' + +const CARD_CLASS = 'bg-white rounded-2xl border border-border border-opacity-40 shadow-sm overflow-hidden' +const SECTION_TITLE_CLASS = 'text-lg font-light text-black mb-0' +const SECTION_HEADER_CLASS = 'border-b border-border border-opacity-40 px-6 py-5' + +const InfoRow: FC<{ label: string; value?: string | number | null }> = ({ label, value }) => ( +
+ {label} + {value ?? '—'} +
+) const OrderDetail: FC = () => { - const { id } = useParams() const { data } = useGetOrderDetails(id!) + const order = data?.data as (OrderDetailDataType & { items?: OrderItemType[] }) | undefined + const creator = order?.creator + const creatorName = creator ? `${creator.firstName} ${creator.lastName}`.trim() : '' return (
- {/* Header Section */} -
-
- سفارش #{data?.data?.orderNumber} -
-
+ {/* Header */} +
+ سفارش #{order?.orderNumber} +
- {/* Order Information Section */} -
-
-

اطلاعات سفارش

+ {/* اطلاعات سفارش */} +
+
+

اطلاعات سفارش

-
- { - data?.data?.items?.map((item) => { +
+ {/* شماره و وضعیت — برجسته */} +
+
+ شماره سفارش + #{order?.orderNumber ?? '—'} +
+ {order?.status && ( + + {order.status} + + )} +
+ {/* جزئیات در گرید منظم */} +
+
+
+

تاریخ ایجاد

+

+ {order?.createdAt ? moment(order.createdAt).format('jYYYY/jMM/jDD — HH:mm') : '—'} +

+
+
+

تخمین زمان (روز)

+

{order?.estimatedDays ?? '—'}

+
+
+

عنوان

+

{order?.title ?? '—'}

+
+
+
+
+

نوع / دسته‌بندی

+

{order?.type?.title ?? '—'}

+
+
+

محصول

+

{order?.product?.title ?? '—'}

+
+
+

شناسه آیتم فاکتور

+

{order?.invoiceItem ?? '—'}

+
+
+
+
+
+ + {/* اطلاعات مشتری */} + {order?.user && ( +
+
+

اطلاعات مشتری

+
+
+
+
+ + +
+
+ +
+
+
+
+ )} + + {/* ایجادکننده سفارش — کارت کامل */} + {creator && ( +
+
+

ایجادکننده سفارش

+
+
+
+ {/* آواتار و نام */} +
+
+ +
+
+

{creatorName || '—'}

+

ادمین ثبت‌کننده

+
+
+ {/* جزئیات ایجادکننده */} +
+
+
+

نام

+

{creator.firstName ?? '—'}

+
+
+

نام‌خانوادگی

+

{creator.lastName ?? '—'}

+
+
+

موبایل

+

{creator.phone ?? '—'}

+
+
+

نقش

+

{creator.role ?? '—'}

+
+
+

شناسه کاربری

+

{creator.id ?? '—'}

+
+
+

تاریخ ایجاد حساب

+

{creator.createdAt ? moment(creator.createdAt).format('jYYYY/jMM/jDD') : '—'}

+
+
+
+
+
+
+ )} + + {/* پیوست‌ها */} + {order?.attachments?.length ? ( +
+
+

پیوست‌ها

+
+
+ {order.attachments.map((att, idx) => { + const url = typeof att === 'string' ? att : (att as { url?: string })?.url + if (!url) return null return ( - + + پیوست {idx + 1} + ) - }) - } -
-
+ })} +
+ + ) : null} + + {/* اقلام سفارش */} + {order?.items?.length ? ( +
+
+

اقلام سفارش

+
+
+ {order.items.map((item) => ( + + ))} +
+
+ ) : null} - {/* Bottom Section - White Card */}
) diff --git a/src/pages/order/service/OrderService.ts b/src/pages/order/service/OrderService.ts index ee9f8da..1f92608 100644 --- a/src/pages/order/service/OrderService.ts +++ b/src/pages/order/service/OrderService.ts @@ -28,7 +28,7 @@ const cleanParams = (params?: GetOrdersParams) => { if (!params) return undefined; return Object.fromEntries( Object.entries(params).filter( - ([_, v]) => v != null && v !== '', + (entry) => entry[1] != null && entry[1] !== '', ) as [string, string][], ); }; diff --git a/src/pages/order/types/Types.ts b/src/pages/order/types/Types.ts index 9eb1885..6fef450 100644 --- a/src/pages/order/types/Types.ts +++ b/src/pages/order/types/Types.ts @@ -95,16 +95,57 @@ export interface OrderListItemType extends RowDataType { export type OrderListResponseType = BaseResponse; export type UserType = { - addresse?: string; - createdAt: string; - firstName?: string; - lastName?: string; + addresse?: string | null; + createdAt?: string; + deletedAt?: string | null; + firstName?: string | null; + lastName?: string | null; + gender?: boolean; isActive: boolean; id: string; maxCredit: number; phone: string; }; +export type OrderDetailCategoryType = { + id: string; + createdAt: string; + deletedAt: string | null; + parent: string | null; + title: string; + isActive: boolean; + avatarUrl: string | null; + order: number | null; +}; + +export type OrderDetailCreatorType = { + id: string; + createdAt: string; + deletedAt: string | null; + firstName: string; + lastName: string; + role: string; + phone: string; +}; + +export type OrderDetailDataType = { + id: string; + createdAt: string; + deletedAt: string | null; + invoiceItem: string; + product: Product | null; + print: unknown | null; + title: string; + type: OrderDetailCategoryType; + user: UserType; + designer: unknown | null; + creator: OrderDetailCreatorType; + orderNumber: number; + status: string; + estimatedDays: number; + attachments: unknown[]; +}; + export type AttachmentsType = { url: string; type: string; @@ -170,7 +211,7 @@ export type OrderItemType = { }[]; }; export type TicketsResponseType = BaseResponse; -export type OrderDetailResponseType = BaseResponse; +export type OrderDetailResponseType = BaseResponse; export type StoreType = { items: CreateOrderType[];