feat(blog): add queued asset uploads

This commit is contained in:
2026-06-12 21:35:29 +03:30
parent 1e302d2aa2
commit eb28a00abd
2 changed files with 321 additions and 64 deletions

View File

@@ -562,6 +562,52 @@ class ApiClient {
return response.json() as Promise<Types.PostAssetSchema>;
}
uploadBlogPostAssetWithProgress(
postId: number,
file: File,
data: { title?: string; alt_text?: string; caption?: string } = {},
onProgress?: (progress: number) => void,
) {
const formData = new FormData();
formData.append('file', file);
formData.append('title', data.title ?? '');
formData.append('alt_text', data.alt_text ?? '');
formData.append('caption', data.caption ?? '');
const token = this.getStorageValue('access_token');
return new Promise<Types.PostAssetSchema>((resolve, reject) => {
const request = new XMLHttpRequest();
request.open('POST', `${this.baseUrl}/api/blog/admin/posts/${postId}/assets`);
if (token) {
request.setRequestHeader('Authorization', `Bearer ${token}`);
}
request.upload.onprogress = (event) => {
if (!event.lengthComputable) return;
onProgress?.(Math.round((event.loaded / event.total) * 100));
};
request.onload = () => {
let body: (Types.PostAssetSchema & ApiErrorBody) | null = null;
try {
body = request.responseText ? JSON.parse(request.responseText) as Types.PostAssetSchema & ApiErrorBody : null;
} catch {
body = null;
}
if (request.status >= 200 && request.status < 300 && body) {
onProgress?.(100);
resolve(body);
return;
}
reject(new Error(body?.error || body?.detail || 'Asset upload failed'));
};
request.onerror = () => reject(new Error('Asset upload failed'));
request.send(formData);
});
}
async deleteBlogPostAsset(postId: number, assetId: number) {
return this.request<Types.MessageSchema>(`/api/blog/admin/posts/${postId}/assets/${assetId}`, {
method: 'DELETE',