212 lines
8.7 KiB
TypeScript
212 lines
8.7 KiB
TypeScript
import { FC, useState } from 'react'
|
||
import Input from '../../components/Input'
|
||
import SwitchComponent from '../../components/Switch'
|
||
import Textarea from '../../components/Textarea'
|
||
import Button from '../../components/Button'
|
||
import { SupportPlanFeatureKey } from './enum/SupportEnum'
|
||
import { useTranslation } from 'react-i18next'
|
||
import PlanItem from './components/PlanItem'
|
||
import { useFormik } from 'formik'
|
||
import { CreatePlanType } from './types/SupportTypes'
|
||
import * as Yup from 'yup'
|
||
import Select from '../../components/Select'
|
||
import { useCreateSupport } from './hooks/useSupportData'
|
||
import { toast } from 'react-toastify'
|
||
import { ErrorType } from '../../helpers/types'
|
||
import { useNavigate } from 'react-router-dom'
|
||
import { Pages } from '../../config/Pages'
|
||
interface PlanFeature {
|
||
featureKey: string;
|
||
featureValue: string | boolean;
|
||
featureType: 'boolean' | 'text';
|
||
isEnabled: boolean;
|
||
}
|
||
|
||
const CreatePlan: FC = () => {
|
||
|
||
const navigate = useNavigate()
|
||
const { t } = useTranslation('global')
|
||
const createSupport = useCreateSupport()
|
||
const [features, setFeatures] = useState<PlanFeature[]>(
|
||
Object.values(SupportPlanFeatureKey).map(key => ({
|
||
featureKey: key,
|
||
featureValue: true,
|
||
featureType: 'boolean',
|
||
isEnabled: true
|
||
}))
|
||
)
|
||
|
||
const handleFeatureChange = (id: string, value: string | boolean, isEnabled: boolean) => {
|
||
setFeatures(prevFeatures =>
|
||
prevFeatures.map(feature =>
|
||
feature.featureKey === id ? { ...feature, featureValue: value, isEnabled } : feature
|
||
)
|
||
)
|
||
}
|
||
|
||
const handleFeatureTypeChange = (id: string, type: 'boolean' | 'text') => {
|
||
setFeatures(prevFeatures =>
|
||
prevFeatures.map(feature =>
|
||
feature.featureKey === id ? {
|
||
...feature,
|
||
featureType: type,
|
||
featureValue: type === 'boolean' ? true : '',
|
||
isEnabled: type === 'boolean' ? true : false
|
||
} : feature
|
||
)
|
||
)
|
||
}
|
||
|
||
const prepareFeaturesForSubmission = (features: PlanFeature[]) => {
|
||
return features.map(feature => {
|
||
if (feature.featureType === 'boolean') {
|
||
return {
|
||
featureKey: feature.featureKey,
|
||
featureValue: feature.isEnabled,
|
||
featureType: 'boolean',
|
||
}
|
||
} else {
|
||
return {
|
||
featureKey: feature.featureKey,
|
||
featureValue: feature.featureValue as string,
|
||
featureType: 'text',
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
const formik = useFormik<CreatePlanType>({
|
||
initialValues: {
|
||
name: '',
|
||
description: '',
|
||
price: 0,
|
||
duration: 0,
|
||
isActive: true,
|
||
features: [],
|
||
},
|
||
validationSchema: Yup.object({
|
||
name: Yup.string().required('نام پلن الزامی است'),
|
||
description: Yup.string().required('توضیحات پلن الزامی است'),
|
||
price: Yup.number().required('قیمت پلن الزامی است'),
|
||
duration: Yup.number().required('مدت پلن الزامی است'),
|
||
}),
|
||
onSubmit: (values) => {
|
||
values.price = Number(values.price)
|
||
values.duration = Number(values.duration)
|
||
const preparedFeatures = prepareFeaturesForSubmission(features)
|
||
const planData: CreatePlanType = {
|
||
...values,
|
||
features: preparedFeatures.map(feature => ({
|
||
featureKey: feature.featureKey,
|
||
featureValue: String(feature.featureValue),
|
||
featureType: feature.featureType as "text" | "boolean"
|
||
}))
|
||
}
|
||
createSupport.mutate(planData, {
|
||
onSuccess: () => {
|
||
toast.success('پلن با موفقیت ساخته شد')
|
||
navigate(Pages.support.list)
|
||
},
|
||
onError: (error: ErrorType) => {
|
||
toast.error(error.response?.data?.error.message[0])
|
||
}
|
||
})
|
||
},
|
||
})
|
||
|
||
return (
|
||
<div className='mt-4'>
|
||
<div className='text-lg font-semibold mb-6'>ساخت پلن</div>
|
||
|
||
<div className='bg-white rounded-lg p-6 shadow-sm mb-6'>
|
||
<div className='text-base font-medium mb-4'>اطلاعات اصلی پلن</div>
|
||
<div className='space-y-6'>
|
||
<div className='rowTwoInput'>
|
||
<Input
|
||
label='نام پلن'
|
||
placeholder='نام پلن'
|
||
{...formik.getFieldProps('name')}
|
||
error_text={formik.touched.name && formik.errors.name ? formik.errors.name : undefined}
|
||
/>
|
||
</div>
|
||
|
||
<div className='rowTwoInput'>
|
||
<Input
|
||
label='قیمت پلن'
|
||
placeholder='قیمت پلن'
|
||
{...formik.getFieldProps('price')}
|
||
error_text={formik.touched.price && formik.errors.price ? formik.errors.price : undefined}
|
||
/>
|
||
|
||
<Input
|
||
label='مدت پلن'
|
||
placeholder='مدت پلن'
|
||
{...formik.getFieldProps('duration')}
|
||
error_text={formik.touched.duration && formik.errors.duration ? formik.errors.duration : undefined}
|
||
/>
|
||
</div>
|
||
|
||
<div className='rowTwoInput'>
|
||
<Textarea
|
||
label='توضیحات پلن'
|
||
placeholder='توضیحات پلن'
|
||
{...formik.getFieldProps('description')}
|
||
error_text={formik.touched.description && formik.errors.description ? formik.errors.description : undefined}
|
||
/>
|
||
</div>
|
||
|
||
<div className='rowTwoInput'>
|
||
<SwitchComponent
|
||
active={formik.values.isActive}
|
||
onChange={(active: boolean) => formik.setFieldValue('isActive', active)}
|
||
label='فعال'
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className='bg-white rounded-lg p-6 shadow-sm'>
|
||
<div className='text-base font-medium mb-4'>ویژگیهای پلن</div>
|
||
<div className='space-y-8'>
|
||
{features.map((feature) => (
|
||
<div key={feature.featureKey} className='border-b border-gray-100 pb-6 last:border-0'>
|
||
<div className='flex items-center gap-4 mb-4'>
|
||
<div className='w-48'>
|
||
<Select
|
||
label='نوع مقدار'
|
||
items={[
|
||
{ label: 'بله/خیر', value: 'boolean' },
|
||
{ label: 'مقدار', value: 'text' }
|
||
]}
|
||
value={feature.featureType}
|
||
onChange={(e) => handleFeatureTypeChange(feature.featureKey, e.target.value as 'boolean' | 'text')}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<PlanItem
|
||
id={feature.featureKey}
|
||
label={t(`support.${feature.featureKey}`)}
|
||
value={feature.featureValue}
|
||
checked={feature.isEnabled}
|
||
featureType={feature.featureType}
|
||
onChange={handleFeatureChange}
|
||
/>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div className='mt-6 flex justify-end'>
|
||
<Button
|
||
label='ثبت پلن'
|
||
onClick={() => formik.handleSubmit()}
|
||
disabled={!formik.isValid || !formik.dirty}
|
||
className='w-fit px-7'
|
||
isLoading={createSupport.isPending}
|
||
/>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default CreatePlan |