From 502e8c538fd3920e9a18f789ecba7d0a7d4d2b58 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sat, 21 Feb 2026 16:42:23 +0330 Subject: [PATCH] form of converet --- src/config/Paths.tsx | 1 + src/pages/invoice/Update.tsx | 14 +- .../invoice/components/InvoiceItemRow.tsx | 16 ++ src/pages/order/ConvertToOrders.tsx | 169 ++++++++++++++++++ src/pages/order/types/Types.ts | 10 ++ src/router/MainRouter.tsx | 2 + 6 files changed, 205 insertions(+), 7 deletions(-) create mode 100644 src/pages/order/ConvertToOrders.tsx diff --git a/src/config/Paths.tsx b/src/config/Paths.tsx index 7b4bd93..0aee870 100644 --- a/src/config/Paths.tsx +++ b/src/config/Paths.tsx @@ -91,4 +91,5 @@ export const Paths = { update: '/print/update/', form: '/print/form/', }, + convertToOrder: '/convert-to-order/', }; diff --git a/src/pages/invoice/Update.tsx b/src/pages/invoice/Update.tsx index fa62ff8..877745b 100644 --- a/src/pages/invoice/Update.tsx +++ b/src/pages/invoice/Update.tsx @@ -132,13 +132,13 @@ const UpdateInvoice: FC = () => { const mappedItems: CreatePreInvoiceItemType[] = invoice.items?.length > 0 ? invoice.items.map((i) => ({ - id: i.id, - productId: i.product?.id ?? "", - quantity: i.quantity ?? 1, - unitPrice: i.unitPrice ?? 0, - discount: i.discount ?? 0, - description: i.description ?? "", - })) + id: i.id, + productId: i.product?.id ?? "", + quantity: i.quantity ?? 1, + unitPrice: i.unitPrice ?? 0, + discount: i.discount ?? 0, + description: i.description ?? "", + })) : [createEmptyItem()]; setItems(mappedItems); diff --git a/src/pages/invoice/components/InvoiceItemRow.tsx b/src/pages/invoice/components/InvoiceItemRow.tsx index 12b9a89..dd1ab23 100644 --- a/src/pages/invoice/components/InvoiceItemRow.tsx +++ b/src/pages/invoice/components/InvoiceItemRow.tsx @@ -3,6 +3,8 @@ import Input from "@/components/Input"; import ProductsSelect from "@/pages/order/components/ProductsSelect"; import type { CreatePreInvoiceItemType } from "../types/Types"; import { Add, Trash } from "iconsax-react"; +import { Link } from "react-router-dom"; +import { Paths } from "@/config/Paths"; type Props = { item: CreatePreInvoiceItemType; index: number; @@ -10,6 +12,7 @@ type Props = { onAdd: () => void; onRemove: () => void; canRemove: boolean; + onConvertToOrder?: () => void; error?: Partial>; }; @@ -20,6 +23,7 @@ const InvoiceItemRow: FC = ({ onAdd, onRemove, canRemove, + onConvertToOrder, error, }) => { const total = (item.quantity || 0) * (item.unitPrice || 0) - (item.discount || 0); @@ -30,6 +34,7 @@ const InvoiceItemRow: FC = ({ return (
+
= ({ )} + {item.id && ( + + + + )}
); diff --git a/src/pages/order/ConvertToOrders.tsx b/src/pages/order/ConvertToOrders.tsx new file mode 100644 index 0000000..3fa014e --- /dev/null +++ b/src/pages/order/ConvertToOrders.tsx @@ -0,0 +1,169 @@ +import { useState, type FC } from 'react' +import { useFormik } from 'formik' +import * as Yup from 'yup' +import Input from '@/components/Input' +import Select from '@/components/Select' +import UploadBox from '@/components/UploadBox' +import Button from '@/components/Button' +import { useGetUsers } from '../user/hooks/useUserData' +import { useGetProducts } from './hooks/useOrderData' +import { useMultiUpload } from '@/pages/uploader/hooks/useUploader' +import { OrderStatusEnum } from './enum/OrderEnum' +import type { ConvertToOrderItemType } from './types/Types' + +const initialValues: ConvertToOrderItemType = { + userId: '', + invoiceItemId: '', + typeId: '', + estimatedDays: 0, + productId: '', + title: '', + attachments: [], +} + +const validationSchema = Yup.object({ + userId: Yup.string().required('انتخاب کاربر اجباری است.'), + invoiceItemId: Yup.string(), + typeId: Yup.string().required('انتخاب نوع اجباری است.'), + estimatedDays: Yup.number().required('تخمین روز اجباری است.').min(0, 'باید عدد مثبت باشد'), + productId: Yup.string().required('انتخاب محصول اجباری است.'), + title: Yup.string().required('عنوان اجباری است.'), +}) + +const ConvertToOrders: FC = () => { + const { data: users } = useGetUsers() + const { data: products } = useGetProducts() + const multiUpload = useMultiUpload() + const [attachmentFiles, setAttachmentFiles] = useState([]) + + const formik = useFormik({ + initialValues, + validationSchema, + onSubmit: async (values) => { + const attachments: string[] = [...values.attachments] + + if (attachmentFiles.length > 0) { + const result = await multiUpload.mutateAsync(attachmentFiles) + result?.data?.forEach((item) => { + attachments.push(item.url) + }) + } + + const payload: ConvertToOrderItemType = { + ...values, + estimatedDays: Number(values.estimatedDays), + attachments, + } + + console.log('Submit:', payload) + // TODO: call API + }, + }) + + return ( +
+

تبدیل به سفارش

+ +
+
+
+ ({ + label: item.title, + value: item.id, + })) ?? [] + } + label="محصول" + placeholder="انتخاب محصول" + {...formik.getFieldProps('productId')} + error_text={ + formik.touched.productId && formik.errors.productId ? formik.errors.productId : '' + } + /> +
+ +
+ + + + + +
+ +
+ +
+ +
+ +
+
+
+
+ ) +} + +export default ConvertToOrders diff --git a/src/pages/order/types/Types.ts b/src/pages/order/types/Types.ts index 62f0eaf..bd14874 100644 --- a/src/pages/order/types/Types.ts +++ b/src/pages/order/types/Types.ts @@ -176,3 +176,13 @@ export type CreateOrderType = { export interface CreateFinalOrderType extends CreateBaseOrderType { items: CreateOrderType[]; } + +export type ConvertToOrderItemType = { + userId: string; + invoiceItemId: string; + typeId: string; + estimatedDays: number; + productId: string; + title: string; + attachments: string[]; +}; diff --git a/src/router/MainRouter.tsx b/src/router/MainRouter.tsx index 02d2fcc..d73ce0a 100644 --- a/src/router/MainRouter.tsx +++ b/src/router/MainRouter.tsx @@ -47,6 +47,7 @@ import AdminList from "@/pages/admin/List"; import CreateAdmin from "@/pages/admin/Create"; import EditAdmin from "@/pages/admin/Update"; import RequestDetail from "@/pages/requests/Detail"; +import ConvertToOrders from "@/pages/order/ConvertToOrders"; const MainRouter: FC = () => { return ( @@ -87,6 +88,7 @@ const MainRouter: FC = () => { } /> } /> } /> + } /> } /> } />