create print form
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { type FC } from 'react'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import { useCreatePrintForm, useGetSections } from './hooks/usePrintData'
|
||||
import { useFormik } from 'formik'
|
||||
import type { CreatePrintFormType } from './types/Types'
|
||||
import ManageForms from './components/ManageForms'
|
||||
import { toast } from '@/shared/toast'
|
||||
import { extractErrorMessage } from '@/config/func'
|
||||
import Button from '@/components/Button'
|
||||
import { TickSquare } from 'iconsax-react'
|
||||
|
||||
const PrintForm: FC = () => {
|
||||
|
||||
const navigate = useNavigate()
|
||||
const { itemId, orderId } = useParams()
|
||||
const { isPending, mutate } = useCreatePrintForm()
|
||||
const { data } = useGetSections()
|
||||
|
||||
const formik = useFormik<CreatePrintFormType>({
|
||||
initialValues: {
|
||||
printAttributes: []
|
||||
},
|
||||
onSubmit: (values) => {
|
||||
mutate({ itemId: +itemId!, orderId: orderId!, params: values }, {
|
||||
onSuccess: () => {
|
||||
toast('با موفقیت ذخیره شد', 'success')
|
||||
navigate(-1)
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(extractErrorMessage(error), 'error')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return (
|
||||
<div className='mt-5'>
|
||||
<div className='flex justify-between items-center'>
|
||||
<h1 className='text-lg font-light'>فرم پرینت</h1>
|
||||
<Button
|
||||
className='w-fit px-6'
|
||||
isLoading={isPending}
|
||||
onClick={() => formik.handleSubmit()}
|
||||
>
|
||||
<div className='flex gap-1.5'>
|
||||
<TickSquare size={18} color='black' />
|
||||
<div className='text-[13px] font-light'>ذخیره</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
<div className='flex flex-col gap-5 mt-6'>
|
||||
{
|
||||
data?.data?.map((item) => {
|
||||
return (
|
||||
<div key={item.id} className='bg-white p-6 rounded-3xl'>
|
||||
<div className='font-bold'>{item.title}</div>
|
||||
<ManageForms formik={formik} attributes={item.fields} />
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PrintForm
|
||||
@@ -0,0 +1,136 @@
|
||||
import { type FC } from 'react'
|
||||
import { clx } from '@/helpers/utils'
|
||||
import Select from '@/components/Select'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import RadioGroup from '@/components/RadioGroup'
|
||||
import DatePickerComponent from '@/components/DatePicker'
|
||||
import Input from '@/components/Input'
|
||||
import Textarea from '@/components/Textarea'
|
||||
import type { FormikProps } from 'formik'
|
||||
import type { CreatePrintFormType } from '../types/Types'
|
||||
import type { EntityType } from '@/pages/formBuilder/types/Types'
|
||||
import { FieldTypeEnum } from '@/pages/formBuilder/enum/Enum'
|
||||
|
||||
type Props = {
|
||||
attributes?: EntityType[],
|
||||
formik: FormikProps<CreatePrintFormType>
|
||||
}
|
||||
|
||||
const ManageForms: FC<Props> = (props) => {
|
||||
|
||||
const { attributes, formik } = props
|
||||
|
||||
const handleChange = (attributeId: number, value: string) => {
|
||||
const attribute = formik.values.printAttributes
|
||||
const index: number = attribute.findIndex(o => o.fieldId === attributeId)
|
||||
if (index > -1) {
|
||||
attribute[index].value = value
|
||||
} else {
|
||||
attribute.push({ fieldId: attributeId, value: value })
|
||||
}
|
||||
formik.setFieldValue('attributes', attribute)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className={clx(
|
||||
'grid grid-cols-1 md:grid-cols-2 gap-6',
|
||||
!attributes && 'hidden'
|
||||
)}>
|
||||
{
|
||||
attributes?.map((item) => {
|
||||
if (item?.type === FieldTypeEnum.select)
|
||||
return (
|
||||
<div key={item.id}>
|
||||
<Select
|
||||
placeholder={`انتخاب ${item.isRequired ? '(اجباری)' : '(اختاری)'}`}
|
||||
label={item.name}
|
||||
items={item.options?.map((value) => {
|
||||
return {
|
||||
label: value.value,
|
||||
value: value.value
|
||||
}
|
||||
})}
|
||||
onChange={(e) => handleChange(item.id, e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
else if (item.type === FieldTypeEnum.checkbox)
|
||||
return (
|
||||
<div key={item.id}>
|
||||
<div className='text-sm mb-3'>{item.name}</div>
|
||||
<div className='flex gap-5 flex-wrap'>
|
||||
{
|
||||
item.options?.map((value) => {
|
||||
const object = formik.values.printAttributes.find(o => o.fieldId === item.id)
|
||||
return (
|
||||
<div key={value.id} className='flex gap-2 items-center'>
|
||||
<div>{value.value}</div>
|
||||
<Checkbox
|
||||
name={item.id + ''}
|
||||
checked={object?.value === value.value}
|
||||
onCheckedChange={(checked) => handleChange(item.id, checked ? value.value : '')}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
else if (item.type === FieldTypeEnum.radio) {
|
||||
const object = formik.values.printAttributes.find(o => o.fieldId === item.id)
|
||||
return (
|
||||
<div key={item.id}>
|
||||
<div className='text-sm mb-3'>{item.name}</div>
|
||||
<RadioGroup
|
||||
items={item.options?.map((value) => {
|
||||
return {
|
||||
label: value.value,
|
||||
value: value.value
|
||||
}
|
||||
})}
|
||||
onChange={(v) => handleChange(item.id, v)}
|
||||
selected={object?.value + '' || ''}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
else if (item.type === FieldTypeEnum.date)
|
||||
return (
|
||||
<div key={item.id}>
|
||||
<DatePickerComponent
|
||||
onChange={(date) => handleChange(item.id, date)}
|
||||
placeholder=''
|
||||
label={item.name}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
else if (item.type === FieldTypeEnum.number || item.type === FieldTypeEnum.text)
|
||||
return (
|
||||
<div key={item.id}>
|
||||
<Input
|
||||
label={item.name}
|
||||
type={item.type}
|
||||
onChange={(e) => handleChange(item.id, e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
else if (item.type === FieldTypeEnum.textarea)
|
||||
return (
|
||||
<div key={item.id} className="md:col-span-2">
|
||||
<Textarea
|
||||
label={item.name}
|
||||
onChange={(e) => handleChange(item.id, e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ManageForms
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import * as api from "../service/PrintService";
|
||||
import type { CreateSectionType } from "../types/Types";
|
||||
import type { CreatePrintFormType, CreateSectionType } from "../types/Types";
|
||||
|
||||
export const useGetSections = () => {
|
||||
return useQuery({
|
||||
@@ -55,3 +55,25 @@ export const useDeleteSection = () => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useCreatePrintForm = () => {
|
||||
return useMutation({
|
||||
mutationFn: ({
|
||||
orderId,
|
||||
itemId,
|
||||
params,
|
||||
}: {
|
||||
orderId: string;
|
||||
itemId: number;
|
||||
params: CreatePrintFormType;
|
||||
}) => api.createPrintForm(orderId, itemId, params),
|
||||
// onSuccess: (_, params) => {
|
||||
// queryClient.refetchQueries({
|
||||
// queryKey: ["sections"],
|
||||
// });
|
||||
// queryClient.refetchQueries({
|
||||
// queryKey: ["section", params.id],
|
||||
// });
|
||||
// },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import axios from "@/config/axios";
|
||||
import type {
|
||||
CreatePrintFormType,
|
||||
CreateSectionType,
|
||||
SectionDetailResponseType,
|
||||
SectionsResponseType,
|
||||
@@ -31,3 +32,15 @@ export const deleteSection = async (id: number) => {
|
||||
const { data } = await axios.delete(`/admin/section/${id}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const createPrintForm = async (
|
||||
orderId: string,
|
||||
itemId: number,
|
||||
params: CreatePrintFormType
|
||||
) => {
|
||||
const { data } = await axios.patch(
|
||||
`/admin/orders/${orderId}/item/${itemId}/print`,
|
||||
params
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { EntityType } from "@/pages/formBuilder/types/Types";
|
||||
import type { BaseResponse } from "@/shared/types/Types";
|
||||
|
||||
export type CreateSectionType = {
|
||||
@@ -10,7 +11,17 @@ export type SectionItemType = {
|
||||
id: number;
|
||||
order: number;
|
||||
title: string;
|
||||
fields: EntityType[];
|
||||
};
|
||||
|
||||
export type SectionsResponseType = BaseResponse<SectionItemType[]>;
|
||||
export type SectionDetailResponseType = BaseResponse<SectionItemType>;
|
||||
|
||||
export type PrintAttributesType = {
|
||||
fieldId: number;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type CreatePrintFormType = {
|
||||
printAttributes: PrintAttributesType[];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user