form builder
This commit is contained in:
@@ -24,6 +24,7 @@ export const Paths = {
|
|||||||
list: '/form-builder/list/',
|
list: '/form-builder/list/',
|
||||||
create: '/form-builder/create/',
|
create: '/form-builder/create/',
|
||||||
update: '/form-builder/update/',
|
update: '/form-builder/update/',
|
||||||
|
values: '/form-builder/values/'
|
||||||
},
|
},
|
||||||
order: {
|
order: {
|
||||||
list: '/order/list'
|
list: '/order/list'
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import { type FC } from 'react'
|
import { type FC } from 'react'
|
||||||
import { useParams } from 'react-router-dom'
|
import { useParams } from 'react-router-dom'
|
||||||
import { useDeleteAttributeValue, useGetAttributeValues } from '../hooks/useProductData'
|
import { useDeleteFieldValue, useGetFieldValues } from './hooks/useFormBuilderData'
|
||||||
import CreateValue from '../components/CreateValue'
|
import CreateValue from './components/CreateValue'
|
||||||
import Table from '@/components/Table'
|
import Table from '@/components/Table'
|
||||||
import UpdateValue from '../components/UpdateValue'
|
import UpdateValue from './components/UpdateValue'
|
||||||
import TrashWithConfrim from '@/components/TrashWithConfrim'
|
import TrashWithConfrim from '@/components/TrashWithConfrim'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import { extractErrorMessage } from '@/config/func'
|
import { extractErrorMessage } from '@/config/func'
|
||||||
|
|
||||||
const AttributeValues: FC = () => {
|
const FormBuilderValues: FC = () => {
|
||||||
|
|
||||||
const { id } = useParams()
|
const { id } = useParams()
|
||||||
const { data, refetch } = useGetAttributeValues(Number(id))
|
const { data, refetch } = useGetFieldValues(Number(id))
|
||||||
const { mutate: deleteValue, isPending } = useDeleteAttributeValue()
|
const { mutate: deleteValue, isPending } = useDeleteFieldValue()
|
||||||
|
|
||||||
const handleDelete = (id: number) => {
|
const handleDelete = (id: number) => {
|
||||||
deleteValue(id, {
|
deleteValue(id, {
|
||||||
@@ -76,4 +76,4 @@ const AttributeValues: FC = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AttributeValues
|
export default FormBuilderValues
|
||||||
@@ -26,7 +26,7 @@ const FormBuilderCreate: FC = () => {
|
|||||||
isRequired: true,
|
isRequired: true,
|
||||||
order: 1,
|
order: 1,
|
||||||
type: FieldTypeEnum.text,
|
type: FieldTypeEnum.text,
|
||||||
entityType: 'product',
|
entityType: type!,
|
||||||
multiple: false,
|
multiple: false,
|
||||||
},
|
},
|
||||||
validationSchema: Yup.object({
|
validationSchema: Yup.object({
|
||||||
@@ -49,7 +49,7 @@ const FormBuilderCreate: FC = () => {
|
|||||||
<div className='mt-5'>
|
<div className='mt-5'>
|
||||||
<div className='flex justify-between items-center'>
|
<div className='flex justify-between items-center'>
|
||||||
|
|
||||||
<h1 className='text-lg font-light'>ساخت ویژگی جدید</h1>
|
<h1 className='text-lg font-light'>ساخت فیلد جدید</h1>
|
||||||
<Button
|
<Button
|
||||||
className='w-fit px-6'
|
className='w-fit px-6'
|
||||||
onClick={() => formik.handleSubmit()}
|
onClick={() => formik.handleSubmit()}
|
||||||
@@ -57,7 +57,7 @@ const FormBuilderCreate: FC = () => {
|
|||||||
>
|
>
|
||||||
<div className='flex gap-1.5'>
|
<div className='flex gap-1.5'>
|
||||||
<AddSquare size={18} color='black' />
|
<AddSquare size={18} color='black' />
|
||||||
<div className='text-[13px] font-light'>ویژگی جدید</div>
|
<div className='text-[13px] font-light'>فیلد جدید</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -65,7 +65,7 @@ const FormBuilderCreate: FC = () => {
|
|||||||
<div className='mt-8 bg-white p-6 rounded-3xl flex-1'>
|
<div className='mt-8 bg-white p-6 rounded-3xl flex-1'>
|
||||||
<div className='rowTwoInput'>
|
<div className='rowTwoInput'>
|
||||||
<Input
|
<Input
|
||||||
label='نام ویژگی'
|
label='نام فیلد'
|
||||||
{...formik.getFieldProps('name')}
|
{...formik.getFieldProps('name')}
|
||||||
error_text={formik.touched.name && formik.errors.name ? formik.errors.name : ''}
|
error_text={formik.touched.name && formik.errors.name ? formik.errors.name : ''}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { extractErrorMessage } from '@/config/func'
|
|||||||
|
|
||||||
const FormBuilderList: FC = () => {
|
const FormBuilderList: FC = () => {
|
||||||
|
|
||||||
const { id } = useParams()
|
const { id, type } = useParams()
|
||||||
const { mutate: deleteField, isPending } = useDeleteField()
|
const { mutate: deleteField, isPending } = useDeleteField()
|
||||||
const { data, refetch } = useGetFields(Number(id))
|
const { data, refetch } = useGetFields(Number(id))
|
||||||
|
|
||||||
@@ -30,17 +30,17 @@ const FormBuilderList: FC = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='mt-5'>
|
<div className='mt-5'>
|
||||||
<div className='flex justify-between items-center'>
|
<div className='flex justify-between items-center'>
|
||||||
<h1 className='text-lg font-light'>ویژگی ها</h1>
|
<h1 className='text-lg font-light'>فیلد ها</h1>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
to={Paths.formBuilder.create + id}
|
to={Paths.formBuilder.create + id + `/${type}`}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
className='w-fit px-6'
|
className='w-fit px-6'
|
||||||
>
|
>
|
||||||
<div className='flex gap-1.5'>
|
<div className='flex gap-1.5'>
|
||||||
<AddSquare size={18} color='black' />
|
<AddSquare size={18} color='black' />
|
||||||
<div className='text-[13px] font-light'>ویژگی جدید</div>
|
<div className='text-[13px] font-light'>فیلد جدید</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -71,7 +71,7 @@ const FormBuilderList: FC = () => {
|
|||||||
title: 'مقادیر',
|
title: 'مقادیر',
|
||||||
render: (item) => {
|
render: (item) => {
|
||||||
return (
|
return (
|
||||||
<Link to={Paths.formBuilder.list + item.id}>
|
<Link to={Paths.formBuilder.values + item.id}>
|
||||||
<Button className='w-fit px-5'>
|
<Button className='w-fit px-5'>
|
||||||
میدیریت مقادیر
|
میدیریت مقادیر
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const FormBuilderUpdate: FC = () => {
|
|||||||
isRequired: true,
|
isRequired: true,
|
||||||
order: 1,
|
order: 1,
|
||||||
type: FieldTypeEnum.text,
|
type: FieldTypeEnum.text,
|
||||||
entityType: 'product',
|
entityType: '',
|
||||||
multiple: false
|
multiple: false
|
||||||
},
|
},
|
||||||
validationSchema: Yup.object({
|
validationSchema: Yup.object({
|
||||||
@@ -67,7 +67,7 @@ const FormBuilderUpdate: FC = () => {
|
|||||||
<div className='mt-5'>
|
<div className='mt-5'>
|
||||||
<div className='flex justify-between items-center'>
|
<div className='flex justify-between items-center'>
|
||||||
|
|
||||||
<h1 className='text-lg font-light'>ویرایش ویژگی</h1>
|
<h1 className='text-lg font-light'>ویرایش فیلد</h1>
|
||||||
<Button
|
<Button
|
||||||
className='w-fit px-6'
|
className='w-fit px-6'
|
||||||
onClick={() => formik.handleSubmit()}
|
onClick={() => formik.handleSubmit()}
|
||||||
@@ -75,7 +75,7 @@ const FormBuilderUpdate: FC = () => {
|
|||||||
>
|
>
|
||||||
<div className='flex gap-1.5'>
|
<div className='flex gap-1.5'>
|
||||||
<AddSquare size={18} color='black' />
|
<AddSquare size={18} color='black' />
|
||||||
<div className='text-[13px] font-light'>ویرایش ویژگی</div>
|
<div className='text-[13px] font-light'>ویرایش فیلد</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,7 +83,7 @@ const FormBuilderUpdate: FC = () => {
|
|||||||
<div className='mt-8 bg-white p-6 rounded-3xl flex-1'>
|
<div className='mt-8 bg-white p-6 rounded-3xl flex-1'>
|
||||||
<div className='rowTwoInput'>
|
<div className='rowTwoInput'>
|
||||||
<Input
|
<Input
|
||||||
label='نام ویژگی'
|
label='نام فیلد'
|
||||||
{...formik.getFieldProps('name')}
|
{...formik.getFieldProps('name')}
|
||||||
error_text={formik.touched.name && formik.errors.name ? formik.errors.name : ''}
|
error_text={formik.touched.name && formik.errors.name ? formik.errors.name : ''}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import { useState, type FC } from 'react'
|
||||||
|
import Button from '@/components/Button'
|
||||||
|
import { AddSquare, TickCircle } from 'iconsax-react'
|
||||||
|
import DefaulModal from '@/components/DefaulModal'
|
||||||
|
import { useFormik } from 'formik'
|
||||||
|
import type { CreateFieldValueType } from '../types/Types'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
import Input from '@/components/Input'
|
||||||
|
import { useCreateFieldValue } from '../hooks/useFormBuilderData'
|
||||||
|
import { extractErrorMessage } from '@/config/func'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
id: number,
|
||||||
|
refetch: () => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
const CreateValue: FC<Props> = ({ id, refetch }) => {
|
||||||
|
|
||||||
|
|
||||||
|
const { mutate: createValue } = useCreateFieldValue()
|
||||||
|
const [showModal, setShowModal] = useState<boolean>(false)
|
||||||
|
|
||||||
|
const formik = useFormik<CreateFieldValueType>({
|
||||||
|
initialValues: {
|
||||||
|
value: '',
|
||||||
|
order: 1
|
||||||
|
},
|
||||||
|
validationSchema: Yup.object({
|
||||||
|
value: Yup.string().required('این فیلد اجباری است')
|
||||||
|
}),
|
||||||
|
onSubmit: (values) => {
|
||||||
|
createValue({ id: id, params: values }, {
|
||||||
|
onSuccess: () => {
|
||||||
|
refetch()
|
||||||
|
setShowModal(false)
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
className='w-fit px-6'
|
||||||
|
onClick={() => setShowModal(true)}
|
||||||
|
>
|
||||||
|
<div className='flex gap-1.5'>
|
||||||
|
<AddSquare size={18} color='black' />
|
||||||
|
<div className='text-[13px] font-light'>مقدار جدید</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<DefaulModal
|
||||||
|
open={showModal}
|
||||||
|
close={() => setShowModal(false)}
|
||||||
|
isHeader
|
||||||
|
title_header='ساخت مقدار جدید'
|
||||||
|
>
|
||||||
|
<div className='mt-5'>
|
||||||
|
<Input
|
||||||
|
label='مقدار'
|
||||||
|
{...formik.getFieldProps('value')}
|
||||||
|
error_text={formik.touched.value && formik.errors.value ? formik.errors.value : ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-5'>
|
||||||
|
<Input
|
||||||
|
label='ترتیب اولویت'
|
||||||
|
{...formik.getFieldProps('order')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-6 flex justify-end'>
|
||||||
|
<Button
|
||||||
|
className='w-fit px-6'
|
||||||
|
onClick={() => formik.handleSubmit()}
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<TickCircle
|
||||||
|
size={18}
|
||||||
|
color='black'
|
||||||
|
/>
|
||||||
|
<div>ذخیره</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</DefaulModal>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CreateValue
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
import { useEffect, useState, type FC } from 'react'
|
||||||
|
import Button from '@/components/Button'
|
||||||
|
import { Edit, TickCircle } from 'iconsax-react'
|
||||||
|
import DefaulModal from '@/components/DefaulModal'
|
||||||
|
import { useFormik } from 'formik'
|
||||||
|
import type { CreateFieldValueType } from '../types/Types'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
import Input from '@/components/Input'
|
||||||
|
import { useGetFieldValueDetail, useUpdateFieldValue } from '../hooks/useFormBuilderData'
|
||||||
|
import { extractErrorMessage } from '@/config/func'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
id: number,
|
||||||
|
refetch: () => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateValue: FC<Props> = ({ id, refetch }) => {
|
||||||
|
|
||||||
|
|
||||||
|
const [showModal, setShowModal] = useState<boolean>(false)
|
||||||
|
const { mutate: updateValue } = useUpdateFieldValue()
|
||||||
|
const { data, refetch: refetchDeetail } = useGetFieldValueDetail(id, showModal)
|
||||||
|
|
||||||
|
const formik = useFormik<CreateFieldValueType>({
|
||||||
|
initialValues: {
|
||||||
|
value: '',
|
||||||
|
order: 1
|
||||||
|
},
|
||||||
|
validationSchema: Yup.object({
|
||||||
|
value: Yup.string().required('این فیلد اجباری است')
|
||||||
|
}),
|
||||||
|
onSubmit: (values) => {
|
||||||
|
updateValue({ id: id, params: values }, {
|
||||||
|
onSuccess: () => {
|
||||||
|
refetch()
|
||||||
|
refetchDeetail()
|
||||||
|
setShowModal(false)
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error))
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
formik.setValues({
|
||||||
|
value: data?.data.value,
|
||||||
|
order: data?.data.order
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [data])
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Edit
|
||||||
|
onClick={() => setShowModal(true)}
|
||||||
|
size={20}
|
||||||
|
color='#0037FF'
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DefaulModal
|
||||||
|
open={showModal}
|
||||||
|
close={() => setShowModal(false)}
|
||||||
|
isHeader
|
||||||
|
title_header='ویرایش مقدار'
|
||||||
|
>
|
||||||
|
<div className='mt-5'>
|
||||||
|
<Input
|
||||||
|
label='مقدار'
|
||||||
|
{...formik.getFieldProps('value')}
|
||||||
|
error_text={formik.touched.value && formik.errors.value ? formik.errors.value : ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-5'>
|
||||||
|
<Input
|
||||||
|
label='ترتیب اولویت'
|
||||||
|
{...formik.getFieldProps('order')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-6 flex justify-end'>
|
||||||
|
<Button
|
||||||
|
className='w-fit px-6'
|
||||||
|
onClick={() => formik.handleSubmit()}
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<TickCircle
|
||||||
|
size={18}
|
||||||
|
color='black'
|
||||||
|
/>
|
||||||
|
<div>ذخیره</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</DefaulModal>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UpdateValue
|
||||||
@@ -7,7 +7,7 @@ export type CreateFieldType = {
|
|||||||
type: FieldTypeEnum,
|
type: FieldTypeEnum,
|
||||||
order: number,
|
order: number,
|
||||||
multiple: boolean,
|
multiple: boolean,
|
||||||
entityType: 'product' | 'print'
|
entityType:string, // 'product' | 'print'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FieldType = {
|
export type FieldType = {
|
||||||
@@ -19,7 +19,7 @@ export type FieldType = {
|
|||||||
product: number,
|
product: number,
|
||||||
type: FieldTypeEnum,
|
type: FieldTypeEnum,
|
||||||
multiple: boolean,
|
multiple: boolean,
|
||||||
entityType: 'product' | 'print'
|
entityType:string, // 'product' | 'print'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FieldResponseType = BaseResponse<FieldType[]>;
|
export type FieldResponseType = BaseResponse<FieldType[]>;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import AttributeValues from '@/pages/product/attribute/AttributeValues'
|
|||||||
import FormBuilderList from '@/pages/formBuilder/List'
|
import FormBuilderList from '@/pages/formBuilder/List'
|
||||||
import FormBuilderCreate from '@/pages/formBuilder/Create'
|
import FormBuilderCreate from '@/pages/formBuilder/Create'
|
||||||
import FormBuilderUpdate from '@/pages/formBuilder/Update'
|
import FormBuilderUpdate from '@/pages/formBuilder/Update'
|
||||||
|
import FormBuilderValues from '@/pages/formBuilder/AttributeValues'
|
||||||
|
|
||||||
const MainRouter: FC = () => {
|
const MainRouter: FC = () => {
|
||||||
return (
|
return (
|
||||||
@@ -67,6 +68,7 @@ const MainRouter: FC = () => {
|
|||||||
<Route path={Paths.formBuilder.list + ':id/:type'} element={<FormBuilderList />} />
|
<Route path={Paths.formBuilder.list + ':id/:type'} element={<FormBuilderList />} />
|
||||||
<Route path={Paths.formBuilder.create + ':id/:type'} element={<FormBuilderCreate />} />
|
<Route path={Paths.formBuilder.create + ':id/:type'} element={<FormBuilderCreate />} />
|
||||||
<Route path={Paths.formBuilder.update + ':id'} element={<FormBuilderUpdate />} />
|
<Route path={Paths.formBuilder.update + ':id'} element={<FormBuilderUpdate />} />
|
||||||
|
<Route path={Paths.formBuilder.values + ':id'} element={<FormBuilderValues />} />
|
||||||
|
|
||||||
<Route path={Paths.order.list} element={<OrdersList />} />
|
<Route path={Paths.order.list} element={<OrdersList />} />
|
||||||
<Route path={Paths.features.list} element={<FeaturesList />} />
|
<Route path={Paths.features.list} element={<FeaturesList />} />
|
||||||
|
|||||||
Reference in New Issue
Block a user