diff --git a/src/pages/orders/Details.tsx b/src/pages/orders/Details.tsx index b36e671..569bc06 100644 --- a/src/pages/orders/Details.tsx +++ b/src/pages/orders/Details.tsx @@ -9,12 +9,16 @@ import { useAddOrderItem, useUpdateOrderItemQuantity, useRemoveOrderItem, + useSendPleaseComeSms, } from './hooks/useOrderData' -import { useParams } from 'react-router-dom' +import { useNavigate, useParams } from 'react-router-dom' +import { ArrowRight2 } from 'iconsax-react' import { formatFaNumber } from '@/helpers/func' +import { Pages } from '@/config/Pages' import { OrderStatus, PaymentStatusEnum } from './enum/Enum' import { PaymentMethodEnum } from '@/pages/paymentMethods/enum/Enum' import { DeliveryMethodEnum } from '@/pages/shipmentMethod/enum/Enum' +import Button from '@/components/Button' import ModalConfrim from '@/components/ModalConfrim' import CustomerInfo from './components/CustomerInfo' import OrderItemsDetails from './components/OrderItemsDetails' @@ -25,6 +29,7 @@ import UpdateOrderFeesModal from './components/UpdateOrderFeesModal' import AddOrderItemModal from './components/AddOrderItemModal' import RefundPaymentModal from './components/RefundPaymentModal' import AddPaymentModal from './components/AddPaymentModal' +import SendPleaseComeSmsModal from './components/SendPleaseComeSmsModal' import { toast } from 'react-toastify' import { extractErrorMessage } from '@/config/func' import { printOrderReceipt } from './print/orderReceiptPrint' @@ -32,6 +37,7 @@ import type { UpdateOrderFeesType } from './types/Types' const OrderDetails: FC = () => { const { id } = useParams() + const navigate = useNavigate() const { data: orderData, isLoading } = useGetOrderById(id!) const { mutate: verifyPayment, isPending: isVerifyingPayment } = useVerifyPayment() const { mutate: changeOrderStatus, isPending: isChangingStatus } = useChangeOrderStatus() @@ -41,8 +47,10 @@ const OrderDetails: FC = () => { const { mutate: addOrderItem, isPending: isAddingItem } = useAddOrderItem() const { mutate: updateOrderItemQuantity, isPending: isUpdatingItemQuantity } = useUpdateOrderItemQuantity() const { mutate: removeOrderItem, isPending: isRemovingItem } = useRemoveOrderItem() + const { mutate: sendPleaseComeSms, isPending: isSendingPleaseComeSms } = useSendPleaseComeSms() const [showCancelModal, setShowCancelModal] = useState(false) + const [showPleaseComeSmsModal, setShowPleaseComeSmsModal] = useState(false) const [refundModal, setRefundModal] = useState<{ defaultAmount: number; maxAmount: number } | null>(null) const [showAddPaymentModal, setShowAddPaymentModal] = useState(false) const [showEditFeesModal, setShowEditFeesModal] = useState(false) @@ -98,6 +106,7 @@ const OrderDetails: FC = () => { OrderStatus.DELIVERED_TO_RECEPTIONIST, OrderStatus.SHIPPED, ].includes(order.status as OrderStatus) + const canSendPleaseComeSms = Boolean(order.user?.phone) const isCourierDelivery = order.deliveryMethod?.method === DeliveryMethodEnum.DeliveryCourier const isDineInOrCarDelivery = order.deliveryMethod?.method === DeliveryMethodEnum.DineIn || @@ -306,12 +315,33 @@ const OrderDetails: FC = () => { ) } + const handleConfirmPleaseComeSms = () => { + sendPleaseComeSms(order.id, { + onSuccess: (response) => { + toast.success(response.message || 'پیامک در صف ارسال قرار گرفت') + setShowPleaseComeSmsModal(false) + }, + onError: (error) => { + toast.error(extractErrorMessage(error)) + }, + }) + } + return (

سفارش {formatFaNumber(order.orderNumber)}

+
@@ -356,13 +386,16 @@ const OrderDetails: FC = () => { isCustomerPickup={isCustomerPickup} isCanceled={isCanceled} canCompleteOrder={canCompleteOrder} + canSendPleaseComeSms={canSendPleaseComeSms} isChangingStatus={isChangingStatus} + isSendingPleaseComeSms={isSendingPleaseComeSms} onSendToKitchen={handleSendToKitchen} onDeliverToCourier={handleDeliverToCourier} onDeliverToWaiter={handleDeliverToWaiter} onDeliverToReceptionist={handleDeliverToReceptionist} onCompleteOrder={handleCompleteOrder} onCancelOrder={() => setShowCancelModal(true)} + onSendPleaseComeSms={() => setShowPleaseComeSmsModal(true)} />
@@ -416,6 +449,15 @@ const OrderDetails: FC = () => { isloading={isRemovingItem} label='آیا از حذف این آیتم مطمئن هستید؟' /> + + setShowPleaseComeSmsModal(false)} + isLoading={isSendingPleaseComeSms} + customerName={order.user?.firstName || ''} + restaurantName={order.restaurant?.name || ''} + onConfirm={handleConfirmPleaseComeSms} + /> ) } diff --git a/src/pages/orders/List.tsx b/src/pages/orders/List.tsx index d69abf0..e91b174 100644 --- a/src/pages/orders/List.tsx +++ b/src/pages/orders/List.tsx @@ -1,4 +1,4 @@ -import { type FC } from 'react' +import { type FC, useState } from 'react' import { useTranslation } from 'react-i18next' import { Add } from 'iconsax-react' import { Link } from 'react-router-dom' @@ -6,12 +6,15 @@ import Table from '@/components/Table' import Filters from '@/components/Filters' import Button from '@/components/Button' import { Pages } from '@/config/Pages' -import { useGetOrders } from './hooks/useOrderData' +import { useGetOrders, useSendPleaseComeSms } from './hooks/useOrderData' import { useOrderFilters } from './hooks/useOrderFilters' import { getOrderTableColumns } from './components/OrderTableColumns' import { useOrderFiltersFields } from './components/OrderFiltersFields' +import SendPleaseComeSmsModal from './components/SendPleaseComeSmsModal' import type { Order } from './types/Types' import type { RowDataType } from '@/components/types/TableTypes' +import { toast } from 'react-toastify' +import { extractErrorMessage } from '@/config/func' const OrdersList: FC = () => { const { t } = useTranslation('global') @@ -24,13 +27,32 @@ const OrdersList: FC = () => { } = useOrderFilters() const { data: ordersData, isLoading } = useGetOrders(apiParams) + const { mutate: sendPleaseComeSms, isPending: isSendingSms } = useSendPleaseComeSms() + const [smsOrder, setSmsOrder] = useState(null) const orders = ordersData?.data || [] - const columns = getOrderTableColumns({ t }) + const columns = getOrderTableColumns({ + t, + onSendPleaseComeSms: (order) => setSmsOrder(order), + }) const filterFields = useOrderFiltersFields() const totalPages = ordersData?.meta?.totalPages || 1 + const handleConfirmSendSms = () => { + if (!smsOrder) return + + sendPleaseComeSms(smsOrder.id, { + onSuccess: (response) => { + toast.success(response.message || 'پیامک در صف ارسال قرار گرفت') + setSmsOrder(null) + }, + onError: (error) => { + toast.error(extractErrorMessage(error)) + }, + }) + } + return (
@@ -64,8 +86,17 @@ const OrdersList: FC = () => { onPageChange: handlePageChange, }} /> + + setSmsOrder(null)} + isLoading={isSendingSms} + customerName={smsOrder?.user?.firstName || ''} + restaurantName={smsOrder?.restaurant?.name || ''} + onConfirm={handleConfirmSendSms} + />
) } -export default OrdersList \ No newline at end of file +export default OrdersList diff --git a/src/pages/orders/components/OrderActions.tsx b/src/pages/orders/components/OrderActions.tsx index 9746800..bd7009e 100644 --- a/src/pages/orders/components/OrderActions.tsx +++ b/src/pages/orders/components/OrderActions.tsx @@ -1,144 +1,162 @@ -import Button from '@/components/Button' -import { type FC, useState, useEffect } from 'react' +import Button from "@/components/Button"; +import { type FC, useState, useEffect } from "react"; interface OrderActionsProps { - onPrint: () => void - showSendToKitchenButton: boolean - showCancelButton: boolean - isPreparing: boolean - isCourierDelivery: boolean - isDineInOrCarDelivery: boolean - isCustomerPickup: boolean - isCanceled: boolean - canCompleteOrder: boolean - isChangingStatus: boolean - onSendToKitchen: () => void - onDeliverToCourier: () => void - onDeliverToWaiter: () => void - onDeliverToReceptionist: () => void - onCompleteOrder: () => void - onCancelOrder: () => void + onPrint: () => void; + showSendToKitchenButton: boolean; + showCancelButton: boolean; + isPreparing: boolean; + isCourierDelivery: boolean; + isDineInOrCarDelivery: boolean; + isCustomerPickup: boolean; + isCanceled: boolean; + canCompleteOrder: boolean; + canSendPleaseComeSms: boolean; + isChangingStatus: boolean; + isSendingPleaseComeSms?: boolean; + onSendToKitchen: () => void; + onDeliverToCourier: () => void; + onDeliverToWaiter: () => void; + onDeliverToReceptionist: () => void; + onCompleteOrder: () => void; + onCancelOrder: () => void; + onSendPleaseComeSms: () => void; } const OrderActions: FC = ({ - onPrint, - showSendToKitchenButton, - showCancelButton, - isPreparing, - isCourierDelivery, - isDineInOrCarDelivery, - isCustomerPickup, - isCanceled, - canCompleteOrder, - isChangingStatus, - onSendToKitchen, - onDeliverToCourier, - onDeliverToWaiter, - onDeliverToReceptionist, - onCompleteOrder, - onCancelOrder, + onPrint, + showSendToKitchenButton, + showCancelButton, + isPreparing, + isCourierDelivery, + isDineInOrCarDelivery, + isCustomerPickup, + isCanceled, + canCompleteOrder, + canSendPleaseComeSms, + isChangingStatus, + isSendingPleaseComeSms, + onSendToKitchen, + onDeliverToCourier, + onDeliverToWaiter, + onDeliverToReceptionist, + onCompleteOrder, + onCancelOrder, + onSendPleaseComeSms, }) => { - const [loadingAction, setLoadingAction] = useState(null) + const [loadingAction, setLoadingAction] = useState(null); - useEffect(() => { - if (!isChangingStatus) { - setLoadingAction(null) - } - }, [isChangingStatus]) - - const handleSendToKitchen = () => { - setLoadingAction('sendToKitchen') - onSendToKitchen() + useEffect(() => { + if (!isChangingStatus) { + setLoadingAction(null); } + }, [isChangingStatus]); - const handleDeliverToCourier = () => { - setLoadingAction('deliverToCourier') - onDeliverToCourier() - } + const handleSendToKitchen = () => { + setLoadingAction("sendToKitchen"); + onSendToKitchen(); + }; - const handleDeliverToWaiter = () => { - setLoadingAction('deliverToWaiter') - onDeliverToWaiter() - } + const handleDeliverToCourier = () => { + setLoadingAction("deliverToCourier"); + onDeliverToCourier(); + }; - const handleDeliverToReceptionist = () => { - setLoadingAction('deliverToReceptionist') - onDeliverToReceptionist() - } + const handleDeliverToWaiter = () => { + setLoadingAction("deliverToWaiter"); + onDeliverToWaiter(); + }; - const handleCancelOrder = () => { - setLoadingAction('cancelOrder') - onCancelOrder() - } + const handleDeliverToReceptionist = () => { + setLoadingAction("deliverToReceptionist"); + onDeliverToReceptionist(); + }; - const handleCompleteOrder = () => { - setLoadingAction('completeOrder') - onCompleteOrder() - } + const handleCancelOrder = () => { + setLoadingAction("cancelOrder"); + onCancelOrder(); + }; - return ( -
-
- {!isCanceled && isPreparing && isDineInOrCarDelivery && ( -
- ) -} + {!isCanceled && isPreparing && isCustomerPickup && ( + + )} + + + + + ); + }, + }, + ]; +}; diff --git a/src/pages/orders/components/SendPleaseComeSmsModal.tsx b/src/pages/orders/components/SendPleaseComeSmsModal.tsx new file mode 100644 index 0000000..7dd6f20 --- /dev/null +++ b/src/pages/orders/components/SendPleaseComeSmsModal.tsx @@ -0,0 +1,57 @@ +import { type FC } from 'react' +import DefaulModal from '@/components/DefaulModal' +import Button from '@/components/Button' + +interface SendPleaseComeSmsModalProps { + isOpen: boolean + onClose: () => void + isLoading?: boolean + customerName: string + restaurantName: string + onConfirm: () => void +} + +const SendPleaseComeSmsModal: FC = ({ + isOpen, + onClose, + isLoading, + customerName, + restaurantName, + onConfirm, +}) => { + const previewMessage = `${customerName || '#NAME#'} عزیز لطفا به پیشخوان ${restaurantName || '#REST#'} مراجعه کنید.` + + return ( + +
+

+ متن پیامک: +

+
+ {previewMessage} +
+ +
+
+
+
+ ) +} + +export default SendPleaseComeSmsModal diff --git a/src/pages/orders/hooks/useOrderData.ts b/src/pages/orders/hooks/useOrderData.ts index b2018d9..72cb15e 100644 --- a/src/pages/orders/hooks/useOrderData.ts +++ b/src/pages/orders/hooks/useOrderData.ts @@ -155,3 +155,9 @@ export const useRemoveOrderItem = () => { }, }); }; + +export const useSendPleaseComeSms = () => { + return useMutation({ + mutationFn: (orderId: string) => api.sendPleaseComeSms(orderId), + }); +}; diff --git a/src/pages/orders/service/OrderService.ts b/src/pages/orders/service/OrderService.ts index 7eeb1ef..188e15d 100644 --- a/src/pages/orders/service/OrderService.ts +++ b/src/pages/orders/service/OrderService.ts @@ -191,3 +191,10 @@ export const getDailyOrderReport = async ( ); return data; }; + +export const sendPleaseComeSms = async (orderId: string): Promise<{ message: string }> => { + const { data } = await axios.post<{ message: string }>( + `/admin/orders/${orderId}/please-come` + ); + return data; +};