259 lines
11 KiB
TypeScript
259 lines
11 KiB
TypeScript
import { type FC, useState } from 'react'
|
||
import type { FormikProps } from 'formik'
|
||
import { useTranslation } from 'react-i18next'
|
||
import Input from '@/components/Input'
|
||
import RadioGroup from '@/components/RadioGroup'
|
||
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'
|
||
import type { UserSavedAddress } from '@/pages/customers/types/Types'
|
||
import CreateOrderAddressSelector from './CreateOrderAddressSelector'
|
||
|
||
interface CreateOrderDeliverySectionProps {
|
||
formik: FormikProps<CreateOrderFormValues>
|
||
deliveryMethods: RestaurantShipmentMethod[]
|
||
cashPaymentMethod?: RestaurantPaymentMethod
|
||
isCourierDelivery: boolean
|
||
isCarDelivery: boolean
|
||
isDineIn: boolean
|
||
customerAddresses: UserSavedAddress[]
|
||
selectedAddressId: string | null
|
||
onSelectSavedAddress: (address: UserSavedAddress) => void
|
||
onSelectManualAddress: () => void
|
||
onAddressFieldChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void
|
||
onLocationSelect: (lat: number, lng: number) => void
|
||
}
|
||
|
||
const CreateOrderDeliverySection: FC<CreateOrderDeliverySectionProps> = ({
|
||
formik,
|
||
deliveryMethods,
|
||
cashPaymentMethod,
|
||
isCourierDelivery,
|
||
isCarDelivery,
|
||
isDineIn,
|
||
customerAddresses,
|
||
selectedAddressId,
|
||
onSelectSavedAddress,
|
||
onSelectManualAddress,
|
||
onAddressFieldChange,
|
||
onLocationSelect,
|
||
}) => {
|
||
const { t } = useTranslation('global')
|
||
const [isLocationModalOpen, setIsLocationModalOpen] = useState(false)
|
||
|
||
const getDeliveryLabel = (method: string) => {
|
||
return t(`shipment.${method}`, {
|
||
defaultValue: method,
|
||
})
|
||
}
|
||
|
||
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'>
|
||
<div className='text-lg font-light'>تحویل و پرداخت</div>
|
||
|
||
<div className='mt-6'>
|
||
<div className='text-sm mb-3'>روش تحویل</div>
|
||
<RadioGroup
|
||
items={deliveryMethods.map((method) => ({
|
||
label:
|
||
method.deliveryFee > 0
|
||
? `${getDeliveryLabel(method.method)} (${formatPrice(method.deliveryFee)})`
|
||
: getDeliveryLabel(method.method),
|
||
value: method.id,
|
||
}))}
|
||
selected={formik.values.deliveryMethodId}
|
||
onChange={(value) => {
|
||
formik.setFieldValue('deliveryMethodId', value)
|
||
formik.setFieldTouched('deliveryMethodId', true, false)
|
||
}}
|
||
/>
|
||
{formik.touched.deliveryMethodId && formik.errors.deliveryMethodId && (
|
||
<div className='text-xs text-red-500 mt-2'>
|
||
{formik.errors.deliveryMethodId}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<div className='mt-8'>
|
||
<div className='text-sm mb-3'>روش پرداخت</div>
|
||
{cashPaymentMethod ? (
|
||
<RadioGroup
|
||
items={[
|
||
{
|
||
label: cashPaymentMethod.description
|
||
? `پرداخت نقدی (${cashPaymentMethod.description})`
|
||
: 'پرداخت نقدی',
|
||
value: cashPaymentMethod.id,
|
||
},
|
||
]}
|
||
selected={formik.values.paymentMethodId}
|
||
onChange={(value) => formik.setFieldValue('paymentMethodId', value)}
|
||
/>
|
||
) : (
|
||
<div className='text-xs text-red-500'>
|
||
روش پرداخت نقدی فعال یافت نشد
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{isDineIn && (
|
||
<div className='mt-8'>
|
||
<Input
|
||
label='شماره میز'
|
||
name='tableNumber'
|
||
placeholder='مثال: ۱۲'
|
||
value={formik.values.tableNumber}
|
||
onChange={formik.handleChange}
|
||
/>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{isCourierDelivery && (
|
||
<div className='w-full bg-white rounded-4xl p-8'>
|
||
<div className='text-lg font-light'>آدرس تحویل</div>
|
||
|
||
<CreateOrderAddressSelector
|
||
addresses={customerAddresses}
|
||
selectedAddressId={selectedAddressId}
|
||
onSelectAddress={onSelectSavedAddress}
|
||
onSelectManual={onSelectManualAddress}
|
||
/>
|
||
|
||
<div className='grid grid-cols-1 sm:grid-cols-2 gap-4 mt-6'>
|
||
<Input
|
||
label='عنوان آدرس'
|
||
name='userAddress.title'
|
||
placeholder='مثال: منزل'
|
||
value={formik.values.userAddress.title}
|
||
onChange={onAddressFieldChange}
|
||
readOnly={isAddressReadOnly}
|
||
/>
|
||
<Input
|
||
label='شماره تماس'
|
||
name='userAddress.phone'
|
||
value={formik.values.userAddress.phone}
|
||
onChange={onAddressFieldChange}
|
||
readOnly={isAddressReadOnly}
|
||
/>
|
||
<Input
|
||
label='کد پستی'
|
||
name='userAddress.postalCode'
|
||
value={formik.values.userAddress.postalCode}
|
||
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>
|
||
|
||
<div className='mt-5'>
|
||
<Textarea
|
||
label='آدرس کامل'
|
||
name='userAddress.address'
|
||
value={formik.values.userAddress.address}
|
||
onChange={onAddressFieldChange}
|
||
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>
|
||
)}
|
||
|
||
{isCarDelivery && (
|
||
<div className='w-full bg-white rounded-4xl p-8'>
|
||
<div className='text-lg font-light'>اطلاعات خودرو</div>
|
||
|
||
<div className='grid grid-cols-1 sm:grid-cols-2 gap-4 mt-6'>
|
||
<Input
|
||
label='مدل خودرو'
|
||
name='carAddress.carModel'
|
||
value={formik.values.carAddress.carModel}
|
||
onChange={formik.handleChange}
|
||
/>
|
||
<Input
|
||
label='رنگ خودرو'
|
||
name='carAddress.carColor'
|
||
value={formik.values.carAddress.carColor}
|
||
onChange={formik.handleChange}
|
||
/>
|
||
<Input
|
||
label='پلاک'
|
||
name='carAddress.plateNumber'
|
||
value={formik.values.carAddress.plateNumber}
|
||
onChange={formik.handleChange}
|
||
/>
|
||
<Input
|
||
label='شماره تماس'
|
||
name='carAddress.phone'
|
||
value={formik.values.carAddress.phone}
|
||
onChange={formik.handleChange}
|
||
/>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
<div className='w-full bg-white rounded-4xl p-8'>
|
||
<div className='text-lg font-light'>توضیحات سفارش</div>
|
||
<div className='mt-6'>
|
||
<Textarea
|
||
label='توضیحات'
|
||
name='description'
|
||
placeholder='توضیحات اضافی برای سفارش...'
|
||
value={formik.values.description}
|
||
onChange={formik.handleChange}
|
||
isNotRequired
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default CreateOrderDeliverySection
|