import { apiFetch } from '@/lib/api'; export type PresignedUploadResponse = { key: string; url: string; expires_at: string; }; export async function getPresignedUploadUrl( filename: string, mimeType: string, ): Promise { return apiFetch('/admin/media/presign', { method: 'POST', body: JSON.stringify({ filename, mime_type: mimeType }), }); } export async function uploadFileToS3( presignedUrl: string, file: File, onProgress?: (percent: number) => void, ): Promise { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress', (event) => { if (event.lengthComputable && onProgress) { onProgress(Math.round((event.loaded / event.total) * 100)); } }); xhr.addEventListener('load', () => { if (xhr.status >= 200 && xhr.status < 300) { resolve(); } else { reject(new Error(`Upload gagal (HTTP ${xhr.status})`)); } }); xhr.addEventListener('error', () => reject(new Error('Upload gagal. Periksa koneksi internet Anda.'))); xhr.addEventListener('abort', () => reject(new Error('Upload dibatalkan.'))); xhr.open('PUT', presignedUrl); xhr.setRequestHeader('Content-Type', file.type); xhr.send(file); }); } export async function uploadFileAndGetKey( file: File, onProgress?: (percent: number) => void, ): Promise { const { key, url } = await getPresignedUploadUrl(file.name, file.type); await uploadFileToS3(url, file, onProgress); return key; }