'use client' import { useState, useCallback, useRef } from 'react' import { processDocument, IDPAPIError } from '@/lib/api' import { IDPResponse } from '@/types/idp' interface DocumentUploadProps { onResult: (result: IDPResponse | null) => void onLoadingChange: (loading: boolean) => void isLoading?: boolean } export default function DocumentUpload({ onResult, onLoadingChange, isLoading = false }: DocumentUploadProps) { const [file, setFile] = useState(null) const [isDragging, setIsDragging] = useState(false) const [error, setError] = useState(null) const fileInputRef = useRef(null) const validateFile = (file: File): string | null => { const maxSize = 10 * 1024 * 1024 const allowedTypes = ['application/pdf', 'image/png', 'image/jpeg', 'image/jpg'] if (file.size > maxSize) { return `File too large: ${(file.size / (1024 * 1024)).toFixed(2)}MB. Max: 10MB` } if (!allowedTypes.includes(file.type)) { return `Unsupported file type. Allowed: PDF, PNG, JPEG` } return null } const handleInputChange = (e: React.ChangeEvent) => { const selectedFile = e.target.files?.[0] if (selectedFile) { handleFileChange(selectedFile) } // Reset input value to allow selecting the same file again if needed e.target.value = '' } // Auto-process when file is set const processFile = useCallback(async (fileToProcess: File) => { if (isLoading) return onLoadingChange(true) setError(null) try { const response = await processDocument(fileToProcess) onResult(response) } catch (err) { if (err instanceof IDPAPIError) { setError(err.message) } else { setError('An unexpected error occurred') } onResult(null) } finally { onLoadingChange(false) } }, [isLoading, onResult, onLoadingChange]) const handleFileChange = (selectedFile: File | null) => { if (!selectedFile) return const validationError = validateFile(selectedFile) if (validationError) { setError(validationError) setFile(null) return } setFile(selectedFile) setError(null) onResult(null) // Auto-process processFile(selectedFile) } const handleDrop = (e: React.DragEvent) => { e.preventDefault() if (isLoading) return setIsDragging(false) const droppedFile = e.dataTransfer.files[0] handleFileChange(droppedFile) } const handleDragOver = (e: React.DragEvent) => { e.preventDefault() if (isLoading) return setIsDragging(true) } const handleDragLeave = () => { setIsDragging(false) } const handleZoneClick = (e: React.MouseEvent) => { if (isLoading) return // Prevent triggering if clicking on children that stop propagation if (e.defaultPrevented) return // Reset value before clicking to ensure change event fires if (fileInputRef.current) { fileInputRef.current.value = '' fileInputRef.current.click() } } const handleUpload = useCallback(async () => { if (!file || isLoading) return onLoadingChange(true) setError(null) try { const response = await processDocument(file) onResult(response) } catch (err) { if (err instanceof IDPAPIError) { setError(err.message) } else { setError('An unexpected error occurred') } onResult(null) } finally { onLoadingChange(false) } }, [file, isLoading, onResult, onLoadingChange]) return (
{/* Upload Zone */}
{file ? (
) : (
)}

{file ? file.name : 'Click or drop file'}

{file ? `${(file.size / 1024).toFixed(2)} KB • Ready` : 'PDF, PNG, JPEG (max 10MB)'}

{file && !isLoading && ( )}
{/* Error */} {error && (

{error}

)}
) }