import { useRef, useState, useEffect } from 'react'; import { useFileService } from '../hooks/useFileService'; import { FileViewer } from './FileViewer'; import { generateFilePreview } from '../utils/filePreview'; import { validateFile, formatFileSize } from '../utils/fileValidation'; import type { FileServiceConfig, FilePreview, ValidationResult } from '../types'; interface FileUploaderProps { config?: FileServiceConfig; onUploadSuccess?: (fileId: string) => void; onUploadError?: (error: string) => void; className?: string; accept?: string; multiple?: boolean; showPreviewAfterUpload?: boolean; showPreviewBeforeUpload?: boolean; } export function FileUploader({ config, onUploadSuccess, onUploadError, className = '', accept, multiple = false, showPreviewAfterUpload = true, showPreviewBeforeUpload = true, }: FileUploaderProps) { const fileInputRef = useRef(null); const [dragActive, setDragActive] = useState(false); const [uploadedFileId, setUploadedFileId] = useState(null); const [selectedFile, setSelectedFile] = useState(null); const [preview, setPreview] = useState(null); const [filePreviewUrl, setFilePreviewUrl] = useState(null); const [validation, setValidation] = useState(null); const [previewLoading, setPreviewLoading] = useState(false); const { uploadFile, loading, error } = useFileService(config); // Generate preview when file is selected useEffect(() => { if (selectedFile && showPreviewBeforeUpload) { setPreviewLoading(true); // Create object URL for preview const url = URL.createObjectURL(selectedFile); setFilePreviewUrl(url); // Generate preview metadata generateFilePreview(selectedFile) .then((previewData) => { setPreview(previewData); setPreviewLoading(false); }) .catch((err) => { console.error('Preview generation failed:', err); setPreviewLoading(false); }); // Validate file const validationResult = validateFile(selectedFile, config); setValidation(validationResult); return () => { URL.revokeObjectURL(url); }; } else { setFilePreviewUrl(null); setPreview(null); setValidation(null); } }, [selectedFile, showPreviewBeforeUpload, config]); const handleFileSelect = (files: globalThis.FileList | null) => { if (!files || files.length === 0) { setSelectedFile(null); return; } const file = files[0]; setSelectedFile(file); }; const handleFileUpload = async () => { if (!selectedFile) return; const result = await uploadFile(selectedFile); if (result.success && result.file) { setUploadedFileId(result.file.id); setSelectedFile(null); // Clear selected file after upload onUploadSuccess?.(result.file.id); } else { setUploadedFileId(null); onUploadError?.(result.error || 'Upload failed'); } }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setDragActive(false); if (e.dataTransfer.files && e.dataTransfer.files.length > 0) { handleFileSelect(e.dataTransfer.files); } }; const handleDrag = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); if (e.type === 'dragenter' || e.type === 'dragover') { setDragActive(true); } else if (e.type === 'dragleave') { setDragActive(false); } }; const handleChange = (e: React.ChangeEvent) => { if (e.target.files && e.target.files.length > 0) { handleFileSelect(e.target.files); } }; const handleUploadNew = () => { setUploadedFileId(null); setSelectedFile(null); if (fileInputRef.current) { fileInputRef.current.value = ''; } }; const handleCancel = () => { setSelectedFile(null); if (fileInputRef.current) { fileInputRef.current.value = ''; } }; const renderFilePreview = () => { if (!selectedFile || !filePreviewUrl) return null; const fileExtension = selectedFile.name.split('.').pop()?.toLowerCase() || ''; const isPdf = fileExtension === 'pdf'; const isImage = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(fileExtension); const isText = ['txt', 'md', 'json', 'xml', 'html', 'css', 'js', 'ts', 'tsx', 'jsx'].includes(fileExtension); const isWord = ['doc', 'docx'].includes(fileExtension); const isCsv = fileExtension === 'csv'; return (

File Preview: {selectedFile.name}

Size: {formatFileSize(selectedFile.size)} Type: {selectedFile.type || fileExtension} {preview?.pages && Pages: {preview.pages}} {preview?.sheets && preview.sheets.length > 0 && ( Sheets: {preview.sheets.join(', ')} )}
{previewLoading && (

Generating preview...

)}
{isPdf && filePreviewUrl && (