Files
danak-admin/src/pages/support/Create.tsx
T
hamid zarghami 00d46d26b9 support plan
2025-05-05 15:19:44 +03:30

212 lines
8.7 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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, 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