Files
dmenu-admin/src/pages/orders/components/CreateOrderDeliverySection.tsx
T
hamid zarghami 7130c304c5 Create order
2026-06-23 12:31:39 +03:30

270 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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'
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>
<div className='grid grid-cols-1 sm:grid-cols-2 gap-3'>
{deliveryMethods.map((method) => {
const isSelected = formik.values.deliveryMethodId === method.id
return (
<button
key={method.id}
type='button'
onClick={() => formik.setFieldValue('deliveryMethodId', method.id)}
className={`text-right p-4 rounded-xl border transition-colors ${
isSelected
? 'border-primary bg-primary/5'
: 'border-border hover:border-primary/40'
}`}
>
<div className='text-sm font-medium'>
{getDeliveryLabel(method.method)}
</div>
{method.description && (
<div className='text-xs text-description mt-1 line-clamp-2'>
{method.description}
</div>
)}
{method.deliveryFee > 0 && (
<div className='text-xs mt-2 text-primary'>
{formatPrice(method.deliveryFee)}
</div>
)}
</button>
)
})}
</div>
{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>
<div className='p-4 rounded-xl border border-primary bg-primary/5'>
<div className='text-sm font-medium'>پرداخت نقدی</div>
{cashPaymentMethod?.description && (
<div className='text-xs text-description mt-1'>
{cashPaymentMethod.description}
</div>
)}
</div>
{!cashPaymentMethod && (
<div className='text-xs text-red-500 mt-2'>
روش پرداخت نقدی فعال یافت نشد
</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