multi phones in setting
This commit is contained in:
@@ -17,11 +17,15 @@ import * as yup from 'yup'
|
||||
import { toast } from 'react-toastify'
|
||||
import { extractErrorMessage } from '@/config/func'
|
||||
import ServiceAreaPicker from './components/ServiceAreaPicker'
|
||||
import PhonesSection from './components/PhonesSection'
|
||||
|
||||
const validationSchema = yup.object({
|
||||
name: yup.string().required('نام رستوران الزامی است'),
|
||||
menuColor: yup.string().required('رنگ منو الزامی است'),
|
||||
phone: yup.string().required('شماره تماس الزامی است'),
|
||||
phones: yup
|
||||
.array()
|
||||
.min(1, 'حداقل یک شماره تماس الزامی است')
|
||||
.of(yup.string().required('شماره تماس الزامی است')),
|
||||
instagram: yup.string().url('لینک اینستاگرام معتبر نیست').nullable(),
|
||||
address: yup.string().required('آدرس الزامی است'),
|
||||
latitude: yup.number().required('انتخاب موقعیت روی نقشه الزامی است'),
|
||||
@@ -40,7 +44,7 @@ const GeneralSettings: FC = () => {
|
||||
initialValues: {
|
||||
name: '',
|
||||
menuColor: '#000000',
|
||||
phone: '',
|
||||
phones: [''],
|
||||
instagram: '',
|
||||
address: '',
|
||||
latitude: 0,
|
||||
@@ -93,7 +97,12 @@ const GeneralSettings: FC = () => {
|
||||
formik.setValues({
|
||||
name: restaurantData.name || '',
|
||||
menuColor: restaurantData.menuColor || '#000000',
|
||||
phone: restaurantData.phone || '',
|
||||
phones:
|
||||
restaurantData.phones?.length
|
||||
? restaurantData.phones
|
||||
: restaurantData.phone
|
||||
? [restaurantData.phone]
|
||||
: [''],
|
||||
instagram: restaurantData.instagram || '',
|
||||
address: restaurantData.address || '',
|
||||
latitude: restaurantData.latitude || 0,
|
||||
@@ -155,16 +164,11 @@ const GeneralSettings: FC = () => {
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className='mt-8 rowTwoInput'>
|
||||
<Input
|
||||
label='شماره تماس'
|
||||
name='phone'
|
||||
value={formik.values.phone}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error_text={formik.touched.phone && formik.errors.phone ? formik.errors.phone : undefined}
|
||||
/>
|
||||
<div className='mt-8'>
|
||||
<PhonesSection formik={formik} />
|
||||
</div>
|
||||
|
||||
<div className='mt-8'>
|
||||
<Input
|
||||
label='اینستاگرام'
|
||||
name='instagram'
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import { type FC } from 'react'
|
||||
import type { FormikProps } from 'formik'
|
||||
import { Add, Call, Trash } from 'iconsax-react'
|
||||
import Input from '@/components/Input'
|
||||
import type { UpdateRestaurantType } from '../types/Types'
|
||||
|
||||
type PhonesSectionProps = {
|
||||
formik: FormikProps<UpdateRestaurantType>
|
||||
}
|
||||
|
||||
const PhonesSection: FC<PhonesSectionProps> = ({ formik }) => {
|
||||
const phones = formik.values.phones ?? []
|
||||
const phonesError = formik.touched.phones && typeof formik.errors.phones === 'string' ? formik.errors.phones : ''
|
||||
const phoneErrors = Array.isArray(formik.errors.phones) ? formik.errors.phones : []
|
||||
|
||||
const getFieldError = (index: number) => {
|
||||
if (!formik.touched.phones?.[index] || !phoneErrors[index]) {
|
||||
return ''
|
||||
}
|
||||
return String(phoneErrors[index])
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='flex items-center justify-between mb-3'>
|
||||
<div className='text-sm'>شمارههای تماس</div>
|
||||
{phones.length > 0 && (
|
||||
<span className='text-xs text-description'>{phones.length} شماره</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className='space-y-3'>
|
||||
{phones.map((phone, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className='bg-gray-50 rounded-2xl p-4 border border-border'
|
||||
>
|
||||
<div className='flex items-center justify-between mb-3'>
|
||||
<div className='flex items-center gap-2.5'>
|
||||
<div className='w-9 h-9 rounded-xl bg-white border border-border flex items-center justify-center shrink-0'>
|
||||
<Call size={18} color='#8C90A3' variant='Bold' />
|
||||
</div>
|
||||
<span className='text-sm text-gray-700'>شماره {index + 1}</span>
|
||||
</div>
|
||||
{phones.length > 1 && (
|
||||
<button
|
||||
type='button'
|
||||
className='p-2 rounded-xl hover:bg-red-50 transition-colors'
|
||||
onClick={() => {
|
||||
formik.setFieldValue(
|
||||
'phones',
|
||||
phones.filter((_, i) => i !== index)
|
||||
)
|
||||
}}
|
||||
aria-label={`حذف شماره ${index + 1}`}
|
||||
>
|
||||
<Trash size={18} color='#EF4444' />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Input
|
||||
label='شماره تماس'
|
||||
name={`phones.${index}`}
|
||||
value={phone}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
inputMode='tel'
|
||||
placeholder='مثال: ۰۹۱۲۳۴۵۶۷۸۹'
|
||||
error_text={getFieldError(index)}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<button
|
||||
type='button'
|
||||
className='w-full flex items-center justify-center gap-2 h-11 rounded-2xl border border-dashed border-border text-sm text-description hover:border-primary hover:text-primary hover:bg-primary/5 transition-colors'
|
||||
onClick={() => {
|
||||
formik.setFieldValue('phones', [...phones, ''])
|
||||
}}
|
||||
>
|
||||
<Add size={20} />
|
||||
افزودن شماره جدید
|
||||
</button>
|
||||
|
||||
{phonesError && <div className='text-xs text-red-500'>{phonesError}</div>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PhonesSection
|
||||
@@ -10,7 +10,7 @@ export type GeoJSONPolygon = {
|
||||
export type UpdateRestaurantType = {
|
||||
name?: string;
|
||||
menuColor?: string;
|
||||
phone?: string;
|
||||
phones?: string[];
|
||||
instagram?: string;
|
||||
address?: string;
|
||||
logo?: string;
|
||||
@@ -51,7 +51,8 @@ export type Restaurant = {
|
||||
isActive: boolean;
|
||||
establishedYear: number | null;
|
||||
phoneNumber: string | null;
|
||||
phone: string;
|
||||
phone?: string;
|
||||
phones?: string[];
|
||||
instagram: string | null;
|
||||
telegram: string | null;
|
||||
whatsapp: string | null;
|
||||
|
||||
Reference in New Issue
Block a user