fix
This commit is contained in:
parent
dd1d0b02b9
commit
30f1e4768a
|
|
@ -55,7 +55,7 @@ export const API_ROUTES = {
|
|||
GET_PRODUCTS: "api/v1/products",
|
||||
GET_PRODUCT: (id: string) => `api/v1/products/${id}`,
|
||||
CREATE_PRODUCT: "api/v1/products",
|
||||
UPDATE_PRODUCT: (id: string) => `api/v1/products/${id}`,
|
||||
UPDATE_PRODUCT: (id: string) => `products/${id}`,
|
||||
DELETE_PRODUCT: (id: string) => `api/v1/products/${id}`,
|
||||
GET_PRODUCT_VARIANTS: (id: string) => `api/v1/products/${id}/variants`,
|
||||
CREATE_PRODUCT_VARIANT: (id: string) => `api/v1/products/${id}/variants`,
|
||||
|
|
@ -67,6 +67,7 @@ export const API_ROUTES = {
|
|||
// Files APIs
|
||||
GET_FILES: "files",
|
||||
UPLOAD_FILE: "files",
|
||||
UPLOAD_USER_FILE: "api/v1/users/files",
|
||||
GET_FILE: (id: string) => `files/${id}`,
|
||||
UPDATE_FILE: (id: string) => `files/${id}`,
|
||||
DELETE_FILE: (id: string) => `files/${id}`,
|
||||
|
|
|
|||
|
|
@ -21,20 +21,13 @@ interface UploadResponse {
|
|||
export const useFileUpload = () => {
|
||||
return useMutation({
|
||||
mutationFn: async (file: File): Promise<{ id: string; url: string; mimeType?: string }> => {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
formData.append("name", "uploaded-file");
|
||||
|
||||
console.log("Uploading file:", file.name);
|
||||
const contentType =
|
||||
file.type && file.type.startsWith("video") ? "video/mp4" : "image/png";
|
||||
|
||||
const response = await httpPostRequest<UploadResponse>(
|
||||
APIUrlGenerator(API_ROUTES.UPLOAD_FILE),
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
}
|
||||
APIUrlGenerator(API_ROUTES.UPLOAD_USER_FILE, undefined, undefined, false),
|
||||
file,
|
||||
{ headers: { "Content-Type": contentType, Accept: "application/json" } }
|
||||
);
|
||||
|
||||
console.log("Upload response:", response);
|
||||
|
|
|
|||
|
|
@ -105,8 +105,7 @@ export const updateProduct = async (data: UpdateProductRequest) => {
|
|||
APIUrlGenerator(
|
||||
API_ROUTES.UPDATE_PRODUCT(data.id.toString()),
|
||||
undefined,
|
||||
undefined,
|
||||
false
|
||||
undefined
|
||||
),
|
||||
data
|
||||
);
|
||||
|
|
|
|||
|
|
@ -40,116 +40,122 @@ const productSchema = yup.object({
|
|||
});
|
||||
|
||||
const toPublicUrl = (img: any): ProductImage => {
|
||||
const rawUrl: string = img?.url || img?.file_url || img?.fileUrl || '';
|
||||
const serveKey: string | undefined = img?.serve_key || img?.serveKey;
|
||||
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?.file_id ?? img?.FileID ?? img).toString(),
|
||||
url,
|
||||
alt: img?.alt || img?.original_name || '',
|
||||
order: img?.order ?? 0,
|
||||
type: img?.mime_type || img?.type || img?.file_type,
|
||||
mime_type: img?.mime_type || img?.file_type,
|
||||
size: img?.size,
|
||||
};
|
||||
const rawUrl: string = img?.url || img?.file_url || img?.fileUrl || '';
|
||||
const serveKey: string | undefined = img?.serve_key || img?.serveKey;
|
||||
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?.file_id ?? img?.FileID ?? img).toString(),
|
||||
url,
|
||||
alt: img?.alt || img?.original_name || '',
|
||||
order: img?.order ?? 0,
|
||||
type: img?.mime_type || img?.type || img?.file_type,
|
||||
mime_type: img?.mime_type || img?.file_type,
|
||||
size: img?.size,
|
||||
};
|
||||
};
|
||||
|
||||
const IMAGE_MAX_SIZE = 2 * 1024 * 1024;
|
||||
const VIDEO_MAX_SIZE = 25 * 1024 * 1024;
|
||||
const VIDEO_MAX_SIZE = 50 * 1024 * 1024;
|
||||
|
||||
const isImageFile = (file: File) => file.type?.startsWith('image/');
|
||||
const isVideoFile = (file: File) => file.type?.startsWith('video/');
|
||||
|
||||
const ensureSquareImage = (file: File) =>
|
||||
new Promise<void>((resolve, reject) => {
|
||||
const url = URL.createObjectURL(file);
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
URL.revokeObjectURL(url);
|
||||
if (img.width === img.height) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error('ابعاد تصویر Explorer باید ۱ در ۱ باشد'));
|
||||
}
|
||||
};
|
||||
img.onerror = () => {
|
||||
URL.revokeObjectURL(url);
|
||||
reject(new Error('امکان بررسی ابعاد تصویر وجود ندارد'));
|
||||
};
|
||||
img.src = url;
|
||||
});
|
||||
new Promise<void>((resolve, reject) => {
|
||||
const url = URL.createObjectURL(file);
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
URL.revokeObjectURL(url);
|
||||
if (img.width === img.height) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error('ابعاد تصویر Explorer باید ۱ در ۱ باشد'));
|
||||
}
|
||||
};
|
||||
img.onerror = () => {
|
||||
URL.revokeObjectURL(url);
|
||||
reject(new Error('امکان بررسی ابعاد تصویر وجود ندارد'));
|
||||
};
|
||||
img.src = url;
|
||||
});
|
||||
|
||||
const validateMediaFile = async (file: File, options?: { requireSquare?: boolean }) => {
|
||||
if (isImageFile(file)) {
|
||||
if (file.size > IMAGE_MAX_SIZE) {
|
||||
throw new Error('حجم تصویر نباید بیشتر از ۲ مگابایت باشد');
|
||||
if (isImageFile(file)) {
|
||||
if (file.size > IMAGE_MAX_SIZE) {
|
||||
throw new Error('حجم تصویر نباید بیشتر از ۲ مگابایت باشد');
|
||||
}
|
||||
if (options?.requireSquare) {
|
||||
await ensureSquareImage(file);
|
||||
}
|
||||
} else if (isVideoFile(file)) {
|
||||
if (file.size > VIDEO_MAX_SIZE) {
|
||||
throw new Error('حجم ویدیو نباید بیشتر از ۲۵ مگابایت باشد');
|
||||
}
|
||||
} else {
|
||||
throw new Error('فقط تصاویر یا ویدیو مجاز است');
|
||||
}
|
||||
if (options?.requireSquare) {
|
||||
await ensureSquareImage(file);
|
||||
}
|
||||
} else if (isVideoFile(file)) {
|
||||
if (file.size > VIDEO_MAX_SIZE) {
|
||||
throw new Error('حجم ویدیو نباید بیشتر از ۲۵ مگابایت باشد');
|
||||
}
|
||||
} else {
|
||||
throw new Error('فقط تصاویر یا ویدیو مجاز است');
|
||||
}
|
||||
};
|
||||
|
||||
const validateExplorerFile = async (file: File) => {
|
||||
if (isImageFile(file)) {
|
||||
await ensureSquareImage(file);
|
||||
return;
|
||||
}
|
||||
if (isVideoFile(file)) {
|
||||
return;
|
||||
}
|
||||
throw new Error('فقط تصاویر یا ویدیو مجاز است');
|
||||
if (isImageFile(file)) {
|
||||
if (file.size > IMAGE_MAX_SIZE) {
|
||||
throw new Error('حجم تصویر نباید بیشتر از ۲ مگابایت باشد');
|
||||
}
|
||||
await ensureSquareImage(file);
|
||||
return;
|
||||
}
|
||||
if (isVideoFile(file)) {
|
||||
if (file.size > VIDEO_MAX_SIZE) {
|
||||
throw new Error('حجم ویدیو نباید بیشتر از ۵۰ مگابایت باشد');
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw new Error('فقط تصاویر یا ویدیو مجاز است');
|
||||
};
|
||||
|
||||
const mapExplorerFiles = (entries: any[]): ProductImage[] => {
|
||||
if (!entries || !Array.isArray(entries)) {
|
||||
return [];
|
||||
}
|
||||
return entries.map((entry, index) => {
|
||||
if (entry?.file) {
|
||||
const media = toPublicUrl(entry.file);
|
||||
return { ...media, order: index };
|
||||
if (!entries || !Array.isArray(entries)) {
|
||||
return [];
|
||||
}
|
||||
if (entry?.file_id) {
|
||||
const normalized = toPublicUrl({
|
||||
...entry,
|
||||
id: entry.file_id,
|
||||
url: entry.file_url || entry.url,
|
||||
file_url: entry.file_url || entry.url,
|
||||
mime_type: entry.mime_type || entry.file_type,
|
||||
type: entry.file_type || entry.type,
|
||||
original_name: entry.name || entry.original_name,
|
||||
});
|
||||
return { ...normalized, order: index };
|
||||
}
|
||||
if (entry?.FileID) {
|
||||
const normalized = toPublicUrl({
|
||||
...entry,
|
||||
id: entry.FileID,
|
||||
url: entry.file_url || entry.url,
|
||||
file_url: entry.file_url || entry.url,
|
||||
});
|
||||
return { ...normalized, order: index };
|
||||
}
|
||||
if (typeof entry === 'number' || typeof entry === 'string') {
|
||||
const normalized = toPublicUrl(entry);
|
||||
return { ...normalized, order: index };
|
||||
}
|
||||
const normalized = toPublicUrl(entry);
|
||||
return { ...normalized, order: index };
|
||||
});
|
||||
return entries.map((entry, index) => {
|
||||
if (entry?.file) {
|
||||
const media = toPublicUrl(entry.file);
|
||||
return { ...media, order: index };
|
||||
}
|
||||
if (entry?.file_id) {
|
||||
const normalized = toPublicUrl({
|
||||
...entry,
|
||||
id: entry.file_id,
|
||||
url: entry.file_url || entry.url,
|
||||
file_url: entry.file_url || entry.url,
|
||||
mime_type: entry.mime_type || entry.file_type,
|
||||
type: entry.file_type || entry.type,
|
||||
original_name: entry.name || entry.original_name,
|
||||
});
|
||||
return { ...normalized, order: index };
|
||||
}
|
||||
if (entry?.FileID) {
|
||||
const normalized = toPublicUrl({
|
||||
...entry,
|
||||
id: entry.FileID,
|
||||
url: entry.file_url || entry.url,
|
||||
file_url: entry.file_url || entry.url,
|
||||
});
|
||||
return { ...normalized, order: index };
|
||||
}
|
||||
if (typeof entry === 'number' || typeof entry === 'string') {
|
||||
const normalized = toPublicUrl(entry);
|
||||
return { ...normalized, order: index };
|
||||
}
|
||||
const normalized = toPublicUrl(entry);
|
||||
return { ...normalized, order: index };
|
||||
});
|
||||
};
|
||||
|
||||
const ProductFormPage = () => {
|
||||
|
|
@ -606,11 +612,11 @@ const ProductFormPage = () => {
|
|||
onUpload={handleFileUpload}
|
||||
onRemove={handleFileRemove}
|
||||
acceptedTypes={['image/*', 'video/*']}
|
||||
maxFileSize={25 * 1024 * 1024}
|
||||
maxFileSize={50 * 1024 * 1024}
|
||||
maxFiles={10}
|
||||
mode="multi"
|
||||
label=""
|
||||
description="تصاویر یا ویدیوهای محصول را آپلود کنید (حداکثر ۲ مگ برای تصویر و ۲۵ مگ برای ویدیو)"
|
||||
description="تصاویر یا ویدیوهای محصول را آپلود کنید (حداکثر ۲ مگ برای تصویر و ۵۰ مگ برای ویدیو)"
|
||||
onUploadStart={() => setIsUploading(true)}
|
||||
onUploadComplete={() => setIsUploading(false)}
|
||||
/>
|
||||
|
|
@ -667,11 +673,11 @@ const ProductFormPage = () => {
|
|||
onUpload={handleExplorerUpload}
|
||||
onRemove={handleExplorerRemove}
|
||||
acceptedTypes={['image/*', 'video/*']}
|
||||
maxFileSize={0}
|
||||
maxFileSize={50 * 1024 * 1024}
|
||||
maxFiles={5}
|
||||
mode="multi"
|
||||
label=""
|
||||
description="فایلهای Explorer را آپلود کنید (تصاویر باید مربعی باشند)"
|
||||
description="فایلهای Explorer را آپلود کنید (تصویر: ۲ مگ، ویدیو: ۵۰ مگ، تصاویر باید مربعی باشند)"
|
||||
onUploadStart={() => setIsExplorerUploading(true)}
|
||||
onUploadComplete={() => setIsExplorerUploading(false)}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue