chore(env): update application version to 2.2.7 in production environment
feat(image-upload): introduce ImageUploadField component for enhanced image uploads - Added ImageUploadField component to streamline image uploads with improved UI and functionality. - Integrated file upload handling with a new file service for better management of image uploads. - Updated SectionStep component to utilize ImageUploadField for icon uploads, enhancing user experience. - Refactored TenderListFilters to use isDateRangeActive utility for improved date range filtering logic.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import api from "../axios";
|
||||
import { buildFileDownloadUrl } from "../config";
|
||||
import { API_ENDPOINTS } from "../endpoints";
|
||||
|
||||
interface IUploadFileParams {
|
||||
file: File;
|
||||
category?: string;
|
||||
tags?: string[];
|
||||
description?: string;
|
||||
onProgress?: (percent: number) => void;
|
||||
}
|
||||
|
||||
export const fileService = {
|
||||
/**
|
||||
* Uploads a binary file to the shared filestore endpoint and returns the
|
||||
* absolute, directly-loadable download URL for the stored file.
|
||||
*
|
||||
* Mirrors the two-step flow documented for CMS/marketing media: upload the
|
||||
* file, then persist the resulting URL on the entity (e.g. `card.icon`).
|
||||
*/
|
||||
uploadFile: async ({
|
||||
file,
|
||||
category,
|
||||
tags = [],
|
||||
description,
|
||||
onProgress,
|
||||
}: IUploadFileParams): Promise<string> => {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
if (category) formData.append("category", category);
|
||||
tags.forEach((tag) => formData.append("tags", tag));
|
||||
if (description) formData.append("description", description);
|
||||
|
||||
const response = await api.post(API_ENDPOINTS.FILES.UPLOAD, formData, {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
onUploadProgress: (progressEvent) => {
|
||||
if (!progressEvent.total) return;
|
||||
const percent = Math.round(
|
||||
(progressEvent.loaded * 100) / progressEvent.total,
|
||||
);
|
||||
onProgress?.(percent);
|
||||
},
|
||||
});
|
||||
|
||||
const fileId = response?.data?.file_id as string | undefined;
|
||||
if (!fileId) {
|
||||
throw new Error("No file id returned from upload");
|
||||
}
|
||||
|
||||
return buildFileDownloadUrl(fileId);
|
||||
} catch (error) {
|
||||
console.error("ERROR caught in File Service Upload File", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from "./companies-service";
|
||||
export * from "./dashboard-service";
|
||||
export * from "./file-service";
|
||||
export * from "./inquiries-service";
|
||||
export * from "./profile-service";
|
||||
export * from "./tenders-service";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import api from "../axios";
|
||||
import { buildFileDownloadUrl, extractFileId } from "../config";
|
||||
import { extractFileId } from "../config";
|
||||
import { API_ENDPOINTS } from "../endpoints";
|
||||
import { fileService } from "./file-service";
|
||||
import {
|
||||
ApiResponse,
|
||||
IAdminListResponse,
|
||||
@@ -128,34 +129,15 @@ export const userService = {
|
||||
onProgress?: (percent: number) => void;
|
||||
}) => {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
formData.append("category", "profile_images");
|
||||
formData.append("tags", "user");
|
||||
formData.append("tags", "profile");
|
||||
formData.append("description", "Admin profile image");
|
||||
|
||||
const response = await api.post(API_ENDPOINTS.FILES.UPLOAD, formData, {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
onUploadProgress: (progressEvent) => {
|
||||
if (!progressEvent.total) return;
|
||||
const percent = Math.round(
|
||||
(progressEvent.loaded * 100) / progressEvent.total,
|
||||
);
|
||||
onProgress?.(percent);
|
||||
},
|
||||
});
|
||||
|
||||
const fileId = response?.data?.file_id as string | undefined;
|
||||
if (!fileId) {
|
||||
throw new Error("No file id returned from upload");
|
||||
}
|
||||
|
||||
// Persisted on the backend as the profile image, so it must be an
|
||||
// absolute, directly-loadable URL — not the frontend `/api/proxy` path.
|
||||
return buildFileDownloadUrl(fileId);
|
||||
return fileService.uploadFile({
|
||||
file,
|
||||
category: "profile_images",
|
||||
tags: ["user", "profile"],
|
||||
description: "Admin profile image",
|
||||
onProgress,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("ERROR caught in User Service Upload Profile Image", error);
|
||||
throw error;
|
||||
|
||||
Reference in New Issue
Block a user