add Cart model + add store fot save all methods
This commit is contained in:
@@ -10,13 +10,9 @@ import { useCart } from '../hook/useCart';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useGetCartItems } from '../hooks/useCartData';
|
||||
import { useCartStore } from '../store/Store';
|
||||
|
||||
interface CartSummaryProps {
|
||||
description?: string;
|
||||
onDescriptionChange?: (value: string) => void;
|
||||
}
|
||||
|
||||
const CartSummary = ({ description = '', onDescriptionChange }: CartSummaryProps) => {
|
||||
const CartSummary = () => {
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
@@ -27,6 +23,7 @@ const CartSummary = ({ description = '', onDescriptionChange }: CartSummaryProps
|
||||
const { items } = useCart();
|
||||
const { data: cartData } = useGetCartItems(isSuccess);
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
const { description, setDescription } = useCartStore();
|
||||
|
||||
const cartFoods = React.useMemo(() => {
|
||||
if (!foods.length) return [];
|
||||
@@ -72,7 +69,7 @@ const CartSummary = ({ description = '', onDescriptionChange }: CartSummaryProps
|
||||
id='description'
|
||||
name='description'
|
||||
value={description}
|
||||
onChange={(e) => onDescriptionChange?.(e.target.value)}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
></textarea>
|
||||
<span className='absolute top-4 right-2 px-2 bg-background text-foreground text-xs'></span>
|
||||
</div>
|
||||
|
||||
@@ -158,3 +158,9 @@ export const useGetCartItems = (enabled = true) => {
|
||||
enabled,
|
||||
});
|
||||
};
|
||||
|
||||
export const useSaveAllMethod = () => {
|
||||
return useMutation({
|
||||
mutationFn: api.saveAllMethod,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -13,7 +13,6 @@ const CartIndex = () => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
const router = useRouter();
|
||||
const { clearCart } = useCart();
|
||||
const [description, setDescription] = React.useState('');
|
||||
const [showClearConfirm, setShowClearConfirm] = React.useState(false);
|
||||
|
||||
const handleClearCart = (e: React.MouseEvent) => {
|
||||
@@ -49,7 +48,7 @@ const CartIndex = () => {
|
||||
|
||||
<div className='flex overflow-y-auto noscrollbar flex-col h-full pt-4 gap-4 pb-24' dir='rtl'>
|
||||
<CartItemsList />
|
||||
<CartSummary description={description} onDescriptionChange={setDescription} />
|
||||
<CartSummary />
|
||||
</div>
|
||||
|
||||
<div className={showClearConfirm ? 'fixed inset-0 z-1001' : 'pointer-events-none fixed inset-0 z-1001'}>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { api } from "@/config/axios";
|
||||
import { BulkCartItem, CartResponse } from "../types/Types";
|
||||
import { BulkCartItem, CartResponse, SaveAllMethod } from "../types/Types";
|
||||
|
||||
export const bulkCart = async (params: BulkCartItem) => {
|
||||
const { data } = await api.post("/public/cart/items/bulk", params);
|
||||
@@ -30,3 +30,8 @@ export const getCartSummary = async () => {
|
||||
const { data } = await api.get("/public/cart/summary");
|
||||
return data;
|
||||
};
|
||||
|
||||
export const saveAllMethod = async (params: SaveAllMethod) => {
|
||||
const { data } = await api.patch("/public/cart/all", params);
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { create } from "zustand";
|
||||
import { createJSONStorage, persist } from "zustand/middleware";
|
||||
import { CartStoreType, SaveAllMethod } from "../types/Types";
|
||||
|
||||
export const useCartStore = create<CartStoreType>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
description: "",
|
||||
setDescription: (value) => set({ description: value }),
|
||||
deliveryMethodId: null,
|
||||
setDeliveryMethodId: (value) => set({ deliveryMethodId: value }),
|
||||
addressId: null,
|
||||
setAddressId: (value) => set({ addressId: value }),
|
||||
paymentMethodId: null,
|
||||
setPaymentMethodId: (value) => set({ paymentMethodId: value }),
|
||||
carAddress: null,
|
||||
setCarAddress: (value) => set({ carAddress: value }),
|
||||
reset: () =>
|
||||
set({
|
||||
description: "",
|
||||
deliveryMethodId: null,
|
||||
addressId: null,
|
||||
paymentMethodId: null,
|
||||
carAddress: null,
|
||||
}),
|
||||
getSaveAllMethodData: (): SaveAllMethod | null => {
|
||||
const state = get();
|
||||
if (!state.deliveryMethodId || !state.paymentMethodId) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
description: state.description,
|
||||
deliveryMethodId: state.deliveryMethodId,
|
||||
...(state.addressId && { addressId: state.addressId }),
|
||||
paymentMethodId: state.paymentMethodId,
|
||||
...(state.carAddress && { carAddress: state.carAddress }),
|
||||
};
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "cart-storage",
|
||||
storage: createJSONStorage(() => localStorage),
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -85,3 +85,40 @@ export interface CartFood {
|
||||
}
|
||||
|
||||
export type CartResponse = BaseResponse<CartData>;
|
||||
|
||||
export type SaveAllMethod = {
|
||||
description: string;
|
||||
deliveryMethodId: string;
|
||||
addressId?: string;
|
||||
paymentMethodId: string;
|
||||
carAddress?: {
|
||||
carModel: string;
|
||||
carColor: string;
|
||||
plateNumber: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type CartStoreType = {
|
||||
description: string;
|
||||
setDescription: (value: string) => void;
|
||||
deliveryMethodId: string | null;
|
||||
setDeliveryMethodId: (value: string | null) => void;
|
||||
addressId: string | null;
|
||||
setAddressId: (value: string | null) => void;
|
||||
paymentMethodId: string | null;
|
||||
setPaymentMethodId: (value: string | null) => void;
|
||||
carAddress: {
|
||||
carModel: string;
|
||||
carColor: string;
|
||||
plateNumber: string;
|
||||
} | null;
|
||||
setCarAddress: (
|
||||
value: {
|
||||
carModel: string;
|
||||
carColor: string;
|
||||
plateNumber: string;
|
||||
} | null
|
||||
) => void;
|
||||
reset: () => void;
|
||||
getSaveAllMethodData: () => SaveAllMethod | null;
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@ import Link from 'next/link';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSetAddressCart } from '../../hooks/useOrderData';
|
||||
import { useCheckoutStore } from '../../store/Store';
|
||||
import useToggle from '@/hooks/helpers/useToggle';
|
||||
import { AddressSelectionModal } from './AddressSelectionModal';
|
||||
@@ -19,7 +18,6 @@ const formatAddress = (address: Address) => {
|
||||
|
||||
export const AddressSection = () => {
|
||||
|
||||
const { mutate: setAddressCart } = useSetAddressCart();
|
||||
const { setIsSelectedAddress, selectedAddressId, setSelectedAddressId, isSelectedShipment } = useCheckoutStore();
|
||||
const params = useParams<{ name: string; id: string }>();
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
@@ -35,24 +33,16 @@ export const AddressSection = () => {
|
||||
const defaultAddress = addresses.find(addr => addr.isDefault);
|
||||
const addressToSet = defaultAddress || addresses.filter(addr => !addr.isDefault)[0];
|
||||
if (addressToSet) {
|
||||
setAddressCart(addressToSet.id, {
|
||||
onSuccess: () => {
|
||||
setIsSelectedAddress(true);
|
||||
setSelectedAddressId(addressToSet.id);
|
||||
},
|
||||
});
|
||||
setIsSelectedAddress(true);
|
||||
setSelectedAddressId(addressToSet.id);
|
||||
}
|
||||
}
|
||||
}, [isLoading, addresses, setAddressCart, setIsSelectedAddress, selectedAddressId, setSelectedAddressId, isSelectedShipment]);
|
||||
}, [isLoading, addresses, setIsSelectedAddress, selectedAddressId, setSelectedAddressId, isSelectedShipment]);
|
||||
|
||||
const handleSelectAddress = (addressId: string) => {
|
||||
setAddressCart(addressId, {
|
||||
onSuccess: () => {
|
||||
setIsSelectedAddress(true);
|
||||
setSelectedAddressId(addressId);
|
||||
setModalVisible(false);
|
||||
},
|
||||
});
|
||||
setIsSelectedAddress(true);
|
||||
setSelectedAddressId(addressId);
|
||||
setModalVisible(false);
|
||||
};
|
||||
|
||||
// پیدا کردن آدرس انتخاب شده یا آدرس پیشفرض یا اولین آدرس غیر پیشفرض
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
'use client';
|
||||
|
||||
import InputField from '@/components/input/InputField';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCheckoutStore } from '../../store/Store';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
export const CarAddressSection = () => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
const { carAddress, setCarAddress } = useCheckoutStore();
|
||||
|
||||
const handleCarModelChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setCarAddress({
|
||||
carModel: e.target.value,
|
||||
carColor: carAddress?.carColor || '',
|
||||
plateNumber: carAddress?.plateNumber || '',
|
||||
});
|
||||
}, [carAddress, setCarAddress]);
|
||||
|
||||
const handleCarColorChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setCarAddress({
|
||||
carModel: carAddress?.carModel || '',
|
||||
carColor: e.target.value,
|
||||
plateNumber: carAddress?.plateNumber || '',
|
||||
});
|
||||
}, [carAddress, setCarAddress]);
|
||||
|
||||
const handlePlateNumberChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setCarAddress({
|
||||
carModel: carAddress?.carModel || '',
|
||||
carColor: carAddress?.carColor || '',
|
||||
plateNumber: e.target.value,
|
||||
});
|
||||
}, [carAddress, setCarAddress]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!carAddress) {
|
||||
setCarAddress({
|
||||
carModel: '',
|
||||
carColor: '',
|
||||
plateNumber: '',
|
||||
});
|
||||
}
|
||||
}, [carAddress, setCarAddress]);
|
||||
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<h3 className="text-sm2 font-medium leading-5 mb-4">
|
||||
اطلاعات خودرو
|
||||
</h3>
|
||||
<div className="flex flex-col gap-4">
|
||||
<InputField
|
||||
htmlFor="carModel"
|
||||
labelText="مدل خودرو"
|
||||
placeholder="مثال: پژو 206"
|
||||
value={carAddress?.carModel || ''}
|
||||
onChange={handleCarModelChange}
|
||||
className="bg-inherit"
|
||||
/>
|
||||
<InputField
|
||||
htmlFor="carColor"
|
||||
labelText="رنگ خودرو"
|
||||
placeholder="مثال: سفید"
|
||||
value={carAddress?.carColor || ''}
|
||||
onChange={handleCarColorChange}
|
||||
className="bg-inherit"
|
||||
/>
|
||||
<InputField
|
||||
htmlFor="plateNumber"
|
||||
labelText="شماره پلاک"
|
||||
placeholder="مثال: 12ب34567"
|
||||
value={carAddress?.plateNumber || ''}
|
||||
onChange={handlePlateNumberChange}
|
||||
className="bg-inherit"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -4,7 +4,7 @@ import { Card, Icon, Wallet2 } from 'iconsax-react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
|
||||
import { useGetPaymentMethod, useSetPaymentMethod } from '../../hooks/useOrderData';
|
||||
import { useGetPaymentMethod } from '../../hooks/useOrderData';
|
||||
import { useCheckoutStore } from '../../store/Store';
|
||||
|
||||
type PaymentSectionProps = {
|
||||
@@ -28,7 +28,6 @@ export const PaymentSection = ({ paymentType, onPaymentTypeChange }: PaymentSect
|
||||
const { t: tOrderDetail } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
const { t: tOrders } = useTranslation('orders');
|
||||
const { data: paymentMethod } = useGetPaymentMethod();
|
||||
const { mutate: setPaymentMethod } = useSetPaymentMethod();
|
||||
const { setIsSelectedPayment } = useCheckoutStore();
|
||||
|
||||
const getPaymentMethodTranslation = useCallback((method: string, fallbackTitle: string) => {
|
||||
@@ -59,11 +58,7 @@ export const PaymentSection = ({ paymentType, onPaymentTypeChange }: PaymentSect
|
||||
value={paymentType}
|
||||
onValueChange={(value) => {
|
||||
onPaymentTypeChange(value);
|
||||
setPaymentMethod(value, {
|
||||
onSuccess: () => {
|
||||
setIsSelectedPayment(true);
|
||||
},
|
||||
});
|
||||
setIsSelectedPayment(true);
|
||||
}}
|
||||
className='flex flex-col gap-6 mt-6'
|
||||
>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import Combobox from '@/components/combobox/Combobox';
|
||||
import { Box } from 'iconsax-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetShipmentMethod, useSetDeliveryMethod } from '../../hooks/useOrderData';
|
||||
import { useGetShipmentMethod } from '../../hooks/useOrderData';
|
||||
import { DeliveryMethod } from '../../types/Types';
|
||||
import { useCheckoutStore } from '../../store/Store';
|
||||
|
||||
@@ -17,7 +17,6 @@ export const ShippingSection = ({ deliveryType, onDeliveryTypeChange }: Shipping
|
||||
const { t: tOrderDetail } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
const { t: tOrders } = useTranslation('orders');
|
||||
const { data: shipmentMethod } = useGetShipmentMethod();
|
||||
const { mutate: setDeliveryMethod } = useSetDeliveryMethod();
|
||||
const { setIsSelectedShipment } = useCheckoutStore();
|
||||
|
||||
const getDeliveryMethodTranslation = (method: string) => {
|
||||
@@ -50,13 +49,7 @@ export const ShippingSection = ({ deliveryType, onDeliveryTypeChange }: Shipping
|
||||
const selectedOption = options[i];
|
||||
if (selectedOption) {
|
||||
onDeliveryTypeChange(selectedOption.id);
|
||||
setDeliveryMethod(selectedOption.id, {
|
||||
onSuccess: () => {
|
||||
setTimeout(() => {
|
||||
setIsSelectedShipment(true);
|
||||
}, 200);
|
||||
},
|
||||
});
|
||||
setIsSelectedShipment(true);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -6,14 +6,15 @@ import { ChevronLeft } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCheckoutStore } from '../../store/Store';
|
||||
import { toast } from '@/components/Toast';
|
||||
import { useConfirmOrder, useCreateOrder } from '../../hooks/useOrderData';
|
||||
import { useCreateOrder } from '../../hooks/useOrderData';
|
||||
import { extractErrorMessage } from '@/lib/func';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useGetCartItems } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData';
|
||||
import { useGetCartItems, useSaveAllMethod } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useGetShipmentMethod } from '../../hooks/useOrderData';
|
||||
import CartItemsList from '@/app/[name]/(Dialogs)/cart/components/CartItemsList';
|
||||
import { useCartStore } from '@/app/[name]/(Dialogs)/cart/store/Store';
|
||||
|
||||
type SummarySectionProps = {
|
||||
cartModal: boolean;
|
||||
@@ -24,9 +25,10 @@ type SummarySectionProps = {
|
||||
export const SummarySection = ({ cartModal, onToggleCartModal, deliveryType }: SummarySectionProps) => {
|
||||
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
const { isSelectedAddress, isSelectedShipment, isSelectedPayment } = useCheckoutStore();
|
||||
const { isSelectedAddress, isSelectedShipment, isSelectedPayment, deliveryType: storeDeliveryType, paymentType, selectedAddressId, tableNumber, carAddress } = useCheckoutStore();
|
||||
const { description } = useCartStore();
|
||||
const { mutate: createOrder } = useCreateOrder();
|
||||
const { mutate: confirmOrder } = useConfirmOrder();
|
||||
const { mutate: saveAllMethod } = useSaveAllMethod()
|
||||
const params = useParams();
|
||||
const name = params.name as string;
|
||||
const { isSuccess } = useGetProfile();
|
||||
@@ -42,6 +44,10 @@ export const SummarySection = ({ cartModal, onToggleCartModal, deliveryType }: S
|
||||
return selectedDeliveryMethod?.method === 'deliveryCourier';
|
||||
}, [selectedDeliveryMethod]);
|
||||
|
||||
const isDeliveryCar = useMemo(() => {
|
||||
return selectedDeliveryMethod?.method === 'deliveryCar';
|
||||
}, [selectedDeliveryMethod]);
|
||||
|
||||
const formatPrice = useCallback(
|
||||
(value: number) => value.toLocaleString('fa-IR'),
|
||||
[]
|
||||
@@ -67,15 +73,67 @@ export const SummarySection = ({ cartModal, onToggleCartModal, deliveryType }: S
|
||||
return;
|
||||
}
|
||||
|
||||
createOrder(undefined, {
|
||||
onSuccess: (data) => {
|
||||
if (data?.data?.paymentUrl) {
|
||||
window.location.href = data?.data?.paymentUrl;
|
||||
toast('در حال ریدایرکت به صفحه پرداخت...', 'success');
|
||||
} else {
|
||||
window.location.href = `/${name}/verify/${data?.data?.order?.id}`;
|
||||
toast('سفارش با موفقیت ثبت شد', 'success');
|
||||
if (isDeliveryCar) {
|
||||
if (!carAddress || !carAddress.carModel || !carAddress.carColor || !carAddress.plateNumber) {
|
||||
toast('لطفا اطلاعات خودرو را تکمیل کنید', 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!storeDeliveryType || storeDeliveryType === '0' || !paymentType || paymentType === '0') {
|
||||
toast('لطفا تمام اطلاعات را تکمیل کنید', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDeliveryCar && !selectedAddressId) {
|
||||
toast('لطفا آدرس را انتخاب کنید', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const saveAllMethodData = {
|
||||
description: description || '',
|
||||
deliveryMethodId: storeDeliveryType,
|
||||
paymentMethodId: paymentType,
|
||||
...(selectedAddressId && !isDeliveryCar && { addressId: selectedAddressId }),
|
||||
...(carAddress && { carAddress }),
|
||||
};
|
||||
|
||||
saveAllMethod(saveAllMethodData, {
|
||||
onSuccess: () => {
|
||||
const orderData: {
|
||||
deliveryMethodId?: string;
|
||||
paymentMethodId?: string;
|
||||
addressId?: string;
|
||||
tableNumber?: number;
|
||||
} = {};
|
||||
|
||||
if (storeDeliveryType && storeDeliveryType !== '0') {
|
||||
orderData.deliveryMethodId = storeDeliveryType;
|
||||
}
|
||||
if (paymentType && paymentType !== '0') {
|
||||
orderData.paymentMethodId = paymentType;
|
||||
}
|
||||
if (selectedAddressId && !isDeliveryCar) {
|
||||
orderData.addressId = selectedAddressId;
|
||||
}
|
||||
if (tableNumber > 0) {
|
||||
orderData.tableNumber = tableNumber;
|
||||
}
|
||||
|
||||
createOrder(orderData, {
|
||||
onSuccess: (data) => {
|
||||
if (data?.data?.paymentUrl) {
|
||||
window.location.href = data?.data?.paymentUrl;
|
||||
toast('در حال ریدایرکت به صفحه پرداخت...', 'success');
|
||||
} else {
|
||||
window.location.href = `/${name}/verify/${data?.data?.order?.id}`;
|
||||
toast('سفارش با موفقیت ثبت شد', 'success');
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(extractErrorMessage(error), 'error');
|
||||
}
|
||||
});
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(extractErrorMessage(error), 'error');
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
import { MinusIcon, PlusIcon } from 'lucide-react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetTableNumber } from '../../hooks/useOrderData';
|
||||
|
||||
type TableSectionProps = {
|
||||
tableNumber: number;
|
||||
@@ -14,17 +12,6 @@ type TableSectionProps = {
|
||||
|
||||
export const TableSection = ({ tableNumber, onIncrement, onDecrement }: TableSectionProps) => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
const { mutate: setTableNumber } = useSetTableNumber();
|
||||
|
||||
useEffect(() => {
|
||||
if (tableNumber === 0) return;
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
setTableNumber(tableNumber);
|
||||
}, 1000);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [tableNumber, setTableNumber]);
|
||||
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4 py-2">
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import useToggle from '@/hooks/helpers/useToggle';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import { AddressSection } from './components/AddressSection';
|
||||
import { CarAddressSection } from './components/CarAddressSection';
|
||||
import { CheckoutHeader } from './components/CheckoutHeader';
|
||||
import { CouponSection } from './components/CouponSection';
|
||||
import { PaymentSection } from './components/PaymentSection';
|
||||
import { ShippingSection } from './components/ShippingSection';
|
||||
import { SummarySection } from './components/SummarySection';
|
||||
import { TableSection } from './components/TableSection';
|
||||
import { useGetShipmentMethod, useSetAddressCart, useSetPaymentMethod } from '../hooks/useOrderData';
|
||||
import { useGetShipmentMethod } from '../hooks/useOrderData';
|
||||
import { useGetCartItems } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useCheckoutStore } from '../store/Store';
|
||||
@@ -17,28 +18,34 @@ import { useCheckoutStore } from '../store/Store';
|
||||
function OrderDetailInex() {
|
||||
const { isSuccess } = useGetProfile();
|
||||
const { data: cartItems } = useGetCartItems(isSuccess);
|
||||
const [deliveryType, setDeliveryType] = React.useState<string>('0');
|
||||
const [paymentType, setPaymentType] = React.useState<string>('0');
|
||||
const { state: cartModal, toggle: toggleCartModal } = useToggle();
|
||||
const { data: shipmentMethod } = useGetShipmentMethod();
|
||||
const {
|
||||
deliveryType,
|
||||
setDeliveryType,
|
||||
paymentType,
|
||||
setPaymentType,
|
||||
tableNumber,
|
||||
setTableNumber,
|
||||
setSelectedAddressId,
|
||||
setIsSelectedAddress,
|
||||
setIsSelectedPayment,
|
||||
setIsSelectedShipment,
|
||||
} = useCheckoutStore();
|
||||
const [couponType, setCouponType] = React.useState<string>('0');
|
||||
const [couponCode, setCouponCode] = React.useState<string>('');
|
||||
const [couponCodeError, setCouponCodeError] = React.useState<string>('');
|
||||
const [tableNumber, setTableNumber] = useState(0);
|
||||
const { state: cartModal, toggle: toggleCartModal } = useToggle();
|
||||
const { data: shipmentMethod } = useGetShipmentMethod();
|
||||
const { mutate: setAddressCart } = useSetAddressCart();
|
||||
const { mutate: setPaymentMethod } = useSetPaymentMethod();
|
||||
const { setSelectedAddressId, setIsSelectedAddress, setIsSelectedPayment } = useCheckoutStore();
|
||||
|
||||
const incrementTableNumber = () => setTableNumber((prev) => prev + 1);
|
||||
const decrementTableNumber = () => setTableNumber((prev) => prev - 1);
|
||||
const incrementTableNumber = () => setTableNumber(tableNumber + 1);
|
||||
const decrementTableNumber = () => setTableNumber(Math.max(0, tableNumber - 1));
|
||||
|
||||
const changeDeliveryType = useCallback((id: string) => {
|
||||
setDeliveryType(id);
|
||||
}, []);
|
||||
}, [setDeliveryType]);
|
||||
|
||||
const changePaymentType = useCallback((id: string) => {
|
||||
setPaymentType(id);
|
||||
}, []);
|
||||
}, [setPaymentType]);
|
||||
|
||||
const changeCouponType = useCallback((id: string) => {
|
||||
setCouponCode('');
|
||||
@@ -53,31 +60,24 @@ function OrderDetailInex() {
|
||||
useEffect(() => {
|
||||
if (cartItems?.data?.deliveryMethodId) {
|
||||
setDeliveryType(cartItems.data.deliveryMethodId);
|
||||
setIsSelectedShipment(true);
|
||||
}
|
||||
}, [cartItems?.data?.deliveryMethodId]);
|
||||
}, [cartItems?.data?.deliveryMethodId, setDeliveryType, setIsSelectedShipment]);
|
||||
|
||||
useEffect(() => {
|
||||
if (cartItems?.data?.paymentMethodId) {
|
||||
setPaymentType(cartItems.data.paymentMethodId);
|
||||
setPaymentMethod(cartItems.data.paymentMethodId, {
|
||||
onSuccess: () => {
|
||||
setIsSelectedPayment(true);
|
||||
},
|
||||
});
|
||||
setIsSelectedPayment(true);
|
||||
}
|
||||
}, [cartItems?.data?.paymentMethodId, setPaymentMethod, setIsSelectedPayment]);
|
||||
}, [cartItems?.data?.paymentMethodId, setPaymentType, setIsSelectedPayment]);
|
||||
|
||||
useEffect(() => {
|
||||
if (cartItems?.data?.addressId) {
|
||||
const addressId = cartItems.data.addressId;
|
||||
setAddressCart(addressId, {
|
||||
onSuccess: () => {
|
||||
setIsSelectedAddress(true);
|
||||
setSelectedAddressId(addressId ?? null);
|
||||
},
|
||||
});
|
||||
setIsSelectedAddress(true);
|
||||
setSelectedAddressId(addressId ?? null);
|
||||
}
|
||||
}, [cartItems?.data?.addressId, setAddressCart, setIsSelectedAddress, setSelectedAddressId]);
|
||||
}, [cartItems?.data?.addressId, setIsSelectedAddress, setSelectedAddressId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (cartItems?.data?.coupon?.couponCode && cartItems.data.couponDiscount > 0) {
|
||||
@@ -104,6 +104,10 @@ function OrderDetailInex() {
|
||||
onDeliveryTypeChange={changeDeliveryType}
|
||||
/>
|
||||
|
||||
{selectedDeliveryMethod?.method === 'deliveryCar' && (
|
||||
<CarAddressSection />
|
||||
)}
|
||||
|
||||
{shouldShowAddress && (
|
||||
<AddressSection />
|
||||
)}
|
||||
|
||||
@@ -39,8 +39,16 @@ export const setPaymentMethod = async (id: string) => {
|
||||
return data;
|
||||
};
|
||||
|
||||
export const createOrder = async (): Promise<CreateOrderResponse> => {
|
||||
const { data } = await api.post<CreateOrderResponse>("/public/checkout");
|
||||
export const createOrder = async (orderData?: {
|
||||
deliveryMethodId?: string;
|
||||
paymentMethodId?: string;
|
||||
addressId?: string;
|
||||
tableNumber?: number;
|
||||
}): Promise<CreateOrderResponse> => {
|
||||
const { data } = await api.post<CreateOrderResponse>(
|
||||
"/public/checkout",
|
||||
orderData
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,13 +1,30 @@
|
||||
import { create } from "zustand";
|
||||
import { createJSONStorage, persist } from "zustand/middleware";
|
||||
import { CheckoutStoreType } from "../types/Types";
|
||||
|
||||
export const useCheckoutStore = create<CheckoutStoreType>((set) => ({
|
||||
isSelectedAddress: false,
|
||||
setIsSelectedAddress: (value) => set({ isSelectedAddress: value }),
|
||||
selectedAddressId: null,
|
||||
setSelectedAddressId: (value) => set({ selectedAddressId: value }),
|
||||
isSelectedPayment: false,
|
||||
setIsSelectedPayment: (value) => set({ isSelectedPayment: value }),
|
||||
isSelectedShipment: false,
|
||||
setIsSelectedShipment: (value) => set({ isSelectedShipment: value }),
|
||||
}));
|
||||
export const useCheckoutStore = create<CheckoutStoreType>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
isSelectedAddress: false,
|
||||
setIsSelectedAddress: (value) => set({ isSelectedAddress: value }),
|
||||
selectedAddressId: null,
|
||||
setSelectedAddressId: (value) => set({ selectedAddressId: value }),
|
||||
isSelectedPayment: false,
|
||||
setIsSelectedPayment: (value) => set({ isSelectedPayment: value }),
|
||||
isSelectedShipment: false,
|
||||
setIsSelectedShipment: (value) => set({ isSelectedShipment: value }),
|
||||
deliveryType: "0",
|
||||
setDeliveryType: (value) => set({ deliveryType: value }),
|
||||
paymentType: "0",
|
||||
setPaymentType: (value) => set({ paymentType: value }),
|
||||
tableNumber: 0,
|
||||
setTableNumber: (value) => set({ tableNumber: value }),
|
||||
carAddress: null,
|
||||
setCarAddress: (value) => set({ carAddress: value }),
|
||||
}),
|
||||
{
|
||||
name: "checkout-storage",
|
||||
storage: createJSONStorage(() => localStorage),
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -127,6 +127,24 @@ export type CheckoutStoreType = {
|
||||
setIsSelectedPayment: (value: boolean) => void;
|
||||
isSelectedShipment: boolean;
|
||||
setIsSelectedShipment: (value: boolean) => void;
|
||||
deliveryType: string;
|
||||
setDeliveryType: (value: string) => void;
|
||||
paymentType: string;
|
||||
setPaymentType: (value: string) => void;
|
||||
tableNumber: number;
|
||||
setTableNumber: (value: number) => void;
|
||||
carAddress: {
|
||||
carModel: string;
|
||||
carColor: string;
|
||||
plateNumber: string;
|
||||
} | null;
|
||||
setCarAddress: (
|
||||
value: {
|
||||
carModel: string;
|
||||
carColor: string;
|
||||
plateNumber: string;
|
||||
} | null
|
||||
) => void;
|
||||
};
|
||||
|
||||
export interface OrderUser {
|
||||
|
||||
Reference in New Issue
Block a user