add stock

This commit is contained in:
hamid zarghami
2026-02-14 16:18:13 +03:30
parent 1c735fcebb
commit a9c8b89829
4 changed files with 61 additions and 8 deletions
+4 -2
View File
@@ -40,7 +40,9 @@ const CreateProduct: FC = () => {
images: [],
discount: 0,
isSpecialOffer: false,
order: 0
order: 0,
stock: undefined,
maxPurchaseQuantity: undefined
},
validationSchema: Yup.object().shape({
title: Yup.string().required('نام کالا الزامی است'),
@@ -61,7 +63,7 @@ const CreateProduct: FC = () => {
const variants =
values.variants.length > 0
? values.variants
: [{ value: '', price: values.price }]
: [{ value: '', price: values.price, ...(values.stock !== undefined && values.stock !== null && { stock: values.stock }) }]
const productData: CreateProductType = {
...values,
variants,
+9 -4
View File
@@ -46,7 +46,9 @@ const UpdateProduct: FC = () => {
images: [],
discount: 0,
isSpecialOffer: false,
order: 0
order: 0,
stock: undefined,
maxPurchaseQuantity: undefined
},
validationSchema: Yup.object().shape({
title: Yup.string().required('نام کالا الزامی است'),
@@ -75,9 +77,10 @@ const UpdateProduct: FC = () => {
? values.variants.map((v) => ({
...(v.id && { id: v.id }),
value: v.value ?? '',
price: v.price ?? 0
price: v.price ?? 0,
...(v.stock !== undefined && v.stock !== null && { stock: v.stock })
}))
: [{ value: '', price: values.price }]
: [{ value: '', price: values.price, ...(values.stock !== undefined && values.stock !== null && { stock: values.stock }) }]
const productData: CreateProductType = {
...values,
variants,
@@ -130,7 +133,9 @@ const UpdateProduct: FC = () => {
images: product.images || [],
discount: product.discount || 0,
isSpecialOffer: product.isSpecialOffer || false,
order: product.order ?? 0
order: product.order ?? 0,
stock: product.variants?.[0]?.stock,
maxPurchaseQuantity: product.maxPurchaseQuantity
})
setIsActive(product.isActive || false)
setIsSpecial(product.isSpecialOffer || false)
@@ -41,7 +41,7 @@ const BasicInfoSection: FC<BasicInfoSectionProps> = ({ formik, categories, initi
formik.setFieldValue('variants', [...formik.values.variants, newVariant()])
}
const updateVariant = (index: number, field: keyof ProductVariant, value: string | number) => {
const updateVariant = (index: number, field: keyof ProductVariant, value: string | number | undefined) => {
const next = [...formik.values.variants]
next[index] = { ...next[index], [field]: value }
formik.setFieldValue('variants', next)
@@ -80,6 +80,22 @@ const BasicInfoSection: FC<BasicInfoSectionProps> = ({ formik, categories, initi
/>
</div>
<div className='mt-5'>
<Input
name='maxPurchaseQuantity'
label='حداکثر تعداد خرید'
placeholder='خالی = بی‌نهایت'
type='number'
min={0}
value={formik.values.maxPurchaseQuantity === undefined || formik.values.maxPurchaseQuantity === null ? '' : formik.values.maxPurchaseQuantity}
onChange={(e) => {
const v = e.target.value
formik.setFieldValue('maxPurchaseQuantity', v === '' ? undefined : Number(v))
}}
error_text={formik.touched.maxPurchaseQuantity && formik.errors.maxPurchaseQuantity ? formik.errors.maxPurchaseQuantity : ''}
/>
</div>
{/* بخش قیمت‌گذاری و تنوع */}
<div className='mt-6 p-5 sm:p-6 rounded-2xl border border-gray-200/80 bg-gray-50/50'>
<div className='text-sm font-medium text-gray-800 mb-1'>قیمتگذاری و تنوع</div>
@@ -109,6 +125,19 @@ const BasicInfoSection: FC<BasicInfoSectionProps> = ({ formik, categories, initi
onChange={(e) => formik.setFieldValue('price', Number(e.target.value))}
error_text={formik.touched.price && formik.errors.price ? formik.errors.price : ''}
/>
<Input
name='stock'
label='موجودی'
placeholder='خالی = بی‌نهایت'
type='number'
min={0}
value={formik.values.stock === undefined || formik.values.stock === null ? '' : formik.values.stock}
onChange={(e) => {
const v = e.target.value
formik.setFieldValue('stock', v === '' ? undefined : Number(v))
}}
error_text={formik.touched.stock && formik.errors.stock ? formik.errors.stock : ''}
/>
<Input
name='discount'
label='تخفیف (تومان)'
@@ -163,7 +192,7 @@ const BasicInfoSection: FC<BasicInfoSectionProps> = ({ formik, categories, initi
</div>
<div>
<label className='block text-sm font-medium text-gray-700 mb-2'>تنوعها و قیمت هر کدام</label>
<label className='block text-sm font-medium text-gray-700 mb-2'>تنوعها، قیمت و موجودی هر کدام</label>
<div className='space-y-3'>
{formik.values.variants.map((v, index) => (
<div
@@ -184,6 +213,17 @@ const BasicInfoSection: FC<BasicInfoSectionProps> = ({ formik, categories, initi
onChange={(e) => updateVariant(index, 'price', Number(e.target.value))}
className='flex-1 min-w-0 shrink-0'
/>
<Input
placeholder='موجودی (خالی=بی‌نهایت)'
type='number'
min={0}
value={v.stock === undefined || v.stock === null ? '' : v.stock}
onChange={(e) => {
const val = e.target.value
updateVariant(index, 'stock', val === '' ? undefined : Number(val))
}}
className='flex-1 min-w-0 shrink-0'
/>
<div className='min-w-5'>
<Trash
onClick={() => removeVariant(index)}
+6
View File
@@ -4,6 +4,7 @@ export type ProductVariant = {
id?: string;
value: string;
price: number;
stock?: number;
};
export type CreateProductType = {
@@ -18,6 +19,9 @@ export type CreateProductType = {
discount: number;
isSpecialOffer: boolean;
order: number;
/** فقط در حالت بدون تنوع استفاده می‌شود */
stock?: number;
maxPurchaseQuantity?: number;
};
export type Category = {
@@ -119,6 +123,7 @@ export type Product = {
score?: number;
discount: number;
isSpecialOffer: boolean;
maxPurchaseQuantity?: number;
};
export type GetProductsParams = {
@@ -150,6 +155,7 @@ export type ProductDetails = {
score?: number | null;
discount: number;
isSpecialOffer: boolean;
maxPurchaseQuantity?: number;
};
export type PaginationMeta = {