feat: integrate S3 storage adapter and update file upload functionality
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { saveArticle } from '@/lib/feature/article/article.external';
|
||||
import { uploadFile } from '@/lib/storage/storage.utils';
|
||||
import { FileUploadField } from '@/ui/components/internal/file-upload-field';
|
||||
import { Button } from '@/ui/components/shadcn/button';
|
||||
import {
|
||||
@@ -60,7 +61,7 @@ export const CreateArticleForm = () => {
|
||||
title: z.string().min(3).max(255),
|
||||
slug: z.string().min(3),
|
||||
description: z.string().min(10),
|
||||
coverImageUrl: z.string().url('Cover image URL must be a valid URL'),
|
||||
coverImageUrl: z.url('Cover image URL must be a valid URL'),
|
||||
content: z
|
||||
.string()
|
||||
.min(10, 'Article content must have at least 10 characters'),
|
||||
@@ -119,19 +120,27 @@ export const CreateArticleForm = () => {
|
||||
);
|
||||
|
||||
const handleCoverImageFileChange = useCallback(
|
||||
(file: File | null) => {
|
||||
async (file: File | null) => {
|
||||
if (coverImageUrlRef.current) {
|
||||
URL.revokeObjectURL(coverImageUrlRef.current);
|
||||
coverImageUrlRef.current = null;
|
||||
}
|
||||
setCoverImageFile(file);
|
||||
if (file) {
|
||||
const url = URL.createObjectURL(file);
|
||||
coverImageUrlRef.current = url;
|
||||
form.setValue('coverImageUrl', url);
|
||||
} else {
|
||||
if (!file) {
|
||||
setCoverImageFile(null);
|
||||
form.setValue('coverImageUrl', '');
|
||||
return;
|
||||
}
|
||||
const fileMetadataResult = await uploadFile(file);
|
||||
if (!fileMetadataResult.ok) {
|
||||
setCoverImageFile(null);
|
||||
form.setValue('coverImageUrl', '');
|
||||
toast((fileMetadataResult.error as Error).message);
|
||||
return;
|
||||
}
|
||||
const fileMetadata = fileMetadataResult.value;
|
||||
coverImageUrlRef.current = fileMetadata.signedUrl;
|
||||
form.setValue('coverImageUrl', fileMetadata.signedUrl);
|
||||
},
|
||||
[form]
|
||||
);
|
||||
|
||||
@@ -21,7 +21,7 @@ import React, { useCallback } from 'react';
|
||||
|
||||
export interface FileUploadFieldProps {
|
||||
file: File | null;
|
||||
onFileChange: (file: File | null) => void;
|
||||
onFileChange: (file: File | null) => Promise<void>;
|
||||
accept?: string;
|
||||
validate?: (file: File) => string | null;
|
||||
onFileReject?: (file: File, message: string) => void;
|
||||
@@ -45,7 +45,8 @@ export const FileUploadField: React.FC<FileUploadFieldProps> = ({
|
||||
const handleAccept = useCallback(
|
||||
(files: File[]) => {
|
||||
const accepted = files[0];
|
||||
if (accepted) onFileChange(accepted);
|
||||
if (!accepted) return;
|
||||
onFileChange(accepted).then(() => {});
|
||||
},
|
||||
[onFileChange]
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user