details order refactor
This commit is contained in:
@@ -15,6 +15,8 @@ import CustomerInfo from './components/CustomerInfo'
|
|||||||
import OrderItemsDetails from './components/OrderItemsDetails'
|
import OrderItemsDetails from './components/OrderItemsDetails'
|
||||||
import PaymentInfo from './components/PaymentInfo'
|
import PaymentInfo from './components/PaymentInfo'
|
||||||
import OrderActions from './components/OrderActions'
|
import OrderActions from './components/OrderActions'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
import { extractErrorMessage } from '@/config/func'
|
||||||
|
|
||||||
const OrderDetails: FC = () => {
|
const OrderDetails: FC = () => {
|
||||||
const { id } = useParams()
|
const { id } = useParams()
|
||||||
@@ -32,7 +34,6 @@ const OrderDetails: FC = () => {
|
|||||||
const colorMap: Record<string, string> = {
|
const colorMap: Record<string, string> = {
|
||||||
'pendingPayment': '#FFEECC',
|
'pendingPayment': '#FFEECC',
|
||||||
'paid': '#E3F2FD',
|
'paid': '#E3F2FD',
|
||||||
'confirmed': '#E3F2FD',
|
|
||||||
'preparing': '#FFF3E0',
|
'preparing': '#FFF3E0',
|
||||||
'ready': '#E3F2FD',
|
'ready': '#E3F2FD',
|
||||||
'shipped': '#E3F2FD',
|
'shipped': '#E3F2FD',
|
||||||
@@ -89,51 +90,51 @@ const OrderDetails: FC = () => {
|
|||||||
const isCashPayment = order.paymentMethod?.method === PaymentMethodEnum.Cash
|
const isCashPayment = order.paymentMethod?.method === PaymentMethodEnum.Cash
|
||||||
const isPendingPayment = order.status === OrderStatus.PENDING_PAYMENT
|
const isPendingPayment = order.status === OrderStatus.PENDING_PAYMENT
|
||||||
const isOrderPaid = order.status === OrderStatus.PAID
|
const isOrderPaid = order.status === OrderStatus.PAID
|
||||||
const isConfirmed = order.status === OrderStatus.CONFIRMED
|
|
||||||
const isPreparing = order.status === OrderStatus.PREPARING
|
const isPreparing = order.status === OrderStatus.PREPARING
|
||||||
const isCanceled = order.status === OrderStatus.CANCELED
|
const isCanceled = order.status === OrderStatus.CANCELED
|
||||||
const isOnlineOrWalletPayment = order.paymentMethod?.method === PaymentMethodEnum.Online || order.paymentMethod?.method === PaymentMethodEnum.Wallet
|
// بررسی وضعیت پرداخت از payments array یا paymentStatus
|
||||||
|
// ابتدا از paymentStatus استفاده میکنیم، اگر نبود از اولین payment در payments array استفاده میکنیم
|
||||||
|
const paymentStatus = order.paymentStatus || order.payments?.[0]?.status
|
||||||
|
// بررسی وضعیت pending (هم enum و هم string literal)
|
||||||
|
const isPaymentPending = paymentStatus === PaymentStatusEnum.Pending || paymentStatus === 'pending'
|
||||||
const isCourierDelivery = order.deliveryMethod?.method === DeliveryMethodEnum.DeliveryCourier
|
const isCourierDelivery = order.deliveryMethod?.method === DeliveryMethodEnum.DeliveryCourier
|
||||||
|
const isDineInOrCarDelivery = order.deliveryMethod?.method === DeliveryMethodEnum.DineIn || order.deliveryMethod?.method === DeliveryMethodEnum.DeliveryCar
|
||||||
|
const isCustomerPickup = order.deliveryMethod?.method === DeliveryMethodEnum.CustomerPickup
|
||||||
|
|
||||||
// نمایش دکمه تایید پرداخت نقدی
|
// نمایش دکمه تایید پرداخت نقدی
|
||||||
const showVerifyCashPaymentButton = isCashPayment && isPendingPayment
|
// وقتی روش پرداخت نقدی است و وضعیت پرداخت Pending باشد
|
||||||
|
const showVerifyCashPaymentButton = isCashPayment && isPaymentPending
|
||||||
// نمایش دکمه تایید سفارش (confirm)
|
|
||||||
// سفارشات پرداخت آنلاین و کیف پولی فقط در صورتی میتوانند confirm شوند که status آنها paid باشد
|
|
||||||
// سفارشات پرداخت نقدی میتوانند تایید شوند
|
|
||||||
const canConfirm = !isConfirmed && !isPreparing && !isCanceled && (
|
|
||||||
isCashPayment ||
|
|
||||||
(isOnlineOrWalletPayment && isOrderPaid)
|
|
||||||
)
|
|
||||||
|
|
||||||
// نمایش دکمه ارسال به آشپزخانه
|
// نمایش دکمه ارسال به آشپزخانه
|
||||||
const showSendToKitchenButton = isConfirmed
|
// برای pendingPayment با پرداخت نقدی یا برای paid
|
||||||
|
const showSendToKitchenButton = (isPendingPayment && isCashPayment) || isOrderPaid
|
||||||
|
|
||||||
// نمایش دکمه کنسل (ادمین همیشه میتواند، مگر اینکه سفارش کنسل شده باشد)
|
// نمایش دکمه کنسل
|
||||||
|
// همیشه نمایش داده میشود مگر اینکه سفارش قبلاً کنسل شده باشد
|
||||||
const showCancelButton = !isCanceled
|
const showCancelButton = !isCanceled
|
||||||
|
|
||||||
const handleVerifyCashPayment = () => {
|
const handleVerifyCashPayment = () => {
|
||||||
const paymentId = order.paymentId || order.paymentMethod?.id
|
const paymentId = order.paymentId || order.payments?.[0]?.id
|
||||||
if (paymentId) {
|
if (paymentId) {
|
||||||
verifyCashPayment(paymentId, {
|
verifyCashPayment(paymentId, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
// Success handled by query invalidation
|
// Success handled by query invalidation
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleConfirmOrder = () => {
|
|
||||||
changeOrderStatus({
|
|
||||||
orderId: order.id,
|
|
||||||
status: OrderStatus.CONFIRMED
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSendToKitchen = () => {
|
const handleSendToKitchen = () => {
|
||||||
changeOrderStatus({
|
changeOrderStatus({
|
||||||
orderId: order.id,
|
orderId: order.id,
|
||||||
status: OrderStatus.PREPARING
|
status: OrderStatus.PREPARING
|
||||||
|
}, {
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,13 +142,32 @@ const OrderDetails: FC = () => {
|
|||||||
changeOrderStatus({
|
changeOrderStatus({
|
||||||
orderId: order.id,
|
orderId: order.id,
|
||||||
status: OrderStatus.SHIPPED
|
status: OrderStatus.SHIPPED
|
||||||
|
}, {
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOrderReady = () => {
|
const handleDeliverToWaiter = () => {
|
||||||
changeOrderStatus({
|
changeOrderStatus({
|
||||||
orderId: order.id,
|
orderId: order.id,
|
||||||
status: OrderStatus.READY
|
status: OrderStatus.DELIVERED_TO_WAITER
|
||||||
|
}, {
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeliverToReceptionist = () => {
|
||||||
|
changeOrderStatus({
|
||||||
|
orderId: order.id,
|
||||||
|
status: OrderStatus.DELIVERED_TO_RECEPTIONIST
|
||||||
|
}, {
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +176,10 @@ const OrderDetails: FC = () => {
|
|||||||
orderId: order.id,
|
orderId: order.id,
|
||||||
status: OrderStatus.CANCELED,
|
status: OrderStatus.CANCELED,
|
||||||
params: description ? { description } : undefined
|
params: description ? { description } : undefined
|
||||||
|
}, {
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
setShowCancelModal(false)
|
setShowCancelModal(false)
|
||||||
}
|
}
|
||||||
@@ -165,6 +189,10 @@ const OrderDetails: FC = () => {
|
|||||||
refundPayment({
|
refundPayment({
|
||||||
orderId: order.id,
|
orderId: order.id,
|
||||||
params: { description: text }
|
params: { description: text }
|
||||||
|
}, {
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
setShowRefundModal(false)
|
setShowRefundModal(false)
|
||||||
}
|
}
|
||||||
@@ -201,19 +229,20 @@ const OrderDetails: FC = () => {
|
|||||||
/>
|
/>
|
||||||
<OrderActions
|
<OrderActions
|
||||||
showVerifyCashPaymentButton={showVerifyCashPaymentButton}
|
showVerifyCashPaymentButton={showVerifyCashPaymentButton}
|
||||||
canConfirm={canConfirm}
|
|
||||||
showSendToKitchenButton={showSendToKitchenButton}
|
showSendToKitchenButton={showSendToKitchenButton}
|
||||||
showCancelButton={showCancelButton}
|
showCancelButton={showCancelButton}
|
||||||
isPreparing={isPreparing}
|
isPreparing={isPreparing}
|
||||||
isCourierDelivery={isCourierDelivery}
|
isCourierDelivery={isCourierDelivery}
|
||||||
|
isDineInOrCarDelivery={isDineInOrCarDelivery}
|
||||||
|
isCustomerPickup={isCustomerPickup}
|
||||||
isCanceled={isCanceled}
|
isCanceled={isCanceled}
|
||||||
isVerifyingPayment={isVerifyingPayment}
|
isVerifyingPayment={isVerifyingPayment}
|
||||||
isChangingStatus={isChangingStatus}
|
isChangingStatus={isChangingStatus}
|
||||||
onVerifyCashPayment={handleVerifyCashPayment}
|
onVerifyCashPayment={handleVerifyCashPayment}
|
||||||
onConfirmOrder={handleConfirmOrder}
|
|
||||||
onSendToKitchen={handleSendToKitchen}
|
onSendToKitchen={handleSendToKitchen}
|
||||||
onDeliverToCourier={handleDeliverToCourier}
|
onDeliverToCourier={handleDeliverToCourier}
|
||||||
onOrderReady={handleOrderReady}
|
onDeliverToWaiter={handleDeliverToWaiter}
|
||||||
|
onDeliverToReceptionist={handleDeliverToReceptionist}
|
||||||
onCancelOrder={() => setShowCancelModal(true)}
|
onCancelOrder={() => setShowCancelModal(true)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,41 +1,76 @@
|
|||||||
import Button from '@/components/Button'
|
import Button from '@/components/Button'
|
||||||
import type { FC } from 'react'
|
import { type FC, useState, useEffect } from 'react'
|
||||||
|
|
||||||
interface OrderActionsProps {
|
interface OrderActionsProps {
|
||||||
showVerifyCashPaymentButton: boolean
|
showVerifyCashPaymentButton: boolean
|
||||||
canConfirm: boolean
|
|
||||||
showSendToKitchenButton: boolean
|
showSendToKitchenButton: boolean
|
||||||
showCancelButton: boolean
|
showCancelButton: boolean
|
||||||
isPreparing: boolean
|
isPreparing: boolean
|
||||||
isCourierDelivery: boolean
|
isCourierDelivery: boolean
|
||||||
|
isDineInOrCarDelivery: boolean
|
||||||
|
isCustomerPickup: boolean
|
||||||
isCanceled: boolean
|
isCanceled: boolean
|
||||||
isVerifyingPayment: boolean
|
isVerifyingPayment: boolean
|
||||||
isChangingStatus: boolean
|
isChangingStatus: boolean
|
||||||
onVerifyCashPayment: () => void
|
onVerifyCashPayment: () => void
|
||||||
onConfirmOrder: () => void
|
|
||||||
onSendToKitchen: () => void
|
onSendToKitchen: () => void
|
||||||
onDeliverToCourier: () => void
|
onDeliverToCourier: () => void
|
||||||
onOrderReady: () => void
|
onDeliverToWaiter: () => void
|
||||||
|
onDeliverToReceptionist: () => void
|
||||||
onCancelOrder: () => void
|
onCancelOrder: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const OrderActions: FC<OrderActionsProps> = ({
|
const OrderActions: FC<OrderActionsProps> = ({
|
||||||
showVerifyCashPaymentButton,
|
showVerifyCashPaymentButton,
|
||||||
canConfirm,
|
|
||||||
showSendToKitchenButton,
|
showSendToKitchenButton,
|
||||||
showCancelButton,
|
showCancelButton,
|
||||||
isPreparing,
|
isPreparing,
|
||||||
isCourierDelivery,
|
isCourierDelivery,
|
||||||
|
isDineInOrCarDelivery,
|
||||||
|
isCustomerPickup,
|
||||||
isCanceled,
|
isCanceled,
|
||||||
isVerifyingPayment,
|
isVerifyingPayment,
|
||||||
isChangingStatus,
|
isChangingStatus,
|
||||||
onVerifyCashPayment,
|
onVerifyCashPayment,
|
||||||
onConfirmOrder,
|
|
||||||
onSendToKitchen,
|
onSendToKitchen,
|
||||||
onDeliverToCourier,
|
onDeliverToCourier,
|
||||||
onOrderReady,
|
onDeliverToWaiter,
|
||||||
|
onDeliverToReceptionist,
|
||||||
onCancelOrder
|
onCancelOrder
|
||||||
}) => {
|
}) => {
|
||||||
|
const [loadingAction, setLoadingAction] = useState<string | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isChangingStatus && !isVerifyingPayment) {
|
||||||
|
setLoadingAction(null)
|
||||||
|
}
|
||||||
|
}, [isChangingStatus, isVerifyingPayment])
|
||||||
|
|
||||||
|
const handleSendToKitchen = () => {
|
||||||
|
setLoadingAction('sendToKitchen')
|
||||||
|
onSendToKitchen()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeliverToCourier = () => {
|
||||||
|
setLoadingAction('deliverToCourier')
|
||||||
|
onDeliverToCourier()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeliverToWaiter = () => {
|
||||||
|
setLoadingAction('deliverToWaiter')
|
||||||
|
onDeliverToWaiter()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeliverToReceptionist = () => {
|
||||||
|
setLoadingAction('deliverToReceptionist')
|
||||||
|
onDeliverToReceptionist()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCancelOrder = () => {
|
||||||
|
setLoadingAction('cancelOrder')
|
||||||
|
onCancelOrder()
|
||||||
|
}
|
||||||
|
|
||||||
if (isCanceled) return null
|
if (isCanceled) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -49,19 +84,11 @@ const OrderActions: FC<OrderActionsProps> = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{canConfirm && (
|
|
||||||
<Button
|
|
||||||
label='تایید سفارش'
|
|
||||||
onClick={onConfirmOrder}
|
|
||||||
isloading={isChangingStatus}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{showSendToKitchenButton && (
|
{showSendToKitchenButton && (
|
||||||
<Button
|
<Button
|
||||||
label='ارسال به آشپزخانه'
|
label='ارسال به آشپزخانه'
|
||||||
onClick={onSendToKitchen}
|
onClick={handleSendToKitchen}
|
||||||
isloading={isChangingStatus}
|
isloading={isChangingStatus && loadingAction === 'sendToKitchen'}
|
||||||
className='bg-orange-600 hover:bg-orange-700'
|
className='bg-orange-600 hover:bg-orange-700'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -69,26 +96,35 @@ const OrderActions: FC<OrderActionsProps> = ({
|
|||||||
{isPreparing && isCourierDelivery && (
|
{isPreparing && isCourierDelivery && (
|
||||||
<Button
|
<Button
|
||||||
label='تحویل به پیک'
|
label='تحویل به پیک'
|
||||||
onClick={onDeliverToCourier}
|
onClick={handleDeliverToCourier}
|
||||||
isloading={isChangingStatus}
|
isloading={isChangingStatus && loadingAction === 'deliverToCourier'}
|
||||||
className='bg-blue-600 hover:bg-blue-700'
|
className='bg-blue-600 hover:bg-blue-700'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isPreparing && !isCourierDelivery && (
|
{isPreparing && isDineInOrCarDelivery && (
|
||||||
<Button
|
<Button
|
||||||
label='غذا آماده است'
|
label='تحویل به گارسون'
|
||||||
onClick={onOrderReady}
|
onClick={handleDeliverToWaiter}
|
||||||
isloading={isChangingStatus}
|
isloading={isChangingStatus && loadingAction === 'deliverToWaiter'}
|
||||||
className='bg-green-600 hover:bg-green-700'
|
className='bg-purple-600 hover:bg-purple-700'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isPreparing && isCustomerPickup && (
|
||||||
|
<Button
|
||||||
|
label='تحویل به رسپشنیست'
|
||||||
|
onClick={handleDeliverToReceptionist}
|
||||||
|
isloading={isChangingStatus && loadingAction === 'deliverToReceptionist'}
|
||||||
|
className='bg-indigo-600 hover:bg-indigo-700'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{showCancelButton && (
|
{showCancelButton && (
|
||||||
<Button
|
<Button
|
||||||
label='لغو سفارش'
|
label='لغو سفارش'
|
||||||
onClick={onCancelOrder}
|
onClick={handleCancelOrder}
|
||||||
isloading={isChangingStatus}
|
isloading={isChangingStatus && loadingAction === 'cancelOrder'}
|
||||||
className='bg-red-600 hover:bg-red-700'
|
className='bg-red-600 hover:bg-red-700'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ const getStatusVariant = (status: string): 'success' | 'error' | 'warning' | 'in
|
|||||||
const variantMap: Record<string, 'success' | 'error' | 'warning' | 'info' | 'pending'> = {
|
const variantMap: Record<string, 'success' | 'error' | 'warning' | 'info' | 'pending'> = {
|
||||||
'pendingPayment': 'pending',
|
'pendingPayment': 'pending',
|
||||||
'paid': 'info',
|
'paid': 'info',
|
||||||
'confirmed': 'info',
|
|
||||||
'preparing': 'warning',
|
'preparing': 'warning',
|
||||||
'ready': 'info',
|
'ready': 'info',
|
||||||
'shipped': 'info',
|
'shipped': 'info',
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
export enum OrderStatus {
|
export enum OrderStatus {
|
||||||
PENDING_PAYMENT = "pendingPayment",
|
PENDING_PAYMENT = "pendingPayment",
|
||||||
PAID = "paid",
|
PAID = "paid",
|
||||||
CONFIRMED = "confirmed",
|
|
||||||
PREPARING = "preparing",
|
PREPARING = "preparing",
|
||||||
READY = "ready",
|
READY = "ready",
|
||||||
|
DELIVERED_TO_WAITER = "deliveredToWaiter",
|
||||||
|
DELIVERED_TO_RECEPTIONIST = "deliveredToReceptionist",
|
||||||
SHIPPED = "shipped",
|
SHIPPED = "shipped",
|
||||||
COMPLETED = "completed",
|
COMPLETED = "completed",
|
||||||
CANCELED = "canceled",
|
CANCELED = "canceled",
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import { type FC } from 'react'
|
import { type FC } from 'react'
|
||||||
import { Cell, LabelList, Pie, PieChart, ResponsiveContainer } from 'recharts'
|
import { Cell, LabelList, Pie, PieChart, ResponsiveContainer } from 'recharts'
|
||||||
|
import { useGetFoodSalesPieChart } from '../hooks/useStatsData';
|
||||||
|
|
||||||
interface FoodSalesChartProps {
|
interface FoodSalesChartProps {
|
||||||
data?: Array<{ name: string; value: number; color: string }>
|
data?: Array<{ name: string; value: number; color: string }>
|
||||||
}
|
}
|
||||||
|
|
||||||
const FoodSalesChart: FC<FoodSalesChartProps> = ({ data }) => {
|
const FoodSalesChart: FC<FoodSalesChartProps> = ({ data }) => {
|
||||||
|
|
||||||
|
useGetFoodSalesPieChart()
|
||||||
|
|
||||||
const defaultData = [
|
const defaultData = [
|
||||||
{ name: 'پیتزا', value: 50, color: '#6B7FED' },
|
{ name: 'پیتزا', value: 50, color: '#6B7FED' },
|
||||||
{ name: 'برگر', value: 25, color: '#A78BFA' },
|
{ name: 'برگر', value: 25, color: '#A78BFA' },
|
||||||
|
|||||||
Reference in New Issue
Block a user