Create print

This commit is contained in:
hamid zarghami
2026-02-22 12:38:19 +03:30
parent 11f8f4326b
commit f2fbd8552a
11 changed files with 137 additions and 17 deletions
+1
View File
@@ -92,4 +92,5 @@ export const Paths = {
form: '/print/form/', form: '/print/form/',
}, },
convertToOrder: '/convert-to-order', convertToOrder: '/convert-to-order',
orderPrint: '/order/print/'
}; };
+7 -2
View File
@@ -1,7 +1,7 @@
import Filters from '@/components/Filters' import Filters from '@/components/Filters'
import { type FC } from 'react' import { type FC } from 'react'
import Table from '@/components/Table' import Table from '@/components/Table'
import { Edit2, Eye, Receipt21, Setting2 } from 'iconsax-react' import { Edit2, Eye, Printer, Receipt21 } from 'iconsax-react'
import { useGetOrders } from './hooks/useOrderData' import { useGetOrders } from './hooks/useOrderData'
import moment from 'moment-jalaali' import moment from 'moment-jalaali'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
@@ -101,6 +101,12 @@ const OrdersList: FC = () => {
render: (item) => { render: (item) => {
return ( return (
<div className='flex gap-2 items-center'> <div className='flex gap-2 items-center'>
<Link title='فرم چاپ' to={Paths.orderPrint + item.id}>
<Printer
size={20}
color='black'
/>
</Link>
<Link <Link
to={Paths.order.details + item.id} to={Paths.order.details + item.id}
> >
@@ -110,7 +116,6 @@ const OrdersList: FC = () => {
<Edit2 size={20} color='#0037FF' /> <Edit2 size={20} color='#0037FF' />
</Link> </Link>
<Receipt21 size={20} color='#FF8000' /> <Receipt21 size={20} color='#FF8000' />
<Setting2 size={20} color='#00B89F' />
</div> </div>
) )
} }
+74
View File
@@ -0,0 +1,74 @@
import { type FC } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useFormik } from 'formik'
import { useGetSections } from '../print/hooks/usePrintData'
import { useSubmitOrderPrint } from './hooks/useOrderData'
import type { OrderPrintFormType } from './types/Types'
import ManageForms from '../print/components/ManageForms'
import Button from '@/components/Button'
import { TickSquare } from 'iconsax-react'
import { toast } from '@/shared/toast'
import { extractErrorMessage } from '@/config/func'
const OrderPrint: FC = () => {
const { id: orderId } = useParams()
const navigate = useNavigate()
const { data } = useGetSections()
const { isPending, mutate } = useSubmitOrderPrint()
const formik = useFormik<OrderPrintFormType>({
initialValues: {
fields: []
},
onSubmit: (values) => {
if (!orderId) return
mutate(
{ 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((section) => (
<div
key={section.id}
className='bg-white p-6 rounded-3xl'
>
<div className='font-bold'>{section.title}</div>
<ManageForms
formik={formik}
attributes={section.fields}
formFieldKey='fields'
/>
</div>
))}
</div>
</div>
)
}
export default OrderPrint
+17 -1
View File
@@ -1,6 +1,10 @@
import { useMutation, useQuery } from "@tanstack/react-query"; import { useMutation, useQuery } from "@tanstack/react-query";
import * as api from "../service/OrderService"; import * as api from "../service/OrderService";
import type { AddTicketType, CreateFinalOrderType } from "../types/Types"; import type {
AddTicketType,
CreateFinalOrderType,
OrderPrintFormType,
} from "../types/Types";
export const useGetOrders = () => { export const useGetOrders = () => {
return useQuery({ return useQuery({
@@ -97,3 +101,15 @@ export const useGetOrderItem = (id?: string) => {
enabled: !!id, enabled: !!id,
}); });
}; };
export const useSubmitOrderPrint = () => {
return useMutation({
mutationFn: ({
orderId,
params,
}: {
orderId: string;
params: OrderPrintFormType;
}) => api.submitOrderPrint(orderId, params),
});
};
+9
View File
@@ -6,6 +6,7 @@ import type {
OrderDetailResponseType, OrderDetailResponseType,
OrderItemResponseType, OrderItemResponseType,
OrderListResponseType, OrderListResponseType,
OrderPrintFormType,
TicketsResponseType, TicketsResponseType,
} from "../types/Types"; } from "../types/Types";
import type { import type {
@@ -90,3 +91,11 @@ export const converToOrder = async (params: ConvertToOrderItemType) => {
const { data } = await axios.post(`/admin/orders`, params); const { data } = await axios.post(`/admin/orders`, params);
return data; return data;
}; };
export const submitOrderPrint = async (
orderId: string,
params: OrderPrintFormType,
) => {
const { data } = await axios.post(`/admin/orders/${orderId}/print`, params);
return data;
};
+9
View File
@@ -207,3 +207,12 @@ export type ConvertToOrderItemType = {
description?: string; description?: string;
attachments: string[]; attachments: string[];
}; };
export type OrderPrintFieldType = {
fieldId: string;
value: string;
};
export type OrderPrintFormType = {
fields: OrderPrintFieldType[];
};
+2 -2
View File
@@ -14,7 +14,7 @@ const UpdateSection: FC = () => {
const { id } = useParams() const { id } = useParams()
const navigate = useNavigate() const navigate = useNavigate()
const { data } = useGetSectionsDetail(+id!) const { data } = useGetSectionsDetail(id!)
const { isPending, mutate } = useUpdateSection() const { isPending, mutate } = useUpdateSection()
const formik = useFormik<CreateSectionType>({ const formik = useFormik<CreateSectionType>({
@@ -26,7 +26,7 @@ const UpdateSection: FC = () => {
title: Yup.string().required('این فیلد اجباری می باشد.') title: Yup.string().required('این فیلد اجباری می باشد.')
}), }),
onSubmit: (values) => { onSubmit: (values) => {
mutate({ id: +id!, params: values }, { mutate({ id: id!, params: values }, {
onSuccess: () => { onSuccess: () => {
toast('با موفقیت ثبت شد', 'success') toast('با موفقیت ثبت شد', 'success')
navigate(-1) navigate(-1)
+10 -6
View File
@@ -10,25 +10,29 @@ import type { FormikProps } from 'formik'
import type { CreatePrintFormType } from '../types/Types' import type { CreatePrintFormType } from '../types/Types'
import type { EntityType } from '@/pages/formBuilder/types/Types' import type { EntityType } from '@/pages/formBuilder/types/Types'
import { FieldTypeEnum } from '@/pages/formBuilder/enum/Enum' import { FieldTypeEnum } from '@/pages/formBuilder/enum/Enum'
import type { OrderPrintFormType } from '@/pages/order/types/Types'
type Props = { type Props = {
attributes?: EntityType[], attributes?: EntityType[]
formik: FormikProps<CreatePrintFormType> formik: FormikProps<CreatePrintFormType> | FormikProps<OrderPrintFormType>
formFieldKey?: keyof CreatePrintFormType | keyof OrderPrintFormType
} }
const ManageForms: FC<Props> = (props) => { const ManageForms: FC<Props> = (props) => {
const { attributes, formik } = props const { attributes, formik, formFieldKey = 'printAttributes' } = props
const fields = ((formik.values as Record<string, { fieldId: string; value: string }[]>)[formFieldKey] ?? [])
const handleChange = (attributeId: string, value: string) => { const handleChange = (attributeId: string, value: string) => {
const attribute = formik.values.printAttributes const attribute = [...fields]
const index: number = attribute.findIndex(o => o.fieldId === attributeId) const index: number = attribute.findIndex(o => o.fieldId === attributeId)
if (index > -1) { if (index > -1) {
attribute[index].value = value attribute[index].value = value
} else { } else {
attribute.push({ fieldId: attributeId, value: value }) attribute.push({ fieldId: attributeId, value: value })
} }
formik.setFieldValue('printAttributes', attribute) formik.setFieldValue(formFieldKey as string, attribute)
} }
@@ -39,7 +43,7 @@ const ManageForms: FC<Props> = (props) => {
)}> )}>
{ {
attributes?.map((item) => { attributes?.map((item) => {
const value = formik.values.printAttributes?.find(o => o.fieldId === item.id) const value = fields.find(o => o.fieldId === item.id)
if (item?.type === FieldTypeEnum.select) if (item?.type === FieldTypeEnum.select)
return ( return (
<div key={item.id}> <div key={item.id}>
+3 -3
View File
@@ -9,7 +9,7 @@ export const useGetSections = () => {
}); });
}; };
export const useGetSectionsDetail = (id: number) => { export const useGetSectionsDetail = (id: string) => {
return useQuery({ return useQuery({
queryKey: ["section", id], queryKey: ["section", id],
queryFn: () => api.getSectionDetail(id), queryFn: () => api.getSectionDetail(id),
@@ -31,7 +31,7 @@ export const useCreateSection = () => {
export const useUpdateSection = () => { export const useUpdateSection = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: ({ id, params }: { id: number; params: CreateSectionType }) => mutationFn: ({ id, params }: { id: string; params: CreateSectionType }) =>
api.updateSection(id, params), api.updateSection(id, params),
onSuccess: (_, params) => { onSuccess: (_, params) => {
queryClient.refetchQueries({ queryClient.refetchQueries({
@@ -47,7 +47,7 @@ export const useUpdateSection = () => {
export const useDeleteSection = () => { export const useDeleteSection = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: (id: number) => api.deleteSection(id), mutationFn: (id: string) => api.deleteSection(id),
onSuccess: () => { onSuccess: () => {
queryClient.refetchQueries({ queryClient.refetchQueries({
queryKey: ["sections"], queryKey: ["sections"],
+3 -3
View File
@@ -16,19 +16,19 @@ export const createSection = async (params: CreateSectionType) => {
return data; return data;
}; };
export const updateSection = async (id: number, params: CreateSectionType) => { export const updateSection = async (id: string, params: CreateSectionType) => {
const { data } = await axios.patch(`/admin/section/${id}`, params); const { data } = await axios.patch(`/admin/section/${id}`, params);
return data; return data;
}; };
export const getSectionDetail = async (id: number) => { export const getSectionDetail = async (id: string) => {
const { data } = await axios.get<SectionDetailResponseType>( const { data } = await axios.get<SectionDetailResponseType>(
`/admin/section/${id}`, `/admin/section/${id}`,
); );
return data; return data;
}; };
export const deleteSection = async (id: number) => { export const deleteSection = async (id: string) => {
const { data } = await axios.delete(`/admin/section/${id}`); const { data } = await axios.delete(`/admin/section/${id}`);
return data; return data;
}; };
+2
View File
@@ -48,6 +48,7 @@ import CreateAdmin from "@/pages/admin/Create";
import EditAdmin from "@/pages/admin/Update"; import EditAdmin from "@/pages/admin/Update";
import RequestDetail from "@/pages/requests/Detail"; import RequestDetail from "@/pages/requests/Detail";
import ConvertToOrders from "@/pages/order/ConvertToOrders"; import ConvertToOrders from "@/pages/order/ConvertToOrders";
import OrderPrint from "@/pages/order/Print";
const MainRouter: FC = () => { const MainRouter: FC = () => {
return ( return (
@@ -89,6 +90,7 @@ const MainRouter: FC = () => {
<Route path={Paths.order.create} element={<NewOrder />} /> <Route path={Paths.order.create} element={<NewOrder />} />
<Route path={Paths.order.edit + ":id"} element={<EditOrder />} /> <Route path={Paths.order.edit + ":id"} element={<EditOrder />} />
<Route path={Paths.convertToOrder} element={<ConvertToOrders />} /> <Route path={Paths.convertToOrder} element={<ConvertToOrders />} />
<Route path={Paths.orderPrint + ':id'} element={<OrderPrint />} />
<Route path={Paths.print.list} element={<SectionList />} /> <Route path={Paths.print.list} element={<SectionList />} />
<Route path={Paths.print.create} element={<CreateSection />} /> <Route path={Paths.print.create} element={<CreateSection />} />