From 3d53661c9a2621901c860301c4cafb6d4be74805 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sun, 1 Feb 2026 16:13:40 +0330 Subject: [PATCH] edit order --- .env | 2 +- src/components/Select.tsx | 2 +- src/config/Paths.tsx | 3 +- src/pages/order/EditOrder.tsx | 182 ++++++++++++ src/pages/order/List.tsx | 4 +- src/pages/order/NewOrder.tsx | 3 +- .../order/components/ManageAttributeEdit.tsx | 138 +++++++++ .../order/components/SingleOrderEdit.tsx | 272 ++++++++++++++++++ src/pages/order/hooks/useOrderData.ts | 14 +- src/pages/order/service/OrderService.ts | 8 + src/pages/order/store/OrderStore.ts | 2 +- src/pages/order/types/Types.ts | 9 +- src/router/MainRouter.tsx | 2 + 13 files changed, 631 insertions(+), 10 deletions(-) create mode 100644 src/pages/order/EditOrder.tsx create mode 100644 src/pages/order/components/ManageAttributeEdit.tsx create mode 100644 src/pages/order/components/SingleOrderEdit.tsx diff --git a/.env b/.env index 5b59c6a..71a052a 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ -VITE_API_BASE_URL = 'http://192.168.99.221:4000' +VITE_API_BASE_URL = 'http://192.168.99.220:4000' VITE_TOKEN_NAME = 'negareh_at' VITE_REFRESH_TOKEN_NAME = 'negareh_art' \ No newline at end of file diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 0dc8874..d535fbd 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -3,7 +3,7 @@ import { clx } from '../helpers/utils' import { ArrowDown2 } from 'iconsax-react' export type ItemsSelectType = { - value: string, + value: string | number, label: string, } type Props = { diff --git a/src/config/Paths.tsx b/src/config/Paths.tsx index 56cba94..5f6d05d 100644 --- a/src/config/Paths.tsx +++ b/src/config/Paths.tsx @@ -29,7 +29,8 @@ export const Paths = { order: { list: '/order/list', details: '/order/detail/', - create: '/order/create' + create: '/order/create', + edit: '/order/edit/' }, features: { list: '/features/list', diff --git a/src/pages/order/EditOrder.tsx b/src/pages/order/EditOrder.tsx new file mode 100644 index 0000000..1cb9834 --- /dev/null +++ b/src/pages/order/EditOrder.tsx @@ -0,0 +1,182 @@ +import { useEffect, useState, type FC } from 'react' +import Button from '@/components/Button' +import { TickSquare } from 'iconsax-react' +import { useOrderStore } from './store/OrderStore' +import { useGetOrderDetails, useUpdateOrder } from './hooks/useOrderData' +import { toast } from '@/shared/toast' +import { useNavigate } from 'react-router-dom' +import { Paths } from '@/config/Paths' +import { extractErrorMessage } from '@/config/func' +import { useFormik } from 'formik' +import type { CreateBaseOrderType } from '../product/types/Types' +import { OrderStatusEnum } from './enum/OrderEnum' +import * as Yup from 'yup' +import Input from '@/components/Input' +import Select from '@/components/Select' +import { useGetUsers } from '../user/hooks/useUserData' +import { useParams } from 'react-router-dom' +import EditOrderComponent from './components/SingleOrderEdit' +import type { CreateOrderType } from './types/Types' + +const EditOrder: FC = () => { + + const { id } = useParams() + const { data } = useGetOrderDetails(id!) + const navigate = useNavigate() + const { mutate: submitOrder, isPending } = useUpdateOrder() + const { data: users } = useGetUsers() + const [showOrders, setShowOrders] = useState([0]) + const { items, setItems } = useOrderStore() + + const formik = useFormik({ + initialValues: { + enableTax: true, + estimatedDays: 0, + paymentMethod: '', + status: OrderStatusEnum.CREATED, + userId: '', + }, + validationSchema: Yup.object({ + userId: Yup.string().required('این فیلد اجباری می باشد.'), + estimatedDays: Yup.number().required('این فیلد اجباری می باشد.'), + paymentMethod: Yup.string().required('این فیلد اجباری می باشد.'), + }), + onSubmit: (values) => { + values.estimatedDays = Number(values.estimatedDays) + onSubmit(values) + } + }) + + const onSubmit = (values: CreateBaseOrderType) => { + if (items.length > 0) { + const params = { + ...values, + items: items + } + submitOrder({ orderId: id!, params }, { + onSuccess: () => { + toast('سفارش با موفقیت ویرایش شد', 'success') + navigate(Paths.order.list) + }, + onError: (error) => { + toast(extractErrorMessage(error), 'error') + } + }) + } else { + toast('حداقل یک سفارش باید اضافه کنید.', 'error') + } + } + + useEffect(() => { + if (data && data?.data) { + formik.setValues({ + enableTax: data?.data?.enableTax, + estimatedDays: data?.data?.estimatedDays as number, + paymentMethod: data?.data?.paymentMethod, + status: data?.data?.status as OrderStatusEnum, + userId: data?.data?.user.id, + }) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [data]) + + useEffect(() => { + if (data && data?.data) { + + const items: CreateOrderType[] = [] + data?.data?.items.map((item) => { + items.push({ + id: item.id, + productId: item.product.id, + quantity: item.quantity, + attributes: item.attributes, + attachments: item.attachments, + discount: item.discount, + unitPrice: item.unitPrice, + description: item.description, + }) + }) + setItems(items) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [data]) + + + + return ( +
+
+

+ سفارش جدید +

+ +
+ +
+
اطلاعات اولیه
+ +
+ + + +
+ +
+ + { + return { + label: item, + value: item + } + })} + {...formik.getFieldProps('status')} + error_text={formik.errors.status && formik.touched.status ? formik.errors.status : ''} + /> +
+ +
+ + {items.map((item) => { + return ( + setShowOrders([...showOrders, showOrders.length])} key={item.productId} initialValues={item} /> + ) + })} + +
+ ) +} + +export default EditOrder \ No newline at end of file diff --git a/src/pages/order/List.tsx b/src/pages/order/List.tsx index 20b3b52..8d7b323 100644 --- a/src/pages/order/List.tsx +++ b/src/pages/order/List.tsx @@ -104,7 +104,9 @@ const OrdersList: FC = () => { > - + + + diff --git a/src/pages/order/NewOrder.tsx b/src/pages/order/NewOrder.tsx index 07c343e..a4d377e 100644 --- a/src/pages/order/NewOrder.tsx +++ b/src/pages/order/NewOrder.tsx @@ -15,6 +15,7 @@ import * as Yup from 'yup' import Input from '@/components/Input' import Select from '@/components/Select' import { useGetUsers } from '../user/hooks/useUserData' +import type { CreateFinalOrderType } from './types/Types' const NewOrder: FC = () => { @@ -45,7 +46,7 @@ const NewOrder: FC = () => { const onSubmit = (values: CreateBaseOrderType) => { if (items.length > 0) { - const params = { + const params: CreateFinalOrderType = { ...values, items: items } diff --git a/src/pages/order/components/ManageAttributeEdit.tsx b/src/pages/order/components/ManageAttributeEdit.tsx new file mode 100644 index 0000000..d5abc93 --- /dev/null +++ b/src/pages/order/components/ManageAttributeEdit.tsx @@ -0,0 +1,138 @@ +import { type FC } from 'react' +import type { CreateOrderType } from '../types/Types' +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 { FieldTypeEnum } from '@/pages/product/enum/Enum' +import type { FieldType } from '@/pages/product/types/Types' + +type Props = { + attributes?: FieldType[], + formik: FormikProps, +} + +const ManageAttributeEdit: FC = (props) => { + + const { attributes, formik } = props + + const handleChange = (attributeId: number, value: string) => { + const attribute = formik.values.attributes + const index: number = attribute.findIndex(o => o.attributeId === attributeId) + if (index > -1) { + attribute[index].value = value + } else { + attribute.push({ attributeId: attributeId, value: value }) + } + formik.setFieldValue('attributes', attribute) + } + + + return ( +
+ { + attributes?.map((item) => { + const value = formik.values.attributes.find(o => Number(o.attributeId) === Number(item.id)) + if (item?.type === FieldTypeEnum.select) + return ( +
+ handleChange(item.id, e.target.value)} + value={value?.value} + /> +
+ ) + else if (item.type === FieldTypeEnum.textarea) + return ( +
+