Files
dzone-admin/src/pages/company/Create.tsx
T
hamid zarghami 75d671545b docket file
2025-05-19 16:32:55 +03:30

278 lines
13 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 { FC } from 'react'
import Button from '../../components/Button'
import { TickCircle } from 'iconsax-react'
import Input from '../../components/Input'
import CreateSidebar from './components/CreateSidebar'
import { useTranslation } from 'react-i18next'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import { CreateCompanyType } from './types/CompanyTypes'
import { useState } from 'react'
import { useMultiUpload, useSingleUpload } from '../service/hooks/useServiceData'
import { useCreateCompany } from './hooks/useCompanyData'
import { toast } from 'react-toastify'
import { ErrorType } from '../../helpers/types'
import { Pages } from '../../config/Pages'
import { useNavigate } from 'react-router-dom'
import CompanyServices from './components/CompanyServices'
import CompanyProducts from './components/CompanyProducts'
import DatePickerComponent from '../../components/DatePicker'
import moment from 'moment-jalaali'
const CreateCompany: FC = () => {
const navigate = useNavigate()
const { t } = useTranslation('global')
const [profileImage, setProfileImage] = useState<File | null>(null)
const [coverImage, setCoverImage] = useState<File | null>(null)
const multiUpload = useMultiUpload()
const singleUpload = useSingleUpload()
const createCompany = useCreateCompany()
const formik = useFormik<CreateCompanyType>({
initialValues: {
phone: '',
firstName: '',
lastName: '',
nationalCode: '',
password: '',
name: '',
email: '',
identificationNumber: '',
dateOfEstablishment: '',
address: '',
mapAddressLink: '',
description: '',
websiteUrl: '',
profileImageUrl: '',
coverImageUrl: '',
isActive: true,
industryId: '',
products: [],
services: [],
},
validationSchema: Yup.object({
phone: Yup.string().required(t('errors.required')),
firstName: Yup.string().required(t('errors.required')),
lastName: Yup.string().required(t('errors.required')),
nationalCode: Yup.string().required(t('errors.required')),
password: Yup.string().required(t('errors.required')),
name: Yup.string().required(t('errors.required')),
email: Yup.string().email(t('errors.invalid_email')).required(t('errors.required')),
identificationNumber: Yup.string().required(t('errors.required')),
dateOfEstablishment: Yup.string().required(t('errors.required')),
address: Yup.string().required(t('errors.required')),
mapAddressLink: Yup.string().url(t('errors.invalid_url')),
description: Yup.string().required(t('errors.required')),
websiteUrl: Yup.string().url(t('errors.invalid_url')).required(t('errors.required')),
isActive: Yup.boolean().required(t('errors.required')),
industryId: Yup.string().required(t('errors.required')),
// products and services validation can be added if needed
}),
onSubmit: async (values) => {
if (!profileImage || !coverImage) {
toast.error('لطفا تصاویر را انتخاب کنید')
return
}
// آپلود تصاویر خدمات
let serviceImages: string[] = []
if (services.length > 0) {
const formDataServices = new FormData()
services.forEach(s => s.image && formDataServices.append('files', s.image))
const serviceUploadRes = await multiUpload.mutateAsync(formDataServices)
serviceImages = serviceUploadRes.data.map((item: { url: string }) => item?.url)
}
// آپلود تصاویر محصولات
let productImages: string[] = []
if (products.length > 0) {
const formDataProducts = new FormData()
products.forEach(p => p.image && formDataProducts.append('files', p.image))
const productUploadRes = await multiUpload.mutateAsync(formDataProducts)
productImages = productUploadRes.data.map((item: { url: string }) => item?.url)
}
// مقداردهی به values
values.services = services.map((s, idx) => ({
title: s.title,
imageUrl: serviceImages[idx] ? serviceImages[idx] : ''
}))
values.products = products.map((p, idx) => ({
title: p.title,
imageUrl: productImages[idx] ? productImages[idx] : ''
}))
const formDataProfile = new FormData()
formDataProfile.append('file', profileImage)
const profileUploadRes = await singleUpload.mutateAsync(formDataProfile)
values.profileImageUrl = profileUploadRes.data.url
const formDataCover = new FormData()
formDataCover.append('file', coverImage)
const coverUploadRes = await singleUpload.mutateAsync(formDataCover)
values.coverImageUrl = coverUploadRes.data.url
await createCompany.mutateAsync(values, {
onSuccess: () => {
toast.success('شرکت با موفقیت ثبت شد')
navigate(Pages.company.list)
},
onError: (error: ErrorType) => {
toast.error(error.response?.data?.error?.message[0])
}
})
}
})
const [services, setServices] = useState<{ title: string; image?: File }[]>([])
const [products, setProducts] = useState<{ title: string; image?: File }[]>([])
return (
<div className='mt-4'>
<div className='flex justify-between items-center'>
<div>
افزودن شرکت
</div>
<Button
className='w-fit px-4'
onClick={() => formik.handleSubmit()}
isLoading={createCompany.isPending || singleUpload.isPending || multiUpload.isPending}
>
<div className='flex items-center gap-2'>
<TickCircle size={20} color='white' />
<div>ثبت شرکت</div>
</div>
</Button>
</div>
<div className='flex gap-6'>
<div className='flex-1'>
<div className='flex-1 mt-10 bg-white py-8 xl:px-10 px-4 rounded-3xl'>
<div>اطلاعات شرکت</div>
<div className='mt-6'>
<Input
label='نام شرکت'
name='name'
value={formik.values.name}
onChange={formik.handleChange}
error_text={formik.touched.name && formik.errors.name ? formik.errors.name : ''}
/>
</div>
<div className='rowTwoInput mt-6'>
<Input
label='نام'
name='firstName'
value={formik.values.firstName}
onChange={formik.handleChange}
error_text={formik.touched.firstName && formik.errors.firstName ? formik.errors.firstName : ''}
/>
<Input
label='نام خانوادگی'
name='lastName'
value={formik.values.lastName}
onChange={formik.handleChange}
error_text={formik.touched.lastName && formik.errors.lastName ? formik.errors.lastName : ''}
/>
</div>
<div className='rowTwoInput mt-6'>
<Input
label='کد ملی'
name='nationalCode'
value={formik.values.nationalCode}
onChange={formik.handleChange}
error_text={formik.touched.nationalCode && formik.errors.nationalCode ? formik.errors.nationalCode : ''}
/>
<Input
label='رمز عبور'
name='password'
type='password'
value={formik.values.password}
onChange={formik.handleChange}
error_text={formik.touched.password && formik.errors.password ? formik.errors.password : ''}
/>
</div>
<div className='rowTwoInput mt-6'>
<Input
label={t('company.phone_number')}
name='phone'
value={formik.values.phone}
onChange={formik.handleChange}
error_text={formik.touched.phone && formik.errors.phone ? formik.errors.phone : ''}
/>
<Input
label={t('company.email')}
name='email'
value={formik.values.email}
onChange={formik.handleChange}
error_text={formik.touched.email && formik.errors.email ? formik.errors.email : ''}
/>
</div>
<div className='rowTwoInput mt-6'>
<Input
label={t('company.national_id')}
name='identificationNumber'
value={formik.values.identificationNumber}
onChange={formik.handleChange}
error_text={formik.touched.identificationNumber && formik.errors.identificationNumber ? formik.errors.identificationNumber : ''}
/>
<DatePickerComponent
label={t('company.establishment_date')}
placeholder='تاریخ تاسیس'
onChange={(date) => formik.setFieldValue('dateOfEstablishment', moment(date).format('YYYY-MM-DD'))}
error_text={formik.touched.dateOfEstablishment && formik.errors.dateOfEstablishment ? formik.errors.dateOfEstablishment : ''}
/>
</div>
<div className='rowTwoInput mt-6'>
<Input
label={t('company.map_link')}
name='mapAddressLink'
value={formik.values.mapAddressLink}
onChange={formik.handleChange}
error_text={formik.touched.mapAddressLink && formik.errors.mapAddressLink ? formik.errors.mapAddressLink : ''}
/>
</div>
<div className='mt-6'>
<Input
label={t('company.address')}
name='address'
value={formik.values.address}
onChange={formik.handleChange}
error_text={formik.touched.address && formik.errors.address ? formik.errors.address : ''}
/>
</div>
<div className='mt-6'>
<Input
label={t('company.short_description')}
name='description'
value={formik.values.description}
onChange={formik.handleChange}
error_text={formik.touched.description && formik.errors.description ? formik.errors.description : ''}
/>
</div>
<CompanyServices value={services} onChange={setServices} />
<CompanyProducts value={products} onChange={setProducts} />
</div>
</div>
<CreateSidebar formik={formik} setProfileImage={setProfileImage} setCoverImage={setCoverImage} />
</div>
</div>
)
}
export default CreateCompany