change variant crud
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { type FC } from 'react'
|
||||
import PageTitle from '../../components/PageTitle'
|
||||
import { useGetProductVariants, useGetProductById } from './hooks/useProductData'
|
||||
import { useGetProductVariants } from './hooks/useProductData'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import PageLoading from '@/components/PageLoading'
|
||||
import type { ProductVariantDetailType } from './types/Types'
|
||||
@@ -13,26 +13,13 @@ const ProductVariant: FC = () => {
|
||||
|
||||
const { id } = useParams()
|
||||
const { data, isLoading, refetch } = useGetProductVariants(id!)
|
||||
const { data: productData } = useGetProductById(id!)
|
||||
|
||||
const categoryTheme = productData?.results?.product?.category?.theme
|
||||
|
||||
const getVariantColumnHeader = () => {
|
||||
switch (categoryTheme) {
|
||||
case 'Size': return 'سایز'
|
||||
case 'Color': return 'رنگ'
|
||||
case 'Meterage': return 'متریاژ'
|
||||
default: return 'تنوع'
|
||||
}
|
||||
return 'تنوع'
|
||||
}
|
||||
|
||||
const getVariantValue = (variant: ProductVariantDetailType) => {
|
||||
switch (categoryTheme) {
|
||||
case 'Size': return variant.size?.value || '-'
|
||||
case 'Color': return variant.color?.name || '-'
|
||||
case 'Meterage': return variant.meterage?.value || '-'
|
||||
default: return '-'
|
||||
}
|
||||
return variant.themeValue?.name || variant.themeValue?.value?.toString() || '-'
|
||||
}
|
||||
|
||||
const getMarketStatusVariant = (status: string) => {
|
||||
|
||||
@@ -6,8 +6,8 @@ import DatePickerComponent from '@/components/DatePicker'
|
||||
import { useState, type FC } from 'react'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { useCreateProductVariant, useGetProductById, useGetProductVariants } from '../hooks/useProductData'
|
||||
import { useGetCategoryVariants } from '@/pages/category'
|
||||
import type { CreateProductVariantRequestType } from '../types/Types'
|
||||
import { useGetThemeValues } from '@/pages/theme/hooks/useThemeData'
|
||||
import { useGetWarranties } from '@/pages/warranty/hooks/useWarrantyData'
|
||||
import { toast } from 'react-toastify'
|
||||
import { extractErrorMessage } from '@/helpers/utils'
|
||||
@@ -26,7 +26,7 @@ const CreateVariant: FC = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const { data: productData } = useGetProductById(id!)
|
||||
const { data: categoryData } = useGetCategoryVariants(productData?.results?.product?.category?._id ?? '')
|
||||
const { data: themeValues } = useGetThemeValues(productData?.results?.product?.category?.theme as string)
|
||||
const { data: variantsData, refetch: refetchVariants } = useGetProductVariants(id!)
|
||||
const createProductVariant = useCreateProductVariant()
|
||||
const { data: warrantiesData } = useGetWarranties()
|
||||
@@ -34,13 +34,15 @@ const CreateVariant: FC = () => {
|
||||
const [showModal, setShowModal] = useState<boolean>(false)
|
||||
|
||||
const categoryTheme = productData?.results?.product?.category?.theme
|
||||
const categoryVariants = categoryData?.results?.data?.category?.categoryVariants
|
||||
const isNoVariantTheme = categoryTheme === 'noColor_noSize'
|
||||
const isThemeNull = !categoryTheme
|
||||
const existingVariantsCount = variantsData?.results?.count || 0
|
||||
const canCreateVariant = !isNoVariantTheme || existingVariantsCount === 0
|
||||
const canCreateVariant = (isThemeNull || isNoVariantTheme)
|
||||
? existingVariantsCount === 0
|
||||
: true
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
variantId: isNoVariantTheme
|
||||
themeValueId: (isNoVariantTheme || isThemeNull)
|
||||
? Yup.string().optional()
|
||||
: Yup.string().required('انتخاب تنوع الزامی است'),
|
||||
warrantyId: Yup.string().required('انتخاب گارانتی الزامی است'),
|
||||
@@ -59,7 +61,7 @@ const CreateVariant: FC = () => {
|
||||
})
|
||||
|
||||
const initialValues = {
|
||||
variantId: '',
|
||||
themeValueId: '',
|
||||
warrantyId: '',
|
||||
order_limit: '',
|
||||
sellerSpecialCode: '' as string | undefined,
|
||||
@@ -76,34 +78,14 @@ const CreateVariant: FC = () => {
|
||||
}
|
||||
|
||||
const getVariantOptions = () => {
|
||||
switch (categoryTheme) {
|
||||
case 'Size':
|
||||
return categoryVariants?.sizes?.map(size => ({
|
||||
value: size._id.toString(),
|
||||
label: size.value
|
||||
return themeValues?.results?.data?.map(themeValue => ({
|
||||
value: themeValue._id,
|
||||
label: themeValue.name || themeValue.value?.toString() || '-'
|
||||
})) || []
|
||||
case 'Color':
|
||||
return categoryVariants?.colors?.map((color, index) => ({
|
||||
value: index.toString(), // استفاده از index به عنوان ID موقت
|
||||
label: color.name
|
||||
})) || []
|
||||
case 'Meterage':
|
||||
return categoryVariants?.meterages?.map(meterage => ({
|
||||
value: meterage._id.toString(),
|
||||
label: meterage.value
|
||||
})) || []
|
||||
default:
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
const getVariantLabel = () => {
|
||||
switch (categoryTheme) {
|
||||
case 'Size': return 'سایز'
|
||||
case 'Color': return 'رنگ'
|
||||
case 'Meterage': return 'متریاژ'
|
||||
default: return 'تنوع'
|
||||
}
|
||||
return categoryTheme ? 'تنوع' : 'تنوع'
|
||||
}
|
||||
|
||||
const getWarrantyOptions = () => {
|
||||
@@ -131,18 +113,11 @@ const CreateVariant: FC = () => {
|
||||
// اضافه کردن variant بر اساس theme
|
||||
let variantData: CreateProductVariantRequestType
|
||||
|
||||
if (isNoVariantTheme) {
|
||||
// در حالت noColor_noSize هیچ variantId ارسال نمیشود
|
||||
if (isNoVariantTheme || isThemeNull) {
|
||||
// در حالت noColor_noSize یا theme null هیچ themeValueId ارسال نمیشود
|
||||
variantData = baseData
|
||||
} else if (categoryTheme === 'Size') {
|
||||
variantData = { ...baseData, sizeId: parseInt(values.variantId) }
|
||||
} else if (categoryTheme === 'Color') {
|
||||
// برای رنگها از index به عنوان ID استفاده میکنیم
|
||||
variantData = { ...baseData, colorId: parseInt(values.variantId) + 1 } // +1 برای اینکه ID از 1 شروع شود
|
||||
} else if (categoryTheme === 'Meterage') {
|
||||
variantData = { ...baseData, meterageId: parseInt(values.variantId) }
|
||||
} else {
|
||||
variantData = baseData
|
||||
variantData = { ...baseData, themeValueId: values.themeValueId }
|
||||
}
|
||||
|
||||
if (!values.sellerSpecialCode) {
|
||||
@@ -160,8 +135,9 @@ const CreateVariant: FC = () => {
|
||||
toast.success('تنوع جدید با موفقیت ایجاد شد')
|
||||
// Refetch لیست تنوعها
|
||||
refetchVariants()
|
||||
// یا میتوانید از invalidateQueries استفاده کنید
|
||||
// Invalidate لیست تنوعها و جزئیات محصول
|
||||
queryClient.invalidateQueries({ queryKey: ['product-variants', id] })
|
||||
queryClient.invalidateQueries({ queryKey: ['product-by-id', id] })
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(extractErrorMessage(error))
|
||||
@@ -199,29 +175,29 @@ const CreateVariant: FC = () => {
|
||||
>
|
||||
{({ setFieldValue }) => (
|
||||
<Form className="space-y-4 w-[500px] mt-4">
|
||||
{/* انتخاب variant - فقط در صورتی که theme نوع noColor_noSize نباشد */}
|
||||
{!isNoVariantTheme && (
|
||||
{/* انتخاب variant - فقط در صورتی که theme معتبر باشد و نوع noColor_noSize نباشد */}
|
||||
{!isNoVariantTheme && !isThemeNull && (
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-700 mb-1 block">
|
||||
{getVariantLabel()}
|
||||
</label>
|
||||
<Field name="variantId">
|
||||
<Field name="themeValueId">
|
||||
{({ field }: FormikFieldProps) => (
|
||||
<Select
|
||||
{...field}
|
||||
placeholder={`انتخاب ${getVariantLabel().toLowerCase()}`}
|
||||
value={field.value}
|
||||
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setFieldValue('variantId', e.target.value)}
|
||||
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setFieldValue('themeValueId', e.target.value)}
|
||||
items={getVariantOptions()}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<ErrorMessage name="variantId" component="div" className="text-red-500 text-sm mt-1" />
|
||||
<ErrorMessage name="themeValueId" component="div" className="text-red-500 text-sm mt-1" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* پیام اطلاعرسانی برای محصولات بدون تنوع */}
|
||||
{isNoVariantTheme && (
|
||||
{(isNoVariantTheme || isThemeNull) && (
|
||||
<div className="p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<p className="text-sm text-blue-800">
|
||||
این محصول تنوع ندارد. فقط میتوانید یک نسخه از محصول ایجاد کنید.
|
||||
|
||||
@@ -12,6 +12,7 @@ import { extractErrorMessage } from '@/helpers/utils'
|
||||
import { Formik, Form, Field, ErrorMessage } from 'formik'
|
||||
import type { FieldInputProps } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
|
||||
interface FormikFieldProps {
|
||||
field: FieldInputProps<string | number | undefined>
|
||||
@@ -26,6 +27,7 @@ interface UpdateVariantProps {
|
||||
const UpdateVariant: FC<UpdateVariantProps> = ({ variant, onUpdate }) => {
|
||||
|
||||
const { id } = useParams()
|
||||
const queryClient = useQueryClient()
|
||||
const { data: variantData, isLoading, error } = useGetVariantById(id!, variant._id)
|
||||
|
||||
const updateVariant = useUpdateVariant()
|
||||
@@ -104,7 +106,12 @@ const UpdateVariant: FC<UpdateVariantProps> = ({ variant, onUpdate }) => {
|
||||
onSuccess: () => {
|
||||
setShowModal(false)
|
||||
toast.success('تنوع با موفقیت بروزرسانی شد')
|
||||
// Refetch لیست تنوعها
|
||||
onUpdate?.()
|
||||
// Invalidate لیست تنوعها و جزئیات محصول
|
||||
queryClient.invalidateQueries({ queryKey: ['product-variants', id] })
|
||||
queryClient.invalidateQueries({ queryKey: ['product-by-id', id] })
|
||||
queryClient.invalidateQueries({ queryKey: ['variant-by-id', id, variant._id] })
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(extractErrorMessage(error))
|
||||
|
||||
@@ -242,6 +242,11 @@ export type ProductVariantDetailType = {
|
||||
isFreeShip: boolean;
|
||||
isWholeSale: boolean;
|
||||
saleFormat: SaleFormatType;
|
||||
themeValue?: {
|
||||
_id: string;
|
||||
name: string;
|
||||
value: number;
|
||||
};
|
||||
size?: SizeType;
|
||||
color?: ColorType;
|
||||
meterage?: MeterageType;
|
||||
@@ -266,9 +271,7 @@ export type GetVariantByIdResponseType = {
|
||||
|
||||
export type CreateProductVariantRequestType = {
|
||||
productId: string;
|
||||
colorId?: number;
|
||||
sizeId?: number;
|
||||
meterageId?: number;
|
||||
themeValueId?: string;
|
||||
warrantyId: number;
|
||||
order_limit: number;
|
||||
sellerSpecialCode?: string;
|
||||
@@ -305,14 +308,14 @@ export type ProductCategoryType = {
|
||||
icon: string;
|
||||
imageUrl: string;
|
||||
description: string;
|
||||
theme: string;
|
||||
variants: number[];
|
||||
hierarchy: string[];
|
||||
leaf: boolean;
|
||||
parent: string;
|
||||
parent: string | null;
|
||||
deleted: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
theme: string;
|
||||
url: string;
|
||||
children: ProductCategoryType[];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user