Create order
This commit is contained in:
@@ -84,9 +84,14 @@ const Input: FC<Props> = (props: Props) => {
|
||||
|
||||
return (
|
||||
<div className='w-full'>
|
||||
<label className='text-sm'>
|
||||
{props.label}
|
||||
</label>
|
||||
{props.label && (
|
||||
<div className='flex items-center gap-1'>
|
||||
<label className='text-sm'>{props.label}</label>
|
||||
{props.isNotRequired && (
|
||||
<span className='text-xs text-description'>(اختیاری)</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='w-full relative mt-1'>
|
||||
<input {...props} onChange={(e) => {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { clx } from '../helpers/utils'
|
||||
type Props = {
|
||||
label?: string,
|
||||
error_text?: string
|
||||
isNotRequired?: boolean
|
||||
} & InputHTMLAttributes<HTMLTextAreaElement>
|
||||
|
||||
const Textarea: FC<Props> = (props: Props) => {
|
||||
@@ -12,8 +13,11 @@ const Textarea: FC<Props> = (props: Props) => {
|
||||
<div className='w-full relative'>
|
||||
{
|
||||
props.label &&
|
||||
<div className='text-sm' >
|
||||
{props.label}
|
||||
<div className='flex items-center gap-1'>
|
||||
<div className='text-sm'>{props.label}</div>
|
||||
{props.isNotRequired && (
|
||||
<span className='text-xs text-description'>(اختیاری)</span>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as api from "../service/UsersService";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import type { GetUsersParams } from "../types/Types";
|
||||
import type { CreateUserAddressType, GetUsersParams } from "../types/Types";
|
||||
|
||||
export const useGetUsers = (params?: GetUsersParams) => {
|
||||
return useQuery({
|
||||
@@ -26,6 +26,16 @@ export const useCreateUser = () => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useCreateUserAddress = () => {
|
||||
return useMutation({
|
||||
mutationFn: ({
|
||||
userId,
|
||||
...params
|
||||
}: CreateUserAddressType & { userId: string }) =>
|
||||
api.createUserAddress(userId, params),
|
||||
});
|
||||
};
|
||||
|
||||
export const useImportUsersFromExcel = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import axios from "@/config/axios";
|
||||
import type {
|
||||
CreateUserAddressResponse,
|
||||
CreateUserAddressType,
|
||||
CreateUserResponse,
|
||||
CreateUserType,
|
||||
GetCustomersResponse,
|
||||
@@ -28,6 +30,17 @@ export const createUser = async (params: CreateUserType) => {
|
||||
return data;
|
||||
};
|
||||
|
||||
export const createUserAddress = async (
|
||||
userId: string,
|
||||
params: CreateUserAddressType,
|
||||
) => {
|
||||
const { data } = await axios.post<CreateUserAddressResponse>(
|
||||
`/admin/users/${userId}/addresses`,
|
||||
params,
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const importUsersFromExcel = async (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
|
||||
@@ -103,4 +103,25 @@ export type CreateUserType = {
|
||||
lastName: string;
|
||||
};
|
||||
|
||||
export type CreateUserResponse = IResponse<User>;
|
||||
export type CreateUserResult = {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
user: User;
|
||||
orderCount: number;
|
||||
totalOrderAmount: number;
|
||||
};
|
||||
|
||||
export type CreateUserResponse = IResponse<CreateUserResult>;
|
||||
|
||||
export type CreateUserAddressType = {
|
||||
title: string;
|
||||
address: string;
|
||||
postalCode?: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
phone: string;
|
||||
isDefault: boolean;
|
||||
};
|
||||
|
||||
export type CreateUserAddressResponse = IResponse<UserSavedAddress>;
|
||||
|
||||
@@ -31,6 +31,7 @@ const CreateOrder: FC = () => {
|
||||
applySavedAddress,
|
||||
selectManualAddress,
|
||||
handleAddressFieldChange,
|
||||
handleLocationSelect,
|
||||
} = useCreateOrderForm()
|
||||
|
||||
return (
|
||||
@@ -78,6 +79,7 @@ const CreateOrder: FC = () => {
|
||||
onSelectSavedAddress={applySavedAddress}
|
||||
onSelectManualAddress={selectManualAddress}
|
||||
onAddressFieldChange={handleAddressFieldChange}
|
||||
onLocationSelect={handleLocationSelect}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ const CreateOrderAddressSelector: FC<CreateOrderAddressSelectorProps> = ({
|
||||
<div className='grid grid-cols-1 sm:grid-cols-2 gap-3'>
|
||||
{addresses.map((address) => {
|
||||
const isSelected = selectedAddressId === address.id
|
||||
const location = [address.province, address.city].filter(Boolean).join('، ')
|
||||
|
||||
return (
|
||||
<button
|
||||
@@ -48,9 +47,6 @@ const CreateOrderAddressSelector: FC<CreateOrderAddressSelectorProps> = ({
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{location && (
|
||||
<div className='text-xs text-description mt-1'>{location}</div>
|
||||
)}
|
||||
<div className='text-xs mt-2 line-clamp-2'>{address.address}</div>
|
||||
</button>
|
||||
)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { type FC } from 'react'
|
||||
import { type FC, useState } from 'react'
|
||||
import type { FormikProps } from 'formik'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/components/Input'
|
||||
import Textarea from '@/components/Textarea'
|
||||
import DefaulModal from '@/components/DefaulModal'
|
||||
import LocationInput from '@/pages/settings/components/LocationInput'
|
||||
import LocationPicker from '@/pages/settings/components/LocationPicker'
|
||||
import { formatPrice } from '@/helpers/func'
|
||||
import type { CreateOrderFormValues } from '../hooks/useCreateOrderForm'
|
||||
import type { RestaurantPaymentMethod, RestaurantShipmentMethod } from '../hooks/useCreateOrderForm'
|
||||
@@ -21,6 +24,7 @@ interface CreateOrderDeliverySectionProps {
|
||||
onSelectSavedAddress: (address: UserSavedAddress) => void
|
||||
onSelectManualAddress: () => void
|
||||
onAddressFieldChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void
|
||||
onLocationSelect: (lat: number, lng: number) => void
|
||||
}
|
||||
|
||||
const CreateOrderDeliverySection: FC<CreateOrderDeliverySectionProps> = ({
|
||||
@@ -35,8 +39,10 @@ const CreateOrderDeliverySection: FC<CreateOrderDeliverySectionProps> = ({
|
||||
onSelectSavedAddress,
|
||||
onSelectManualAddress,
|
||||
onAddressFieldChange,
|
||||
onLocationSelect,
|
||||
}) => {
|
||||
const { t } = useTranslation('global')
|
||||
const [isLocationModalOpen, setIsLocationModalOpen] = useState(false)
|
||||
|
||||
const getDeliveryLabel = (method: string) => {
|
||||
return t(`shipment.${method}`, {
|
||||
@@ -47,6 +53,14 @@ const CreateOrderDeliverySection: FC<CreateOrderDeliverySectionProps> = ({
|
||||
const isAddressReadOnly =
|
||||
selectedAddressId !== null && customerAddresses.length > 0
|
||||
|
||||
const handleMapLocationSelect = (lat: number, lng: number) => {
|
||||
onLocationSelect(lat, lng)
|
||||
setIsLocationModalOpen(false)
|
||||
}
|
||||
|
||||
const latitude = formik.values.userAddress.latitude
|
||||
const longitude = formik.values.userAddress.longitude
|
||||
|
||||
return (
|
||||
<div className='flex flex-col gap-8'>
|
||||
<div className='w-full bg-white rounded-4xl p-8'>
|
||||
@@ -109,7 +123,7 @@ const CreateOrderDeliverySection: FC<CreateOrderDeliverySectionProps> = ({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{(isDineIn || isCarDelivery) && (
|
||||
{isDineIn && (
|
||||
<div className='mt-8'>
|
||||
<Input
|
||||
label='شماره میز'
|
||||
@@ -135,57 +149,36 @@ const CreateOrderDeliverySection: FC<CreateOrderDeliverySectionProps> = ({
|
||||
|
||||
<div className='grid grid-cols-1 sm:grid-cols-2 gap-4 mt-6'>
|
||||
<Input
|
||||
label='نام گیرنده'
|
||||
name='userAddress.fullName'
|
||||
value={formik.values.userAddress.fullName}
|
||||
label='عنوان آدرس'
|
||||
name='userAddress.title'
|
||||
placeholder='مثال: منزل'
|
||||
value={formik.values.userAddress.title}
|
||||
onChange={onAddressFieldChange}
|
||||
readOnly={isAddressReadOnly}
|
||||
/>
|
||||
<Input
|
||||
label='شماره تماس گیرنده'
|
||||
label='شماره تماس'
|
||||
name='userAddress.phone'
|
||||
value={formik.values.userAddress.phone}
|
||||
onChange={onAddressFieldChange}
|
||||
readOnly={isAddressReadOnly}
|
||||
/>
|
||||
<Input
|
||||
label='استان'
|
||||
name='userAddress.province'
|
||||
value={formik.values.userAddress.province}
|
||||
onChange={onAddressFieldChange}
|
||||
readOnly={isAddressReadOnly}
|
||||
/>
|
||||
<Input
|
||||
label='شهر'
|
||||
name='userAddress.city'
|
||||
value={formik.values.userAddress.city}
|
||||
onChange={onAddressFieldChange}
|
||||
readOnly={isAddressReadOnly}
|
||||
/>
|
||||
<Input
|
||||
label='کد پستی'
|
||||
name='userAddress.postalCode'
|
||||
value={formik.values.userAddress.postalCode}
|
||||
onChange={onAddressFieldChange}
|
||||
readOnly={isAddressReadOnly}
|
||||
/>
|
||||
<Input
|
||||
label='عرض جغرافیایی'
|
||||
type='number'
|
||||
name='userAddress.latitude'
|
||||
value={formik.values.userAddress.latitude || ''}
|
||||
onChange={onAddressFieldChange}
|
||||
readOnly={isAddressReadOnly}
|
||||
isNotRequired
|
||||
/>
|
||||
<Input
|
||||
label='طول جغرافیایی'
|
||||
type='number'
|
||||
name='userAddress.longitude'
|
||||
value={formik.values.userAddress.longitude || ''}
|
||||
onChange={onAddressFieldChange}
|
||||
readOnly={isAddressReadOnly}
|
||||
isNotRequired
|
||||
</div>
|
||||
|
||||
<div className={isAddressReadOnly ? 'pointer-events-none opacity-60' : ''}>
|
||||
<LocationInput
|
||||
label='موقعیت روی نقشه'
|
||||
latitude={latitude || undefined}
|
||||
longitude={longitude || undefined}
|
||||
onClick={() => setIsLocationModalOpen(true)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -198,6 +191,28 @@ const CreateOrderDeliverySection: FC<CreateOrderDeliverySectionProps> = ({
|
||||
readOnly={isAddressReadOnly}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DefaulModal
|
||||
open={isLocationModalOpen}
|
||||
close={() => setIsLocationModalOpen(false)}
|
||||
isHeader={true}
|
||||
title_header='انتخاب موقعیت روی نقشه'
|
||||
width={800}
|
||||
>
|
||||
<div className='p-4'>
|
||||
<LocationPicker
|
||||
initialPosition={
|
||||
latitude && longitude
|
||||
? [latitude, longitude]
|
||||
: undefined
|
||||
}
|
||||
onLocationSelect={handleMapLocationSelect}
|
||||
/>
|
||||
<div className='mt-4 text-xs text-gray-600 text-center'>
|
||||
روی نقشه کلیک کنید تا موقعیت را انتخاب کنید
|
||||
</div>
|
||||
</div>
|
||||
</DefaulModal>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -243,6 +258,7 @@ const CreateOrderDeliverySection: FC<CreateOrderDeliverySectionProps> = ({
|
||||
placeholder='توضیحات اضافی برای سفارش...'
|
||||
value={formik.values.description}
|
||||
onChange={formik.handleChange}
|
||||
isNotRequired
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as Yup from 'yup'
|
||||
import { toast } from 'react-toastify'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useCreateOrder } from './useOrderData'
|
||||
import { useCreateUser } from '@/pages/customers/hooks/useUsersData'
|
||||
import { useCreateUser, useCreateUserAddress } from '@/pages/customers/hooks/useUsersData'
|
||||
import { useGetFoods } from '@/pages/food/hooks/useFoodData'
|
||||
import { useGetRestaurantShipmentMethods } from '@/pages/shipmentMethod/hooks/useShipmentMethodData'
|
||||
import { useGetRestaurantPaymentMethods } from '@/pages/paymentMethods/hooks/usePaymentMethodData'
|
||||
@@ -21,6 +21,7 @@ import type { RestaurantShipmentMethod } from '@/pages/shipmentMethod/types/Type
|
||||
import type { RestaurantPaymentMethod } from '@/pages/paymentMethods/types/Types'
|
||||
import type { UserSavedAddress, UserWithAddresses } from '@/pages/customers/types/Types'
|
||||
import { mapSavedAddressToOrderAddress } from '../utils/mapSavedAddress'
|
||||
import { mapFormAddressToCreateUserAddress } from '../utils/mapFormAddressToCreateUserAddress'
|
||||
import { Pages } from '@/config/Pages'
|
||||
import type { ErrorType } from '@/helpers/types'
|
||||
import { extractErrorMessage } from '@/config/func'
|
||||
@@ -40,10 +41,8 @@ export interface CreateOrderFormValues {
|
||||
}
|
||||
|
||||
const emptyUserAddress = (): CreateOrderUserAddress => ({
|
||||
fullName: '',
|
||||
title: '',
|
||||
phone: '',
|
||||
city: '',
|
||||
province: '',
|
||||
address: '',
|
||||
postalCode: '',
|
||||
latitude: 0,
|
||||
@@ -66,7 +65,10 @@ export const useCreateOrderForm = () => {
|
||||
const navigate = useNavigate()
|
||||
const { mutate: createOrder, isPending: isCreating } = useCreateOrder()
|
||||
const { mutateAsync: createUser, isPending: isCreatingUser } = useCreateUser()
|
||||
const { mutateAsync: createUserAddress, isPending: isCreatingAddress } =
|
||||
useCreateUserAddress()
|
||||
const [customerAddresses, setCustomerAddresses] = useState<UserSavedAddress[]>([])
|
||||
const [customerUserId, setCustomerUserId] = useState<string | null>(null)
|
||||
const [selectedAddressId, setSelectedAddressId] = useState<string | null>(null)
|
||||
const [isNewCustomer, setIsNewCustomer] = useState(false)
|
||||
|
||||
@@ -126,16 +128,14 @@ export const useCreateOrderForm = () => {
|
||||
|
||||
if (selectedDelivery?.method === DeliveryMethodEnum.DeliveryCourier) {
|
||||
const address = values.userAddress
|
||||
if (
|
||||
!address.fullName ||
|
||||
!address.phone ||
|
||||
!address.city ||
|
||||
!address.province ||
|
||||
!address.address
|
||||
) {
|
||||
if (!address.title || !address.phone || !address.address) {
|
||||
toast.error('لطفاً آدرس تحویل را کامل کنید')
|
||||
return
|
||||
}
|
||||
if (!address.latitude || !address.longitude) {
|
||||
toast.error('لطفاً موقعیت روی نقشه را انتخاب کنید')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedDelivery?.method === DeliveryMethodEnum.DeliveryCar) {
|
||||
@@ -146,11 +146,17 @@ export const useCreateOrderForm = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const submitOrder = () => {
|
||||
if (
|
||||
selectedDelivery?.method === DeliveryMethodEnum.DineIn &&
|
||||
!values.tableNumber.trim()
|
||||
) {
|
||||
toast.error('لطفاً شماره میز را وارد کنید')
|
||||
return
|
||||
}
|
||||
|
||||
const submitOrder = (userId: string, addressId?: string) => {
|
||||
const payload: CreateOrderType = {
|
||||
userPhone: values.userPhone,
|
||||
firstName: values.firstName,
|
||||
lastName: values.lastName,
|
||||
userId,
|
||||
items: values.items,
|
||||
deliveryMethodId: values.deliveryMethodId,
|
||||
paymentMethodId: values.paymentMethodId,
|
||||
@@ -160,16 +166,15 @@ export const useCreateOrderForm = () => {
|
||||
payload.description = values.description.trim()
|
||||
}
|
||||
|
||||
if (values.tableNumber.trim()) {
|
||||
if (
|
||||
selectedDelivery?.method === DeliveryMethodEnum.DineIn &&
|
||||
values.tableNumber.trim()
|
||||
) {
|
||||
payload.tableNumber = values.tableNumber.trim()
|
||||
}
|
||||
|
||||
if (selectedDelivery?.method === DeliveryMethodEnum.DeliveryCourier) {
|
||||
payload.userAddress = {
|
||||
...values.userAddress,
|
||||
latitude: Number(values.userAddress.latitude) || 0,
|
||||
longitude: Number(values.userAddress.longitude) || 0,
|
||||
}
|
||||
if (selectedDelivery?.method === DeliveryMethodEnum.DeliveryCourier && addressId) {
|
||||
payload.addressId = addressId
|
||||
}
|
||||
|
||||
if (selectedDelivery?.method === DeliveryMethodEnum.DeliveryCar) {
|
||||
@@ -192,20 +197,66 @@ export const useCreateOrderForm = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const registerNewCustomer = async () => {
|
||||
const registerNewCustomer = async (): Promise<string | null> => {
|
||||
if (!isNewCustomer) {
|
||||
submitOrder()
|
||||
return
|
||||
return customerUserId
|
||||
}
|
||||
|
||||
try {
|
||||
await createUser({
|
||||
const response = await createUser({
|
||||
phone: values.userPhone.trim(),
|
||||
firstName: values.firstName.trim(),
|
||||
lastName: values.lastName.trim(),
|
||||
})
|
||||
const userId = response.data.user.id
|
||||
setCustomerUserId(userId)
|
||||
setIsNewCustomer(false)
|
||||
submitOrder()
|
||||
return userId
|
||||
}
|
||||
|
||||
const resolveAddressId = async (userId: string): Promise<string | undefined> => {
|
||||
if (selectedDelivery?.method !== DeliveryMethodEnum.DeliveryCourier) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (selectedAddressId) {
|
||||
return selectedAddressId
|
||||
}
|
||||
|
||||
const response = await createUserAddress({
|
||||
userId,
|
||||
...mapFormAddressToCreateUserAddress(
|
||||
values.userAddress,
|
||||
customerAddresses.length === 0
|
||||
),
|
||||
})
|
||||
return response.data.id
|
||||
}
|
||||
|
||||
const submitFlow = async () => {
|
||||
try {
|
||||
const userId = await registerNewCustomer()
|
||||
if (!userId) {
|
||||
toast.error('کاربر انتخاب نشده است')
|
||||
return
|
||||
}
|
||||
|
||||
let addressId: string | undefined
|
||||
try {
|
||||
addressId = await resolveAddressId(userId)
|
||||
} catch (error) {
|
||||
toast.error(extractErrorMessage(error as ErrorType, 'خطا در ثبت آدرس'))
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
selectedDelivery?.method === DeliveryMethodEnum.DeliveryCourier &&
|
||||
!addressId
|
||||
) {
|
||||
toast.error('لطفاً آدرس تحویل را انتخاب کنید')
|
||||
return
|
||||
}
|
||||
|
||||
submitOrder(userId, addressId)
|
||||
} catch (error) {
|
||||
toast.error(extractErrorMessage(error as ErrorType, 'خطا در ثبت مشتری'))
|
||||
}
|
||||
@@ -216,42 +267,30 @@ export const useCreateOrderForm = () => {
|
||||
return
|
||||
}
|
||||
|
||||
await registerNewCustomer()
|
||||
await submitFlow()
|
||||
},
|
||||
})
|
||||
|
||||
const getCustomerFullName = useCallback(
|
||||
(firstName?: string, lastName?: string) =>
|
||||
[firstName ?? formik.values.firstName, lastName ?? formik.values.lastName]
|
||||
.filter(Boolean)
|
||||
.join(' '),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[formik.values.firstName, formik.values.lastName]
|
||||
)
|
||||
|
||||
const applySavedAddress = useCallback(
|
||||
(address: UserSavedAddress, fullName?: string) => {
|
||||
formik.setFieldValue(
|
||||
'userAddress',
|
||||
mapSavedAddressToOrderAddress(address, fullName ?? getCustomerFullName())
|
||||
)
|
||||
(address: UserSavedAddress) => {
|
||||
formik.setFieldValue('userAddress', mapSavedAddressToOrderAddress(address))
|
||||
setSelectedAddressId(address.id)
|
||||
},
|
||||
[formik, getCustomerFullName]
|
||||
[formik]
|
||||
)
|
||||
|
||||
const selectManualAddress = useCallback(() => {
|
||||
setSelectedAddressId(null)
|
||||
formik.setFieldValue('userAddress', {
|
||||
...emptyUserAddress(),
|
||||
fullName: getCustomerFullName(),
|
||||
phone: formik.values.userPhone,
|
||||
})
|
||||
}, [formik, getCustomerFullName])
|
||||
}, [formik])
|
||||
|
||||
const handleUserFound = useCallback(
|
||||
(user: UserWithAddresses) => {
|
||||
setIsNewCustomer(false)
|
||||
setCustomerUserId(user.id)
|
||||
const addresses = user.addresses ?? []
|
||||
setCustomerAddresses(addresses)
|
||||
|
||||
@@ -259,7 +298,6 @@ export const useCreateOrderForm = () => {
|
||||
setSelectedAddressId(null)
|
||||
formik.setFieldValue('userAddress', {
|
||||
...emptyUserAddress(),
|
||||
fullName: getCustomerFullName(user.firstName, user.lastName),
|
||||
phone: user.phone || formik.values.userPhone,
|
||||
})
|
||||
return
|
||||
@@ -267,22 +305,21 @@ export const useCreateOrderForm = () => {
|
||||
|
||||
const defaultAddress =
|
||||
addresses.find((address) => address.isDefault) ?? addresses[0]
|
||||
applySavedAddress(
|
||||
defaultAddress,
|
||||
[user.firstName, user.lastName].filter(Boolean).join(' ')
|
||||
)
|
||||
applySavedAddress(defaultAddress)
|
||||
},
|
||||
[applySavedAddress, formik, getCustomerFullName]
|
||||
[applySavedAddress, formik]
|
||||
)
|
||||
|
||||
const clearCustomerData = useCallback(() => {
|
||||
setIsNewCustomer(false)
|
||||
setCustomerUserId(null)
|
||||
setCustomerAddresses([])
|
||||
setSelectedAddressId(null)
|
||||
formik.setFieldValue('userAddress', emptyUserAddress())
|
||||
}, [formik])
|
||||
|
||||
const handleUserNotFound = useCallback(() => {
|
||||
setCustomerUserId(null)
|
||||
setCustomerAddresses([])
|
||||
setSelectedAddressId(null)
|
||||
formik.setFieldValue('userAddress', emptyUserAddress())
|
||||
@@ -397,6 +434,15 @@ export const useCreateOrderForm = () => {
|
||||
[formik]
|
||||
)
|
||||
|
||||
const handleLocationSelect = useCallback(
|
||||
(lat: number, lng: number) => {
|
||||
setSelectedAddressId(null)
|
||||
formik.setFieldValue('userAddress.latitude', lat)
|
||||
formik.setFieldValue('userAddress.longitude', lng)
|
||||
},
|
||||
[formik]
|
||||
)
|
||||
|
||||
const removeItem = (foodId: string) => {
|
||||
formik.setFieldValue(
|
||||
'items',
|
||||
@@ -418,7 +464,7 @@ export const useCreateOrderForm = () => {
|
||||
addFoodToOrder,
|
||||
updateItemQuantity,
|
||||
removeItem,
|
||||
isSubmitting: isCreating || isCreatingUser,
|
||||
isSubmitting: isCreating || isCreatingUser || isCreatingAddress,
|
||||
customerAddresses,
|
||||
selectedAddressId,
|
||||
handleUserFound,
|
||||
@@ -427,6 +473,7 @@ export const useCreateOrderForm = () => {
|
||||
applySavedAddress,
|
||||
selectManualAddress,
|
||||
handleAddressFieldChange,
|
||||
handleLocationSelect,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -249,10 +249,8 @@ export interface CreateOrderItem {
|
||||
}
|
||||
|
||||
export interface CreateOrderUserAddress {
|
||||
fullName: string;
|
||||
title: string;
|
||||
phone: string;
|
||||
city: string;
|
||||
province: string;
|
||||
address: string;
|
||||
postalCode: string;
|
||||
latitude: number;
|
||||
@@ -267,18 +265,14 @@ export interface CreateOrderCarAddress {
|
||||
}
|
||||
|
||||
export interface CreateOrderType {
|
||||
userPhone: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
userId: string;
|
||||
items: CreateOrderItem[];
|
||||
deliveryMethodId: string;
|
||||
paymentMethodId: string;
|
||||
description?: string;
|
||||
tableNumber?: string;
|
||||
userAddress?: CreateOrderUserAddress;
|
||||
addressId?: string;
|
||||
carAddress?: CreateOrderCarAddress;
|
||||
paymentDesc?: string;
|
||||
paymentAttachments?: string[];
|
||||
}
|
||||
|
||||
export type CreateOrderResponse = IResponse<Order>;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { CreateUserAddressType } from '@/pages/customers/types/Types'
|
||||
import type { CreateOrderUserAddress } from '../types/Types'
|
||||
|
||||
export const mapFormAddressToCreateUserAddress = (
|
||||
address: CreateOrderUserAddress,
|
||||
isDefault: boolean
|
||||
): CreateUserAddressType => {
|
||||
const payload: CreateUserAddressType = {
|
||||
title: address.title || 'آدرس جدید',
|
||||
address: address.address,
|
||||
latitude: Number(address.latitude) || 0,
|
||||
longitude: Number(address.longitude) || 0,
|
||||
phone: address.phone,
|
||||
isDefault,
|
||||
}
|
||||
|
||||
const postalCode = address.postalCode?.trim()
|
||||
if (postalCode) {
|
||||
payload.postalCode = postalCode
|
||||
}
|
||||
|
||||
return payload
|
||||
}
|
||||
@@ -2,15 +2,12 @@ import type { UserSavedAddress } from '@/pages/customers/types/Types'
|
||||
import type { CreateOrderUserAddress } from '../types/Types'
|
||||
|
||||
export const mapSavedAddressToOrderAddress = (
|
||||
saved: UserSavedAddress,
|
||||
fullName: string
|
||||
saved: UserSavedAddress
|
||||
): CreateOrderUserAddress => ({
|
||||
fullName: fullName || saved.title,
|
||||
title: saved.title || 'آدرس',
|
||||
phone: saved.phone,
|
||||
city: saved.city,
|
||||
province: saved.province,
|
||||
address: saved.address,
|
||||
postalCode: saved.postalCode,
|
||||
postalCode: saved.postalCode || '',
|
||||
latitude: saved.latitude,
|
||||
longitude: saved.longitude,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user