refactor: replace images with file_ids in product management components

This commit is contained in:
hossein taromi 2025-07-30 14:10:28 +03:30
parent 4f4ef51ccc
commit a228605ba0
5 changed files with 35 additions and 31 deletions

View File

@ -40,11 +40,11 @@ const VariantForm: React.FC<VariantFormProps> = ({ variant, onSave, onCancel, is
product_option_id: undefined,
attributes: {},
meta: {},
images: []
file_ids: []
}
);
const [uploadedImages, setUploadedImages] = useState<ProductImage[]>(variant?.images || []);
const [uploadedImages, setUploadedImages] = useState<ProductImage[]>(variant?.file_ids || []);
const [attributes, setAttributes] = useState<Record<string, any>>(variant?.attributes || {});
const [meta, setMeta] = useState<Record<string, any>>(variant?.meta || {});
const [newAttributeKey, setNewAttributeKey] = useState('');
@ -129,7 +129,7 @@ const VariantForm: React.FC<VariantFormProps> = ({ variant, onSave, onCancel, is
...formData,
attributes,
meta,
images: uploadedImages
file_ids: uploadedImages
});
onSave(convertedData);
@ -547,9 +547,9 @@ export const VariantManager: React.FC<VariantManagerProps> = ({ variants, onChan
)}
</div>
{variant.images && variant.images.length > 0 && (
{variant.file_ids && variant.file_ids.length > 0 && (
<div className="flex gap-2 mt-3">
{variant.images.slice(0, 3).map((image, imgIndex) => (
{variant.file_ids.slice(0, 3).map((image, imgIndex) => (
<img
key={image.id}
src={image.url}
@ -557,9 +557,9 @@ export const VariantManager: React.FC<VariantManagerProps> = ({ variants, onChan
className="w-12 h-12 object-cover rounded border"
/>
))}
{variant.images.length > 3 && (
{variant.file_ids.length > 3 && (
<div className="w-12 h-12 bg-gray-100 dark:bg-gray-600 rounded border flex items-center justify-center text-xs">
+{variant.images.length - 3}
+{variant.file_ids.length - 3}
</div>
)}
</div>

View File

@ -21,7 +21,7 @@ export interface ProductVariant {
product_option_id?: number;
attributes?: Record<string, any>;
meta?: Record<string, any>;
images?: ProductImage[];
file_ids?: ProductImage[];
created_at?: string;
updated_at?: string;
}
@ -44,7 +44,7 @@ export interface Product {
price?: number;
status?: string;
attributes?: Record<string, any>;
images: ProductImage[];
file_ids: ProductImage[];
variants?: ProductVariant[];
product_variants?: ProductVariant[];
created_at: string;
@ -61,7 +61,7 @@ export interface ProductFormData {
total_sold: number;
type: number;
attributes: Record<string, any>;
images: ProductImage[];
file_ids: ProductImage[];
variants: ProductVariantFormData[];
}
@ -77,7 +77,7 @@ export interface ProductVariantFormData {
product_option_id?: number;
attributes: Record<string, any>;
meta: Record<string, any>;
images: ProductImage[];
file_ids: ProductImage[];
}
export interface ProductFilters {
@ -100,7 +100,7 @@ export interface CreateProductRequest {
total_sold: number;
type: number;
attributes?: Record<string, any>;
images?: number[];
file_ids?: number[];
variants?: CreateVariantRequest[];
}
@ -115,7 +115,7 @@ export interface UpdateProductRequest {
total_sold: number;
type: number;
attributes?: Record<string, any>;
images?: number[];
file_ids?: number[];
variants?: UpdateVariantRequest[];
}
@ -130,6 +130,7 @@ export interface CreateVariantRequest {
weight: number;
attributes?: Record<string, any>;
meta?: Record<string, any>;
file_ids?: number[];
}
export interface UpdateVariantRequest {
@ -143,6 +144,7 @@ export interface UpdateVariantRequest {
weight: number;
attributes?: Record<string, any>;
meta?: Record<string, any>;
file_ids?: number[];
}
export interface ProductsResponse {

View File

@ -184,14 +184,14 @@ const ProductDetailPage = () => {
)}
{/* تصاویر محصول */}
{product.images && product.images.length > 0 && (
{product.file_ids && product.file_ids.length > 0 && (
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
<SectionTitle className="flex items-center gap-2 mb-4">
<Image className="h-5 w-5" />
تصاویر محصول
</SectionTitle>
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{product.images.map((image, index) => (
{product.file_ids.map((image, index) => (
<div key={image.id || index} className="relative group">
<img
src={image.url}
@ -321,13 +321,13 @@ const ProductDetailPage = () => {
)}
{/* تصاویر نسخه */}
{variant.images && variant.images.length > 0 && (
{variant.file_ids && variant.file_ids.length > 0 && (
<div>
<h5 className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
تصاویر نسخه
</h5>
<div className="grid grid-cols-4 gap-2">
{variant.images.map((image, imgIndex) => (
{variant.file_ids.map((image, imgIndex) => (
<img
key={image.id || imgIndex}
src={image.url}
@ -392,7 +392,7 @@ const ProductDetailPage = () => {
</div>
)}
{product.images && (
{product.file_ids && (
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Image className="h-4 w-4 text-purple-500" />
@ -401,7 +401,7 @@ const ProductDetailPage = () => {
</span>
</div>
<span className="font-semibold text-gray-900 dark:text-gray-100">
{formatNumber(product.images.length)}
{formatNumber(product.file_ids.length)}
</span>
</div>
)}

View File

@ -31,7 +31,7 @@ const productSchema = yup.object({
category_ids: yup.array().of(yup.number()).default([]),
product_option_id: yup.number().transform(createOptionalNumberTransform()).nullable(),
attributes: yup.object().default({}),
images: yup.array().of(yup.object()).default([]),
file_ids: yup.array().of(yup.object()).default([]),
variants: yup.array().default([]),
});
@ -76,7 +76,7 @@ const ProductFormPage = () => {
category_ids: [],
product_option_id: undefined,
attributes: {},
images: [],
file_ids: [],
variants: []
}
});
@ -113,7 +113,7 @@ const ProductFormPage = () => {
product_option_id: variant.product_option_id || undefined,
attributes: variant.attributes || {},
meta: variant.meta || {},
images: variant.images || []
file_ids: variant.file_ids || []
}));
console.log('✅ Successfully processed variants:', formVariants.length);
@ -128,10 +128,10 @@ const ProductFormPage = () => {
category_ids: categoryIds,
product_option_id: product.product_option_id || undefined,
attributes: product.attributes || {},
images: product.images || [],
file_ids: product.file_ids || [],
variants: formVariants
});
setUploadedImages(product.images || []);
setUploadedImages(product.file_ids || []);
setAttributes(product.attributes || {});
}
}, [isEdit, product, reset]);
@ -148,7 +148,7 @@ const ProductFormPage = () => {
const updatedImages = [...uploadedImages, newImage];
setUploadedImages(updatedImages);
setValue('images', updatedImages, { shouldValidate: true, shouldDirty: true });
setValue('file_ids', updatedImages, { shouldValidate: true, shouldDirty: true });
return result;
} catch (error) {
@ -160,7 +160,7 @@ const ProductFormPage = () => {
const handleFileRemove = (fileId: string) => {
const updatedImages = uploadedImages.filter(img => img.id !== fileId);
setUploadedImages(updatedImages);
setValue('images', updatedImages, { shouldValidate: true, shouldDirty: true });
setValue('file_ids', updatedImages, { shouldValidate: true, shouldDirty: true });
deleteFile(fileId);
};
@ -204,7 +204,7 @@ const ProductFormPage = () => {
attributes: convertPersianNumbersInObject(attributes),
category_ids: convertedData.category_ids.length > 0 ? convertedData.category_ids : [],
product_option_id: convertedData.product_option_id || null,
images: validImageIds
file_ids: validImageIds
};
console.log('Submitting product data:', baseSubmitData);
@ -223,6 +223,7 @@ const ProductFormPage = () => {
stock_number: variant.stock_number,
weight: variant.weight,
product_option_id: variant.product_option_id || null,
file_ids: (variant.file_ids || []).map((img: any) => Number(img.id)).filter((id: number) => !isNaN(id)),
attributes: variant.attributes && Object.keys(variant.attributes).length > 0 ? variant.attributes : {},
meta: variant.meta && Object.keys(variant.meta).length > 0 ? variant.meta : {}
})) || [];
@ -247,6 +248,7 @@ const ProductFormPage = () => {
stock_number: variant.stock_number,
weight: variant.weight,
product_option_id: variant.product_option_id || null,
file_ids: (variant.file_ids || []).map((img: any) => Number(img.id)).filter((id: number) => !isNaN(id)),
attributes: variant.attributes && Object.keys(variant.attributes).length > 0 ? variant.attributes : {},
meta: variant.meta && Object.keys(variant.meta).length > 0 ? variant.meta : {}
})) || [];

View File

@ -281,9 +281,9 @@ const ProductsListPage = () => {
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center gap-3">
<div className="flex-shrink-0">
{product.images && product.images.length > 0 ? (
{product.file_ids && product.file_ids.length > 0 ? (
<img
src={product.images[0].url}
src={product.file_ids[0].url}
alt={product.name}
className="w-10 h-10 object-cover rounded"
/>
@ -352,9 +352,9 @@ const ProductsListPage = () => {
<div key={product.id} className="border border-gray-200 dark:border-gray-700 rounded-lg p-4">
<div className="flex gap-3 mb-3">
<div className="flex-shrink-0">
{product.images && product.images.length > 0 ? (
{product.file_ids && product.file_ids.length > 0 ? (
<img
src={product.images[0].url}
src={product.file_ids[0].url}
alt={product.name}
className="w-12 h-12 object-cover rounded"
/>