Files
pos-system/apps/web-client/src/services/api/storage.api.ts
2026-02-23 11:35:54 +00:00

91 lines
2.2 KiB
TypeScript

import { ApiResponse } from '@goodgo/types';
import { apiClient } from './client';
/**
* EN: Raw upload response from storage service.
* VI: Response upload thô từ storage service.
*/
interface UploadFileResult {
success: boolean;
fileId?: string;
objectKey?: string;
error?: string;
}
/**
* EN: CDN URL response payload.
* VI: Payload response URL CDN.
*/
interface CdnUrlResult {
url: string;
isCDN: boolean;
description: string;
}
/**
* EN: Normalized avatar upload response.
* VI: Response upload avatar đã chuẩn hóa.
*/
export interface UploadAvatarResult {
fileId: string;
objectKey?: string;
url: string;
}
/**
* EN: Storage API for avatar upload flow.
* VI: Storage API cho luồng upload avatar.
*/
export const storageApi = {
/**
* EN: Upload avatar as a public file and resolve CDN/fallback URL.
* VI: Upload avatar ở chế độ public và lấy URL CDN/fallback.
*/
uploadAvatar: async (file: File): Promise<ApiResponse<UploadAvatarResult>> => {
const formData = new FormData();
formData.append('file', file);
const uploadResponse = await apiClient.post<UploadFileResult>(
'/files/upload?accessLevel=public',
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
},
}
);
const uploadedFileId = uploadResponse.data?.fileId;
if (!uploadResponse.success || !uploadResponse.data?.success || !uploadedFileId) {
throw new Error(
uploadResponse.data?.error ||
uploadResponse.error?.message ||
'Failed to upload avatar'
);
}
let resolvedUrl = '';
try {
const cdnUrlResponse = await apiClient.get<CdnUrlResult>(
`/files/${uploadedFileId}/cdn-url`
);
resolvedUrl = cdnUrlResponse.data?.url ?? '';
} catch {
// EN: Fallback keeps profile update possible even if CDN URL fetch fails.
// VI: Fallback vẫn cho phép cập nhật profile nếu lấy CDN URL thất bại.
resolvedUrl = '';
}
return {
success: true,
data: {
fileId: uploadedFileId,
objectKey: uploadResponse.data.objectKey,
url: resolvedUrl,
},
timestamp: new Date().toISOString(),
};
},
};