feat: restore profile settings API integration
Co-authored-by: Velik <hongochai10@users.noreply.github.com>
This commit is contained in:
90
apps/web-client/src/services/api/storage.api.ts
Normal file
90
apps/web-client/src/services/api/storage.api.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
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(),
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user