crud company
This commit is contained in:
+167
-53
@@ -6,40 +6,129 @@ 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({
|
||||
const formik = useFormik<CreateCompanyType>({
|
||||
initialValues: {
|
||||
phone: '',
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
nationalCode: '',
|
||||
password: '',
|
||||
name: '',
|
||||
ceoFirstName: '',
|
||||
ceoLastName: '',
|
||||
phoneNumber: '',
|
||||
email: '',
|
||||
nationalId: '',
|
||||
establishmentDate: '',
|
||||
identificationNumber: '',
|
||||
dateOfEstablishment: '',
|
||||
address: '',
|
||||
mapLink: '',
|
||||
shortDescription: ''
|
||||
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')),
|
||||
ceoFirstName: Yup.string().required(t('errors.required')),
|
||||
ceoLastName: Yup.string().required(t('errors.required')),
|
||||
phoneNumber: Yup.string().required(t('errors.required')),
|
||||
email: Yup.string().email(t('errors.invalid_email')).required(t('errors.required')),
|
||||
nationalId: Yup.string().required(t('errors.required')),
|
||||
establishmentDate: Yup.string().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')),
|
||||
mapLink: Yup.string().url(t('errors.invalid_url')),
|
||||
shortDescription: 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: (values) => {
|
||||
console.log(values)
|
||||
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'>
|
||||
@@ -50,6 +139,7 @@ const CreateCompany: FC = () => {
|
||||
<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' />
|
||||
@@ -63,41 +153,57 @@ const CreateCompany: FC = () => {
|
||||
<div className='flex-1 mt-10 bg-white py-8 xl:px-10 px-4 rounded-3xl'>
|
||||
<div>اطلاعات شرکت</div>
|
||||
|
||||
<div className='rowTwoInput mt-6'>
|
||||
<div className='mt-6'>
|
||||
<Input
|
||||
label={t('company.company_name')}
|
||||
label='نام شرکت'
|
||||
name='name'
|
||||
value={formik.values.name}
|
||||
onChange={formik.handleChange}
|
||||
error_text={formik.touched.name && formik.errors.name ? formik.errors.name : ''}
|
||||
/>
|
||||
<Input
|
||||
label={t('company.ceo_first_name')}
|
||||
name='ceoFirstName'
|
||||
value={formik.values.ceoFirstName}
|
||||
onChange={formik.handleChange}
|
||||
error_text={formik.touched.ceoFirstName && formik.errors.ceoFirstName ? formik.errors.ceoFirstName : ''}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='rowTwoInput mt-6'>
|
||||
<Input
|
||||
label={t('company.ceo_last_name')}
|
||||
name='ceoLastName'
|
||||
value={formik.values.ceoLastName}
|
||||
label='نام'
|
||||
name='firstName'
|
||||
value={formik.values.firstName}
|
||||
onChange={formik.handleChange}
|
||||
error_text={formik.touched.ceoLastName && formik.errors.ceoLastName ? formik.errors.ceoLastName : ''}
|
||||
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='phoneNumber'
|
||||
value={formik.values.phoneNumber}
|
||||
name='phone'
|
||||
value={formik.values.phone}
|
||||
onChange={formik.handleChange}
|
||||
error_text={formik.touched.phoneNumber && formik.errors.phoneNumber ? formik.errors.phoneNumber : ''}
|
||||
error_text={formik.touched.phone && formik.errors.phone ? formik.errors.phone : ''}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='rowTwoInput mt-6'>
|
||||
<Input
|
||||
label={t('company.email')}
|
||||
name='email'
|
||||
@@ -105,29 +211,32 @@ const CreateCompany: FC = () => {
|
||||
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='nationalId'
|
||||
value={formik.values.nationalId}
|
||||
name='identificationNumber'
|
||||
value={formik.values.identificationNumber}
|
||||
onChange={formik.handleChange}
|
||||
error_text={formik.touched.nationalId && formik.errors.nationalId ? formik.errors.nationalId : ''}
|
||||
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.establishment_date')}
|
||||
name='establishmentDate'
|
||||
value={formik.values.establishmentDate}
|
||||
onChange={formik.handleChange}
|
||||
error_text={formik.touched.establishmentDate && formik.errors.establishmentDate ? formik.errors.establishmentDate : ''}
|
||||
/>
|
||||
<Input
|
||||
label={t('company.map_link')}
|
||||
name='mapLink'
|
||||
value={formik.values.mapLink}
|
||||
name='mapAddressLink'
|
||||
value={formik.values.mapAddressLink}
|
||||
onChange={formik.handleChange}
|
||||
error_text={formik.touched.mapLink && formik.errors.mapLink ? formik.errors.mapLink : ''}
|
||||
error_text={formik.touched.mapAddressLink && formik.errors.mapAddressLink ? formik.errors.mapAddressLink : ''}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -144,16 +253,21 @@ const CreateCompany: FC = () => {
|
||||
<div className='mt-6'>
|
||||
<Input
|
||||
label={t('company.short_description')}
|
||||
name='shortDescription'
|
||||
value={formik.values.shortDescription}
|
||||
name='description'
|
||||
value={formik.values.description}
|
||||
onChange={formik.handleChange}
|
||||
error_text={formik.touched.shortDescription && formik.errors.shortDescription ? formik.errors.shortDescription : ''}
|
||||
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 />
|
||||
<CreateSidebar formik={formik} setProfileImage={setProfileImage} setCoverImage={setCoverImage} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user