import { AxiosInstance } from "axios"; import { presignedAxios } from "./presignedAxios"; import { withHeaders } from "@/record-management/services/api/withHeaders"; export interface UploadKeyResponse { uploadKey: string; presignedUrl?: string; presigned?: string; fileInfo: { fileName: string; originalname: string; contentType: string; fileType: string; size: number; }; } export interface UploadAndCreateResourceParams { type: "signature" | "stamp" | "header" | "footer"; file: File; name: { am: string; en: string }; parentId: string; locale?: "am" | "en" | null; } const config = { signature: { uploadKey: "/signatures/get-file-upload-key", create: "/signatures", parentField: "employeeId", }, stamp: { uploadKey: "/employee-stamps/get-file-upload-key", create: "/employee-stamps", parentField: "employeePositionId", }, header: { uploadKey: "/headers/get-file-upload-key", create: "/headers", parentField: "unitId", }, footer: { uploadKey: "/footers/get-file-upload-key", create: "/footers", parentField: "unitId", }, } as const; /** * Get upload key and presigned URL for file upload */ export async function getUploadKey( endpoint: string, file: File, axiosInstance: AxiosInstance, positionId?: string[], recordTypeKey?: string | null, ): Promise { const payload = { fileName: file.name, originalname: file.name, contentType: file.type || "application/octet-stream", size: file.size, ...(positionId?.length ? { positionId } : {}), recordTypeKey: recordTypeKey, }; const { data } = await axiosInstance.post( endpoint, payload, { headers: withHeaders(), }, ); return data; } /** * Upload file to presigned URL */ export async function uploadToPresigned( file: File, presignedUrl: string, ): Promise { if (!presignedUrl) { throw new Error("Presigned URL is required"); } const uploadRes = await presignedAxios.put(presignedUrl, file, { headers: { "Content-Type": file.type, }, }); if (uploadRes.status < 200 || uploadRes.status >= 300) { throw new Error( `Upload failed with status ${uploadRes.status}: ${uploadRes.statusText}`, ); } } /** * Unified upload and create resource function */ export async function uploadAndCreateResource( params: UploadAndCreateResourceParams, axiosInstance: AxiosInstance, positionId?: string[], recordTypeKey?: string | null, ) { const { type, file, name, parentId, locale } = params; const typeConfig = config[type]; // 1. Get upload key and presigned URL const uploadKeyResponse = await getUploadKey( typeConfig.uploadKey, file, axiosInstance, positionId, recordTypeKey, ); const presignedUrl = uploadKeyResponse.presignedUrl || uploadKeyResponse.presigned; // 2. Upload file to presigned URL await uploadToPresigned(file, presignedUrl || ""); // 3. For header/footer: done — no separate create POST needed if (type === "header" || type === "footer") { // 4. For signature/stamp: create resource const createPayload = { fileInfo: uploadKeyResponse.fileInfo, name, [typeConfig.parentField]: parentId, positionIds: positionId, isCurrent: true, recordTypeKey: recordTypeKey, }; const { data } = await axiosInstance.post( typeConfig.create, createPayload, { headers: withHeaders(), }, ); return data; } // 4. For signature/stamp: create resource const createPayload = { fileInfo: uploadKeyResponse.fileInfo, name, [typeConfig.parentField]: parentId, ...(type === "signature" ? { isCurrent: true } : {}), ...(type === "stamp" && locale !== undefined ? { locale } : {}), }; const { data } = await axiosInstance.post(typeConfig.create, createPayload, { headers: withHeaders(), }); return data; }