diff --git a/src/app/[name]/(Dialogs)/cart/components/CartSummary.tsx b/src/app/[name]/(Dialogs)/cart/components/CartSummary.tsx index 6559a94..34c8526 100644 --- a/src/app/[name]/(Dialogs)/cart/components/CartSummary.tsx +++ b/src/app/[name]/(Dialogs)/cart/components/CartSummary.tsx @@ -2,12 +2,14 @@ import React from 'react'; import Link from 'next/link'; +import { useParams, useRouter, usePathname } from 'next/navigation'; import Button from '@/components/button/PrimaryButton'; import { useGetFoods } from '@/app/[name]/(Main)/hooks/useMenuData'; import type { Food } from '@/app/[name]/(Main)/types/Types'; import { useCart } from '../hook/useCart'; import { useTranslation } from 'react-i18next'; import { Add, Minus } from 'iconsax-react'; +import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData'; interface CartSummaryProps { description?: string; @@ -15,6 +17,11 @@ interface CartSummaryProps { } const CartSummary = ({ description = '', onDescriptionChange }: CartSummaryProps) => { + const params = useParams(); + const router = useRouter(); + const pathname = usePathname(); + const name = params.name as string; + const { isSuccess } = useGetProfile(); const { data: foodsResponse } = useGetFoods(); const foods = React.useMemo(() => foodsResponse?.data ?? [], [foodsResponse?.data]); const { items } = useCart(); @@ -72,6 +79,13 @@ const CartSummary = ({ description = '', onDescriptionChange }: CartSummaryProps onClick={(event) => { if (isCartEmpty) { event.preventDefault(); + return; + } + if (!isSuccess) { + event.preventDefault(); + const redirectUrl = encodeURIComponent(pathname); + router.push(`/${name}/auth?redirect=${redirectUrl}`); + return; } }} className={isCartEmpty ? 'pointer-events-none opacity-60' : ''} diff --git a/src/app/[name]/(Dialogs)/order/checkout/[id]/components/SummarySection.tsx b/src/app/[name]/(Dialogs)/order/checkout/[id]/components/SummarySection.tsx index c39110f..c9c6985 100644 --- a/src/app/[name]/(Dialogs)/order/checkout/[id]/components/SummarySection.tsx +++ b/src/app/[name]/(Dialogs)/order/checkout/[id]/components/SummarySection.tsx @@ -4,6 +4,9 @@ import AnimatedBottomSheet from '@/components/bottomsheet/AnimatedBottomSheet'; import Button from '@/components/button/PrimaryButton'; import { ChevronLeft } from 'lucide-react'; import { useTranslation } from 'react-i18next'; +import { useCheckoutStore } from '../../store/Store'; +import { toast } from '@/components/Toast'; +import { useCreateOrder } from '../../hooks/useOrderData'; type SummarySectionProps = { cartModal: boolean; @@ -11,7 +14,35 @@ type SummarySectionProps = { }; export const SummarySection = ({ cartModal, onToggleCartModal }: SummarySectionProps) => { + const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' }); + const { isSelectedAddress, isSelectedShipment, isSelectedPayment } = useCheckoutStore(); + const { mutate: createOrder } = useCreateOrder(); + + const handleSubmit = () => { + if (!isSelectedAddress) { + toast('لطفا آدرس را انتخاب کنید', 'error'); + return; + } + if (!isSelectedShipment) { + toast('لطفا روش تحویل را انتخاب کنید', 'error'); + return; + } + if (!isSelectedPayment) { + toast('لطفا روش پرداخت را انتخاب کنید', 'error'); + return; + } + + createOrder(undefined, { + onSuccess: () => { + toast('سفارش با موفقیت ثبت شد', 'success'); + onToggleCartModal(); + }, + onError: () => { + toast('خطا در ثبت سفارش', 'error'); + } + }); + }; return ( <> @@ -37,7 +68,7 @@ export const SummarySection = ({ cartModal, onToggleCartModal }: SummarySectionP {t("SectionSummary.TotalLabel")} 110,000 T - diff --git a/src/app/[name]/(Dialogs)/order/checkout/[id]/page.tsx b/src/app/[name]/(Dialogs)/order/checkout/[id]/page.tsx index 1232e89..49a2aa2 100644 --- a/src/app/[name]/(Dialogs)/order/checkout/[id]/page.tsx +++ b/src/app/[name]/(Dialogs)/order/checkout/[id]/page.tsx @@ -1,7 +1,7 @@ 'use client'; import useToggle from '@/hooks/helpers/useToggle'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { AddressSection } from './components/AddressSection'; import { CheckoutHeader } from './components/CheckoutHeader'; import { CouponSection } from './components/CouponSection'; @@ -9,6 +9,7 @@ import { PaymentSection } from './components/PaymentSection'; import { ShippingSection } from './components/ShippingSection'; import { SummarySection } from './components/SummarySection'; import { TableSection } from './components/TableSection'; +import { useGetShipmentMethod } from '../hooks/useOrderData'; function OrderDetailInex() { const [deliveryType, setDeliveryType] = React.useState('0'); @@ -18,6 +19,7 @@ function OrderDetailInex() { const [couponCodeError, setCouponCodeError] = React.useState(''); const [tableNumber, setTableNumber] = useState(0); const { state: cartModal, toggle: toggleCartModal } = useToggle(); + const { data: shipmentMethod } = useGetShipmentMethod(); const incrementTableNumber = () => setTableNumber((prev) => prev + 1); const decrementTableNumber = () => setTableNumber((prev) => prev - 1); @@ -40,6 +42,16 @@ function OrderDetailInex() { setCouponCode(value); }, []); + const selectedDeliveryMethod = useMemo(() => { + if (!shipmentMethod?.data || !deliveryType) return null; + return shipmentMethod.data.find((item) => item.id === deliveryType); + }, [shipmentMethod?.data, deliveryType]); + + const shouldShowAddress = useMemo(() => { + if (!selectedDeliveryMethod) return true; + return selectedDeliveryMethod.method !== 'dineIn' && selectedDeliveryMethod.method !== 'deliveryCar'; + }, [selectedDeliveryMethod]); + return (
@@ -49,7 +61,7 @@ function OrderDetailInex() { onDeliveryTypeChange={changeDeliveryType} /> - {deliveryType === '0' && ( + {shouldShowAddress && ( )} diff --git a/src/app/[name]/(Dialogs)/order/checkout/hooks/useOrderData.ts b/src/app/[name]/(Dialogs)/order/checkout/hooks/useOrderData.ts index 66c26c9..fb71d91 100644 --- a/src/app/[name]/(Dialogs)/order/checkout/hooks/useOrderData.ts +++ b/src/app/[name]/(Dialogs)/order/checkout/hooks/useOrderData.ts @@ -5,6 +5,7 @@ import { setAddressCart, setDeliveryMethod, setPaymentMethod, + createOrder, } from "../service/OrderService"; export const useGetShipmentMethod = () => { @@ -38,3 +39,9 @@ export const useSetPaymentMethod = () => { mutationFn: setPaymentMethod, }); }; + +export const useCreateOrder = () => { + return useMutation({ + mutationFn: createOrder, + }); +}; diff --git a/src/app/[name]/(Dialogs)/order/checkout/service/OrderService.ts b/src/app/[name]/(Dialogs)/order/checkout/service/OrderService.ts index bb3722a..5596122 100644 --- a/src/app/[name]/(Dialogs)/order/checkout/service/OrderService.ts +++ b/src/app/[name]/(Dialogs)/order/checkout/service/OrderService.ts @@ -36,3 +36,8 @@ export const setPaymentMethod = async (id: string) => { }); return data; }; + +export const createOrder = async () => { + const { data } = await api.post("/public/checkout"); + return data; +}; diff --git a/src/features/auth/components/StepOtp.tsx b/src/features/auth/components/StepOtp.tsx index 05e60a8..69de111 100644 --- a/src/features/auth/components/StepOtp.tsx +++ b/src/features/auth/components/StepOtp.tsx @@ -11,6 +11,7 @@ import { extractErrorMessage } from '@/lib/func' import { useReceiptStore } from '@/zustand/receiptStore' import { useBulkCart } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData' import { setRefreshToken, setToken } from '@/lib/api/func' +import { useSearchParams } from 'next/navigation' type Props = { @@ -19,13 +20,21 @@ type Props = { } const StepOtp = ({ phone, slug }: Props) => { - + const searchParams = useSearchParams() + const redirectUrl = searchParams.get('redirect') const { t } = useTranslation('auth') const { mutate: mutateOtpVerify, isPending } = useOtpVerify() const { items, clear } = useReceiptStore() const { mutate: mutateBulkCart, isPending: isBulkCartPending } = useBulkCart() + const getRedirectPath = () => { + if (redirectUrl) { + return decodeURIComponent(redirectUrl) + } + return `/${slug}` + } + const formik = useFormik({ initialValues: { phone: phone, @@ -56,17 +65,17 @@ const StepOtp = ({ phone, slug }: Props) => { mutateBulkCart({ items: bulkCartItems }, { onSuccess: () => { clear() - window.location.href = `/${slug}` + window.location.href = getRedirectPath() }, onError: (error) => { toast(extractErrorMessage(error), 'error') } }) } else { - window.location.href = `/${slug}` + window.location.href = getRedirectPath() } } else { - window.location.href = `/${slug}` + window.location.href = getRedirectPath() }