'use client'; import { createGlobalState } from 'react-global-hooks'; import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react'; import { FaUpload } from 'react-icons/fa'; import { useCallback, useState } from 'react'; import { useDropzone } from 'react-dropzone'; import { apiClient } from '@/utils/api'; export interface AddSingleImageModalState { onComplete?: (imagePath: string|null) => void; } export const addSingleImageModalState = createGlobalState(null); export const openAddImageModal = (onComplete: (imagePath: string|null) => void) => { addSingleImageModalState.set({onComplete }); }; export default function AddSingleImageModal() { const [addSingleImageModalInfo, setAddSingleImageModalInfo] = addSingleImageModalState.use(); const [uploadProgress, setUploadProgress] = useState(0); const [isUploading, setIsUploading] = useState(false); const open = addSingleImageModalInfo !== null; const onCancel = () => { if (!isUploading) { setAddSingleImageModalInfo(null); } }; const onDone = (imagePath: string|null) => { if (addSingleImageModalInfo?.onComplete && !isUploading) { addSingleImageModalInfo.onComplete(imagePath); setAddSingleImageModalInfo(null); } }; const onDrop = useCallback( async (acceptedFiles: File[]) => { if (acceptedFiles.length === 0) return; setIsUploading(true); setUploadProgress(0); const formData = new FormData(); acceptedFiles.forEach(file => { formData.append('files', file); }); try { const resp = await apiClient.post(`/api/img/upload`, formData, { headers: { 'Content-Type': 'multipart/form-data', }, onUploadProgress: progressEvent => { const percentCompleted = Math.round((progressEvent.loaded * 100) / (progressEvent.total || 100)); setUploadProgress(percentCompleted); }, timeout: 0, // Disable timeout }); console.log('Upload successful:', resp.data); onDone(resp.data.files[0] || null); } catch (error) { console.error('Upload failed:', error); } finally { setIsUploading(false); setUploadProgress(0); } }, [addSingleImageModalInfo], ); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, accept: { 'image/*': ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'], }, multiple: false, }); return (
Add Control Image

{isDragActive ? 'Drop the image here...' : 'Drag & drop an image here, or click to select one'}

{isUploading && (

Uploading... {uploadProgress}%

)}
); }