Files
dmenu-plus-front/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx
T
2025-12-25 11:26:14 +03:30

215 lines
9.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useParams, useRouter } from 'next/navigation';
import React from 'react';
import Button from '@/components/button/PrimaryButton';
import { Skeleton } from '@/components/ui/skeleton';
import { Clock } from 'iconsax-react';
import clsx from 'clsx';
import useToggle from '@/hooks/helpers/useToggle';
import Prompt from '@/components/utils/Prompt';
import { useCancelOrder, useGetOrderDetail } from '../../checkout/hooks/useOrderData';
import ordersTranslations from '@/locales/fa/orders.json';
import { toast } from '@/components/Toast';
import { extractErrorMessage } from '@/lib/func';
import { useQueryClient } from '@tanstack/react-query';
const getDeliveryMethodTitle = (method: string) => {
switch (method) {
case 'deliveryCourier':
return 'ارسال توسط پیک';
case 'deliveryCar':
return 'تحویل به خودرو';
case 'pickup':
return 'تحویل حضوری';
case 'dineIn':
return 'سرو در رستوران';
default:
return 'روش ارسال';
}
};
// const getStatusPercentage = (status: string) => {
// switch (status) {
// case 'new':
// case 'pendingPayment':
// return 0;
// case 'paid':
// case 'confirmed':
// return 20;
// case 'preparing':
// return 40;
// case 'ready':
// return 60;
// case 'shipped':
// case 'delivering':
// return 80;
// case 'completed':
// case 'delivered':
// return 100;
// default:
// return 0;
// }
// };
const getStatusText = (status: string): string => {
const statusKey = status as keyof typeof ordersTranslations.status;
return ordersTranslations.status[statusKey] || 'نامشخص';
};
const formatDate = (dateString: string): string => {
const date = new Date(dateString);
return date.toLocaleDateString('fa-IR', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
};
// const formatTime = (dateString: string): string => {
// const date = new Date(dateString);
// return date.toLocaleTimeString('fa-IR', {
// hour: '2-digit',
// minute: '2-digit'
// });
// };
function OrderTrackingPage() {
const { id, name } = useParams();
const router = useRouter();
const queryClient = useQueryClient();
const { state: cancelModal, toggle: toggleCancelModal } = useToggle();
const { data: orderDetail, isLoading } = useGetOrderDetail(id as string);
const { mutate: cancelOrder } = useCancelOrder();
const onCancelOrder = (e: React.MouseEvent | null) => {
if (!e || !id) return;
cancelOrder(id as string, {
onSuccess: () => {
toggleCancelModal();
queryClient.invalidateQueries({ queryKey: ['order-detail', id] });
toast('سفارش با موفقیت لغو شد', 'success');
},
onError: (error) => {
toast(extractErrorMessage(error), 'error');
}
});
};
return (
<div className="fixed inset-0 bg-container flex flex-col">
<div className='flex-1 overflow-y-auto px-4 py-6'>
<div className='max-w-2xl mx-auto flex flex-col gap-6'>
{isLoading ? (
<>
<Skeleton className='h-6 w-48 mx-auto' />
<div className='flex flex-col gap-4'>
<Skeleton className='h-5 w-full' />
<Skeleton className='h-5 w-full' />
<Skeleton className='h-20 w-full' />
<Skeleton className='h-5 w-full' />
</div>
</>
) : orderDetail?.data ? (
<>
<h1 className='text-lg font-semibold text-center'>
{getDeliveryMethodTitle(orderDetail.data.deliveryMethod.method)}
</h1>
<div className='flex flex-col'>
<div className='flex justify-between items-center h-16 border-b border-border'>
<span className='text-sm text-muted-foreground flex items-center gap-2'>
<Clock className='stroke-current' size={16} />
زمان سفارش
</span>
<div className='flex items-end gap-0.5'>
<span className='text-sm font-semibold'>{formatDate(orderDetail.data.createdAt)}</span>
{/* <span className='text-xs text-muted-foreground'>{formatTime(orderDetail.data.createdAt)}</span> */}
</div>
</div>
<div className='flex justify-between items-center h-16 border-b border-border'>
<span className='text-sm text-muted-foreground'>نوع ارسال</span>
<span className='text-sm font-semibold'>{orderDetail.data?.deliveryMethod?.description}</span>
</div>
<div className='flex justify-between items-center h-16 border-b border-border'>
<span className='text-sm text-muted-foreground'>شماره سفارش</span>
<span className='text-sm font-semibold'>#{orderDetail.data.orderNumber}</span>
</div>
<div className='flex justify-between items-center h-16 border-b border-border'>
<span className='text-sm text-muted-foreground'>وضعیت سفارش</span>
<span className='text-sm font-semibold'>{getStatusText(orderDetail.data.status)}</span>
</div>
{orderDetail.data.tableNumber && (
<div className='flex justify-between items-center h-16 border-b border-border'>
<span className='text-sm text-muted-foreground'>شماره میز</span>
<span className='text-sm font-semibold'>#{orderDetail.data.tableNumber}</span>
</div>
)}
{orderDetail.data.userAddress && (
<div className='py-3 border-b border-border'>
<div className='text-sm text-muted-foreground mb-1'>آدرس تحویل</div>
<div className='text-sm'>{orderDetail.data.userAddress.address}</div>
</div>
)}
<div className='flex justify-between items-center py-4 border-t border-border'>
<span className='text-sm font-medium'>مجموع سفارش</span>
<span className='text-sm font-bold text-primary'>
{orderDetail.data.total.toLocaleString('fa-IR')} تومان
</span>
</div>
</div>
</>
) : (
<div className='text-center text-muted-foreground py-12'>
اطلاعات سفارش یافت نشد
</div>
)}
</div>
</div>
<div className='p-4 border-t border-border bg-container'>
<div className='max-w-2xl mx-auto grid grid-cols-2 gap-4'>
<Button
onClick={() => router.push(`/${name}`)}
type='button'>
بازگشت به منو
</Button>
<Button
type='submit'
onClick={toggleCancelModal}
className='bg-disabled! text-foreground!'
disabled={
orderDetail?.data?.status === 'cancelled' ||
orderDetail?.data?.status === 'delivered' ||
orderDetail?.data?.status === 'delivering'
}
>
لغو سفارش
</Button>
</div>
</div>
<div className={clsx(
'fixed inset-0 z-1001',
!cancelModal && 'pointer-events-none'
)}>
<Prompt
title={'لغو سفارش'}
description={'آیا از درخواست خود اطمینان دارید؟'}
textConfirm={'بله'}
textCancel={'منصرف شدم'}
onConfirm={onCancelOrder}
visible={cancelModal}
onClick={toggleCancelModal}
onCancel={toggleCancelModal}
/>
</div>
</div>
);
}
export default OrderTrackingPage;