submit order base

This commit is contained in:
hamid zarghami
2026-01-27 11:16:46 +03:30
parent bc58e6b564
commit 1f33fa7a7f
8 changed files with 94 additions and 34 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
VITE_TOKEN_NAME = 'negareh_t' VITE_TOKEN_NAME = 'negareh_t'
VITE_REFRESH_TOKEN_NAME = 'negareh_rt' VITE_REFRESH_TOKEN_NAME = 'negareh_rt'
VITE_API_BASE_URL = 'http://192.168.99.226:4000' VITE_API_BASE_URL = 'http://10.24.161.1:4000'
+1 -1
View File
@@ -26,7 +26,7 @@ const Button: FC<Props> = memo((props: Props) => {
<div className='flex gap-2 items-center'> <div className='flex gap-2 items-center'>
{ {
!props.percentage ? !props.percentage ?
<MoonLoader size={20} color='#fff' /> <MoonLoader size={20} color='#000' />
: :
<span>{props.percentage}%</span> <span>{props.percentage}%</span>
} }
+3 -1
View File
@@ -8,7 +8,9 @@ const instance = axios.create({
instance.interceptors.request.use( instance.interceptors.request.use(
(config) => { (config) => {
const token = getToken(); const token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIwMUtGWjREWDhTNVJNOFMzMDc1NVZTWUNQUSIsImlhdCI6MTc2OTQ5NzYyMSwiZXhwIjoxNzY5NDk4ODIxfQ.YK6hQh3y-msWITy2sdLMsmwBvwXC5iHa3OxtWphyWQI" ||
getToken();
if (token) { if (token) {
config.headers.Authorization = `Bearer ${token}`; config.headers.Authorization = `Bearer ${token}`;
} }
+38 -2
View File
@@ -1,14 +1,50 @@
import { type FC } from 'react' import { useState, type FC } from 'react'
import Order from './components/Order' import Order from './components/Order'
import Button from '@/components/Button'
import { TickSquare } from 'iconsax-react'
import { useOrderStore } from './store/OrderStore'
import { useSubmitOrder } from './hooks/useOrderData'
import { toast } from '@/shared/toast'
const NewOrder: FC = () => { const NewOrder: FC = () => {
const { mutate: submitOrder, isPending } = useSubmitOrder()
const [showOrders, setShowOrders] = useState([0])
const { items } = useOrderStore()
const onSubmit = () => {
if (items.length > 0) {
submitOrder(items)
} else {
toast('حداقل یک سفارش باید اضافه کنید.', 'error')
}
}
return ( return (
<div className='mt-5'> <div className='mt-5'>
<div className='justify-between items-center flex'>
<h1 className='text-lg font-light'> <h1 className='text-lg font-light'>
سفارش جدید سفارش جدید
</h1> </h1>
<Button
className='w-fit px-5'
onClick={onSubmit}
isLoading={isPending}
>
<div className='flex gap-2 items-center'>
<TickSquare size={20} color='black' />
<div>ثبت نهایی سفارش</div>
</div>
</Button>
</div>
{showOrders.map((item) => {
return (
<Order addNewItem={() => setShowOrders([...showOrders, showOrders.length])} key={item} />
)
})}
<Order />
</div> </div>
) )
} }
+42 -20
View File
@@ -5,7 +5,7 @@ import Select from '@/components/Select'
import UploadBox from '@/components/UploadBox' import UploadBox from '@/components/UploadBox'
import VoiceRecorder from '@/components/VoiceRecorder' import VoiceRecorder from '@/components/VoiceRecorder'
import { COLORS } from '@/constants/colors' import { COLORS } from '@/constants/colors'
import { AddSquare } from 'iconsax-react' import { AddSquare, Edit } from 'iconsax-react'
import ProductsSelect from './ProductsSelect' import ProductsSelect from './ProductsSelect'
import { useFormik } from 'formik' import { useFormik } from 'formik'
import * as Yup from 'yup' import * as Yup from 'yup'
@@ -13,12 +13,19 @@ import type { AttachmentsType, OrderType, ProductType } from '../type/Types'
import { useGetProducts } from '../hooks/useOrderData' import { useGetProducts } from '../hooks/useOrderData'
import ManageAttribute from './ManageAttribute' import ManageAttribute from './ManageAttribute'
import { useMultiUpload, useSingleUpload } from '@/pages/uploader/hooks/useUploader' import { useMultiUpload, useSingleUpload } from '@/pages/uploader/hooks/useUploader'
import { useAuthStore } from '../store/OrderStore' import { useOrderStore } from '../store/OrderStore'
import { clx } from '@/helpers/utils'
const Order: FC = () => { type Props = {
addNewItem: () => void,
}
const Order: FC<Props> = ({ addNewItem }) => {
const { data } = useGetProducts() const { data } = useGetProducts()
const { setItems, items } = useAuthStore() const { setItems, items } = useOrderStore()
const [indexOrder, setIndexOrder] = useState<number>(-1)
const [isEditMode, setIsEditMode] = useState<boolean>(false)
const [productSelected, setProductSelected] = useState<ProductType>() const [productSelected, setProductSelected] = useState<ProductType>()
const [voiceFile, setVoiceFile] = useState<File>() const [voiceFile, setVoiceFile] = useState<File>()
const [files, setFiles] = useState<File[]>([]) const [files, setFiles] = useState<File[]>([])
@@ -27,14 +34,15 @@ const Order: FC = () => {
const formik = useFormik<OrderType>({ const formik = useFormik<OrderType>({
initialValues: { initialValues: {
productId: 0, productId: undefined,
attachments: [], attachments: [],
quantity: undefined, quantity: undefined,
description: '', description: '',
attributes: [] attributes: []
}, },
validationSchema: Yup.object({ validationSchema: Yup.object({
productId: Yup.number().required('این فیلد اجباری می باشد'),
quantity: Yup.number().required('این فیلد اجباری می باشد'),
}), }),
onSubmit: async (values) => { onSubmit: async (values) => {
const attachments: AttachmentsType[] = [] const attachments: AttachmentsType[] = []
@@ -60,8 +68,21 @@ const Order: FC = () => {
} }
}) })
} }
if (indexOrder === -1) {
values.attachments = attachments values.attachments = attachments
setIndexOrder(items.length)
setItems([...items, values]) setItems([...items, values])
addNewItem()
setIsEditMode(true)
} else {
if (values.attachments.length) {
values.attachments = [...values.attachments, ...attachments]
}
const items_edit = [...items]
items_edit[indexOrder] = values
setItems(items_edit)
}
} }
}) })
@@ -85,19 +106,8 @@ const Order: FC = () => {
<div className='mt-6 rowTwoInput'> <div className='mt-6 rowTwoInput'>
<ProductsSelect <ProductsSelect
onChange={handleChange} onChange={handleChange}
error_text={formik.touched.productId && formik.errors.productId ? formik.errors.productId : ''}
/> />
{/* <Select
label='ویژگی'
placeholder='انتخاب'
items={productSelected?.attributes?.map((item) => {
return {
label: item.name,
value: item.id + ''
}
}) || []}
onChange={handleChangeAttribute}
/> */}
</div> </div>
<div> <div>
@@ -118,6 +128,7 @@ const Order: FC = () => {
label='تعداد' label='تعداد'
placeholder='انتخاب' placeholder='انتخاب'
{...formik.getFieldProps('quantity')} {...formik.getFieldProps('quantity')}
error_text={formik.touched.quantity && formik.errors.quantity ? formik.errors.quantity : ''}
/> />
<Input <Input
@@ -125,6 +136,8 @@ const Order: FC = () => {
readOnly={Number(formik.values.quantity) !== 0} readOnly={Number(formik.values.quantity) !== 0}
{...formik.getFieldProps('quantity')} {...formik.getFieldProps('quantity')}
type='number' type='number'
error_text={formik.touched.quantity && formik.errors.quantity ? formik.errors.quantity : ''}
/> />
</div> </div>
@@ -149,13 +162,22 @@ const Order: FC = () => {
<div className='mt-6 flex justify-end'> <div className='mt-6 flex justify-end'>
<Button <Button
className='bg-transparent border border-primary text-primary w-fit px-6' className={clx(
'bg-transparent border border-primary text-primary w-fit px-6',
isEditMode && 'bg-transparent border-[#3B82F6] text-[#3B82F6] '
)}
onClick={() => formik.handleSubmit()} onClick={() => formik.handleSubmit()}
isLoading={singleUpload.isPending || multiUpload.isPending}
> >
<div className='flex gap-1'> <div className='flex gap-1'>
{
isEditMode ?
<Edit color='#3B82F6' size={20} />
:
<AddSquare color={COLORS.primary} size={20} /> <AddSquare color={COLORS.primary} size={20} />
}
<div> <div>
اضافه کردن {isEditMode ? 'ویرایش کردن' : 'اضافه کردن'}
</div> </div>
</div> </div>
</Button> </Button>
+1 -1
View File
@@ -7,6 +7,6 @@ export const getProducts = async () => {
}; };
export const submitOrder = async (params: OrderType[]) => { export const submitOrder = async (params: OrderType[]) => {
const { data } = await axios.post(`/public/order`, params); const { data } = await axios.post(`/public/order`, { items: params });
return data; return data;
}; };
+1 -1
View File
@@ -1,7 +1,7 @@
import { create } from "zustand"; import { create } from "zustand";
import type { StoreType } from "../type/Types"; import type { StoreType } from "../type/Types";
export const useAuthStore = create<StoreType>((set) => ({ export const useOrderStore = create<StoreType>((set) => ({
items: [], items: [],
setItems(value) { setItems(value) {
set({ items: value }); set({ items: value });
+1 -1
View File
@@ -17,7 +17,7 @@ export type AttachmentsType = {
}; };
export type OrderType = { export type OrderType = {
productId: number; productId?: number;
quantity?: number; quantity?: number;
attributes: { attributes: {
attributeId: number; attributeId: number;