checkout
This commit is contained in:
@@ -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' : ''}
|
||||
|
||||
@@ -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
|
||||
<span className='font-medium '>{t("SectionSummary.TotalLabel")}</span>
|
||||
<span className='font-bold place-self-end'>110,000 T</span>
|
||||
</div>
|
||||
<Button className='mt-6'>
|
||||
<Button onClick={handleSubmit} className='mt-6'>
|
||||
{t("ButtonSubmit")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -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<string>('0');
|
||||
@@ -18,6 +19,7 @@ function OrderDetailInex() {
|
||||
const [couponCodeError, setCouponCodeError] = React.useState<string>('');
|
||||
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 (
|
||||
<div className='h-full bg-inherit flex flex-col gap-5'>
|
||||
<CheckoutHeader />
|
||||
@@ -49,7 +61,7 @@ function OrderDetailInex() {
|
||||
onDeliveryTypeChange={changeDeliveryType}
|
||||
/>
|
||||
|
||||
{deliveryType === '0' && (
|
||||
{shouldShowAddress && (
|
||||
<AddressSection />
|
||||
)}
|
||||
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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<LoginVerifyOTPType>({
|
||||
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()
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user