feat(products): fix image preview by using public file URL and normalizing edit data
This commit is contained in:
parent
2915f4ea10
commit
88ee42e434
|
|
@ -5,6 +5,25 @@ import { Button } from './Button';
|
||||||
import { FileUploader } from './FileUploader';
|
import { FileUploader } from './FileUploader';
|
||||||
import { useFileUpload, useFileDelete } from '../../hooks/useFileUpload';
|
import { useFileUpload, useFileDelete } from '../../hooks/useFileUpload';
|
||||||
import { persianToEnglish, convertPersianNumbersInObject } from '../../utils/numberUtils';
|
import { persianToEnglish, convertPersianNumbersInObject } from '../../utils/numberUtils';
|
||||||
|
import { API_GATE_WAY, API_ROUTES } from '@/constant/routes';
|
||||||
|
|
||||||
|
const toPublicUrl = (img: any): ProductImage => {
|
||||||
|
const rawUrl: string = img?.url || '';
|
||||||
|
const serveKey: string | undefined = (img && img.serve_key) || undefined;
|
||||||
|
const url = serveKey
|
||||||
|
? `${API_GATE_WAY}/${API_ROUTES.DOWNLOAD_FILE(serveKey)}`
|
||||||
|
: rawUrl?.startsWith('http')
|
||||||
|
? rawUrl
|
||||||
|
: rawUrl
|
||||||
|
? `${API_GATE_WAY}${rawUrl.startsWith('/') ? '' : '/'}${rawUrl}`
|
||||||
|
: '';
|
||||||
|
return {
|
||||||
|
id: (img?.id ?? img).toString(),
|
||||||
|
url,
|
||||||
|
alt: img?.alt || '',
|
||||||
|
order: img?.order ?? 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
interface ProductOption {
|
interface ProductOption {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -47,7 +66,7 @@ const VariantForm: React.FC<VariantFormProps> = ({ variant, onSave, onCancel, is
|
||||||
|
|
||||||
const [uploadedImages, setUploadedImages] = useState<ProductImage[]>(
|
const [uploadedImages, setUploadedImages] = useState<ProductImage[]>(
|
||||||
Array.isArray(variant?.file_ids) && variant.file_ids.length > 0 && typeof variant.file_ids[0] === 'object'
|
Array.isArray(variant?.file_ids) && variant.file_ids.length > 0 && typeof variant.file_ids[0] === 'object'
|
||||||
? variant.file_ids
|
? variant.file_ids.map(toPublicUrl)
|
||||||
: []
|
: []
|
||||||
);
|
);
|
||||||
const [variantAttributeValue, setVariantAttributeValue] = useState('');
|
const [variantAttributeValue, setVariantAttributeValue] = useState('');
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import { VariantManager } from "@/components/ui/VariantManager";
|
||||||
import { ArrowRight, Package, X, Plus, Trash2 } from "lucide-react";
|
import { ArrowRight, Package, X, Plus, Trash2 } from "lucide-react";
|
||||||
import { FormHeader, PageContainer, SectionTitle, Label } from '../../../components/ui/Typography';
|
import { FormHeader, PageContainer, SectionTitle, Label } from '../../../components/ui/Typography';
|
||||||
import { createNumberTransform, createOptionalNumberTransform, convertPersianNumbersInObject } from '../../../utils/numberUtils';
|
import { createNumberTransform, createOptionalNumberTransform, convertPersianNumbersInObject } from '../../../utils/numberUtils';
|
||||||
|
import { API_GATE_WAY, API_ROUTES } from '@/constant/routes';
|
||||||
|
|
||||||
const productSchema = yup.object({
|
const productSchema = yup.object({
|
||||||
name: yup.string().required('نام محصول الزامی است').min(2, 'نام محصول باید حداقل 2 کاراکتر باشد'),
|
name: yup.string().required('نام محصول الزامی است').min(2, 'نام محصول باید حداقل 2 کاراکتر باشد'),
|
||||||
|
|
@ -35,6 +36,24 @@ const productSchema = yup.object({
|
||||||
variants: yup.array().default([]),
|
variants: yup.array().default([]),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const toPublicUrl = (img: any): ProductImage => {
|
||||||
|
const rawUrl: string = img?.url || '';
|
||||||
|
const serveKey: string | undefined = (img && img.serve_key) || undefined;
|
||||||
|
const url = serveKey
|
||||||
|
? `${API_GATE_WAY}/${API_ROUTES.DOWNLOAD_FILE(serveKey)}`
|
||||||
|
: rawUrl?.startsWith('http')
|
||||||
|
? rawUrl
|
||||||
|
: rawUrl
|
||||||
|
? `${API_GATE_WAY}${rawUrl.startsWith('/') ? '' : '/'}${rawUrl}`
|
||||||
|
: '';
|
||||||
|
return {
|
||||||
|
id: (img?.id ?? img).toString(),
|
||||||
|
url,
|
||||||
|
alt: img?.alt || '',
|
||||||
|
order: img?.order ?? 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const ProductFormPage = () => {
|
const ProductFormPage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { id } = useParams<{ id: string }>();
|
const { id } = useParams<{ id: string }>();
|
||||||
|
|
@ -143,8 +162,9 @@ const ProductFormPage = () => {
|
||||||
variants: formVariants
|
variants: formVariants
|
||||||
});
|
});
|
||||||
const initialImages = (product.file_ids && product.file_ids.length > 0 ? product.file_ids : (product as any).files || []);
|
const initialImages = (product.file_ids && product.file_ids.length > 0 ? product.file_ids : (product as any).files || []);
|
||||||
setUploadedImages(initialImages);
|
const normalizedImages: ProductImage[] = (initialImages || []).map(toPublicUrl);
|
||||||
setValue('file_ids', initialImages, { shouldValidate: true, shouldDirty: false });
|
setUploadedImages(normalizedImages);
|
||||||
|
setValue('file_ids', normalizedImages, { shouldValidate: true, shouldDirty: false });
|
||||||
}
|
}
|
||||||
}, [isEdit, product, reset]);
|
}, [isEdit, product, reset]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue