This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
import { type FC } from 'react'
|
||||
import { Link, useParams } from 'react-router-dom'
|
||||
import { Edit2, Printer } from 'iconsax-react'
|
||||
import { DocumentText, Edit2, Printer } from 'iconsax-react'
|
||||
import { toast } from 'react-toastify'
|
||||
import BackButton from '@/components/BackButton'
|
||||
import RefreshButton from '@/components/RefreshButton'
|
||||
import Button from '@/components/Button'
|
||||
import { Paths } from '@/config/Paths'
|
||||
import { extractErrorMessage } from '@/config/func'
|
||||
import { useGetInvoiceItem } from '@/pages/invoice/hooks/useInvoiceData'
|
||||
import { useGetOrderDetails, useUpdateOrderStatus } from './hooks/useOrderData'
|
||||
import TicketSection from './components/TicketSection'
|
||||
import OrderDetailSidebar from './components/OrderDetailSidebar'
|
||||
import InvoiceItemDetailSection from './components/InvoiceItemDetailSection'
|
||||
import type { OrderDetailDataType } from './types/Types'
|
||||
import { OrderStatusEnum } from './enum/OrderEnum'
|
||||
|
||||
@@ -20,6 +20,8 @@ const OrderDetail: FC = () => {
|
||||
const { mutate: updateOrderStatus, isPending: isUpdatingStatus } =
|
||||
useUpdateOrderStatus()
|
||||
const order = data?.data as OrderDetailDataType | undefined
|
||||
const { data: invoiceItemData } = useGetInvoiceItem(order?.invoiceItem ?? null)
|
||||
const invoiceId = invoiceItemData?.data?.invoice?.id
|
||||
|
||||
const handleUpdateStatus = (status: OrderStatusEnum) => {
|
||||
if (!id) return
|
||||
@@ -62,13 +64,23 @@ const OrderDetail: FC = () => {
|
||||
<div>
|
||||
<h1 className="text-lg font-light text-gray-900">جزئیات سفارش</h1>
|
||||
<p className="mt-1 text-sm text-gray-500">
|
||||
مشاهده اطلاعات سفارش، آیتم پیشفاکتور و گفتگو
|
||||
مشاهده اطلاعات سفارش و گفتگو
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<RefreshButton onClick={() => refetch()} isLoading={isFetching} />
|
||||
{invoiceId && (
|
||||
<Link to={Paths.perfomaInvoice.detail + invoiceId}>
|
||||
<Button className="w-fit px-4 bg-white border border-gray-200 text-gray-800 hover:bg-gray-50">
|
||||
<div className="flex items-center gap-2">
|
||||
<DocumentText size={18} color="currentColor" />
|
||||
پیشفاکتور
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
<Link to={Paths.orderPrint + id}>
|
||||
<Button className="w-fit px-4 bg-white border border-gray-200 text-gray-800 hover:bg-gray-50">
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -90,8 +102,6 @@ const OrderDetail: FC = () => {
|
||||
|
||||
<div className="mt-6 flex flex-col-reverse gap-6 xl:flex-row xl:items-start">
|
||||
<div className="min-w-0 flex-1 space-y-6">
|
||||
<InvoiceItemDetailSection invoiceItemId={order?.invoiceItem} />
|
||||
|
||||
<TicketSection />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
import { type FC, type ReactNode } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import moment from 'moment-jalaali'
|
||||
import { DocumentText } from 'iconsax-react'
|
||||
import PresignedImage from '@/components/PresignedImage'
|
||||
import { Paths } from '@/config/Paths'
|
||||
import { useGetInvoiceItem } from '@/pages/invoice/hooks/useInvoiceData'
|
||||
import { formatItemDiscountDisplay } from '@/pages/invoice/utils/invoiceItem'
|
||||
import { getUserDisplayName } from '../utils/orderDetailUtils'
|
||||
|
||||
type Props = {
|
||||
invoiceItemId?: string | null
|
||||
}
|
||||
|
||||
const formatAmount = (amount: number) =>
|
||||
Number(amount).toLocaleString('fa-IR') + ' ریال'
|
||||
|
||||
type FieldProps = {
|
||||
label: string
|
||||
children: ReactNode
|
||||
className?: string
|
||||
}
|
||||
|
||||
const Field: FC<FieldProps> = ({ label, children, className }) => (
|
||||
<div className={className}>
|
||||
<p className="mb-1.5 text-xs text-gray-500">{label}</p>
|
||||
<div className="text-sm text-gray-900">{children}</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
const InvoiceItemDetailSection: FC<Props> = ({ invoiceItemId }) => {
|
||||
const { data, isLoading, isError } = useGetInvoiceItem(invoiceItemId ?? null)
|
||||
const invoiceItem = data?.data
|
||||
const discounts = invoiceItem ? formatItemDiscountDisplay(invoiceItem) : null
|
||||
const imageUrl = invoiceItem?.product?.images?.[0]
|
||||
|
||||
if (!invoiceItemId) {
|
||||
return (
|
||||
<section id="invoice-item" className="rounded-3xl bg-white p-8 text-center shadow-sm">
|
||||
<p className="text-sm text-gray-500">آیتم فاکتوری به این سفارش متصل نیست.</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<section id="invoice-item" className="overflow-hidden rounded-3xl bg-white shadow-sm animate-pulse">
|
||||
<div className="border-b border-gray-100 px-5 py-4 md:px-6">
|
||||
<div className="h-5 w-40 rounded bg-gray-200" />
|
||||
</div>
|
||||
<div className="p-5 md:p-6 space-y-4">
|
||||
<div className="h-24 rounded-2xl bg-gray-100" />
|
||||
<div className="grid grid-cols-2 gap-4 sm:grid-cols-3">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<div key={i} className="h-14 rounded-xl bg-gray-100" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
if (isError || !invoiceItem) {
|
||||
return (
|
||||
<section id="invoice-item" className="rounded-3xl bg-white p-8 text-center shadow-sm">
|
||||
<p className="text-sm text-red-500">آیتم پیشفاکتور یافت نشد.</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<section id="invoice-item" className="overflow-hidden rounded-3xl bg-white shadow-sm">
|
||||
<div className="border-b border-gray-100 px-5 py-4 md:px-6">
|
||||
<h2 className="text-base font-medium text-gray-900">جزئیات آیتم پیشفاکتور</h2>
|
||||
<p className="mt-0.5 text-xs text-gray-500">
|
||||
اطلاعات مالی و محصول مرتبط با این سفارش
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="p-5 md:p-6">
|
||||
<div className="flex flex-col gap-5 md:flex-row">
|
||||
<div className="size-24 shrink-0 overflow-hidden rounded-xl border border-gray-200 bg-gray-50">
|
||||
{imageUrl ? (
|
||||
<PresignedImage
|
||||
src={imageUrl}
|
||||
alt={invoiceItem.product?.title}
|
||||
className="size-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex size-full items-center justify-center text-gray-300">
|
||||
<DocumentText size={32} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="min-w-0 flex-1 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<Field label="پیشفاکتور">
|
||||
<Link
|
||||
to={Paths.perfomaInvoice.detail + invoiceItem.invoice.id}
|
||||
className="font-medium text-[#0037FF] hover:underline"
|
||||
>
|
||||
#{invoiceItem.invoice.invoiceNumber}
|
||||
</Link>
|
||||
</Field>
|
||||
<Field label="مشتری">
|
||||
{getUserDisplayName(invoiceItem.invoice.user)}
|
||||
</Field>
|
||||
<Field label="محصول">
|
||||
{invoiceItem.product?.title ?? '—'}
|
||||
</Field>
|
||||
<Field label="تعداد">
|
||||
{invoiceItem.quantity?.toLocaleString('fa-IR') ?? '—'}
|
||||
</Field>
|
||||
<Field label="مبلغ واحد">
|
||||
{invoiceItem.unitPrice != null
|
||||
? formatAmount(invoiceItem.unitPrice)
|
||||
: '—'}
|
||||
</Field>
|
||||
<Field label="تخفیف (مبلغ)">
|
||||
{discounts?.value ?? '—'}
|
||||
</Field>
|
||||
<Field label="تخفیف (درصد)">
|
||||
{discounts?.percent ?? '—'}
|
||||
</Field>
|
||||
<Field label="مبلغ کل">
|
||||
<span className="font-semibold">
|
||||
{formatAmount(invoiceItem.total ?? 0)}
|
||||
</span>
|
||||
</Field>
|
||||
<Field label="تاریخ تایید">
|
||||
{invoiceItem.confirmedAt
|
||||
? moment(invoiceItem.confirmedAt).format('jYYYY/jMM/jDD HH:mm')
|
||||
: '—'}
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{invoiceItem.description && (
|
||||
<div className="mt-5 rounded-xl border border-dashed border-gray-200 bg-gray-50/60 px-4 py-3">
|
||||
<p className="text-xs font-medium text-gray-500 mb-1.5">توضیحات</p>
|
||||
<p className="whitespace-pre-wrap text-sm leading-7 text-gray-800">
|
||||
{invoiceItem.description}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default InvoiceItemDetailSection
|
||||
Reference in New Issue
Block a user