'use client'; import { useState, useCallback } from 'react'; import { Upload, File as FileIcon, X, Eye } from 'lucide-react'; import { Button } from './ui/button'; import { Card } from './ui/card'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from './ui/dialog'; interface UploadedFile { file: File; text?: string; } interface FileUploadProps { onFilesUploaded: (files: File[]) => void; onTextExtracted?: (fileName: string, text: string) => void; } export function FileUpload({ onFilesUploaded, onTextExtracted }: FileUploadProps) { const [files, setFiles] = useState([]); const [isDragging, setIsDragging] = useState(false); const [selectedFile, setSelectedFile] = useState(null); const [isLoading, setIsLoading] = useState<{ [key: string]: boolean }>({}); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); setIsDragging(true); }, []); const handleDragLeave = useCallback((e: React.DragEvent) => { e.preventDefault(); setIsDragging(false); }, []); const processFile = async (file: File) => { setIsLoading(prev => ({ ...prev, [file.name]: true })); try { const formData = new FormData(); formData.append('file', file); const response = await fetch('/api/extract', { method: 'POST', body: formData, }); if (!response.ok) { throw new Error('Failed to extract text'); } const data = await response.json(); if (onTextExtracted) { onTextExtracted(file.name, data.text); } return data.text; } catch (error) { console.error('Error extracting text:', error); return undefined; } finally { setIsLoading(prev => ({ ...prev, [file.name]: false })); } }; const handleDrop = useCallback(async (e: React.DragEvent) => { e.preventDefault(); setIsDragging(false); const droppedFiles = Array.from(e.dataTransfer.files).filter( file => file.type === 'application/pdf' ); if (droppedFiles.length > 0) { const newFiles = droppedFiles.map(file => ({ file })); setFiles(prev => [...prev, ...newFiles]); onFilesUploaded(droppedFiles); // Process each file for (const file of droppedFiles) { const text = await processFile(file); setFiles(prev => prev.map(f => f.file.name === file.name ? { ...f, text } : f ) ); } } }, [onFilesUploaded]); const handleFileInput = useCallback(async (e: React.ChangeEvent) => { if (e.target.files) { const selectedFiles = Array.from(e.target.files).filter( file => file.type === 'application/pdf' ); if (selectedFiles.length > 0) { const newFiles = selectedFiles.map(file => ({ file })); setFiles(prev => [...prev, ...newFiles]); onFilesUploaded(selectedFiles); // Process each file for (const file of selectedFiles) { const text = await processFile(file); setFiles(prev => prev.map(f => f.file.name === file.name ? { ...f, text } : f ) ); } } } }, [onFilesUploaded]); const removeFile = useCallback((index: number) => { setFiles(prev => prev.filter((_, i) => i !== index)); }, []); return (
document.getElementById('file-upload')?.click()} >
Click to upload or drag and drop

PDF files only

{files.length > 0 && (
{files.map((uploadedFile, index) => (
{uploadedFile.file.name} {isLoading[uploadedFile.file.name] && ( Processing... )}
{uploadedFile.text && ( )}
))}
)} setSelectedFile(null)}> {selectedFile?.file.name}
{selectedFile?.text}
); }