snikhilesh's picture
Upload folder using huggingface_hub
023df37 verified
/**
* File Upload Component
* Drag-and-drop file upload interface
*/
import { useState, useCallback } from 'react';
interface FileUploadProps {
onFileUpload: (file: File) => void;
}
export function FileUpload({ onFileUpload }: FileUploadProps) {
const [isDragging, setIsDragging] = useState(false);
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const handleDragOver = useCallback((e: React.DragEvent) => {
e.preventDefault();
setIsDragging(true);
}, []);
const handleDragLeave = useCallback((e: React.DragEvent) => {
e.preventDefault();
setIsDragging(false);
}, []);
const handleDrop = useCallback((e: React.DragEvent) => {
e.preventDefault();
setIsDragging(false);
const files = Array.from(e.dataTransfer.files);
const pdfFile = files.find(file => file.type === 'application/pdf');
if (pdfFile) {
setSelectedFile(pdfFile);
} else {
alert('Please upload a PDF file');
}
}, []);
const handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files;
if (files && files.length > 0) {
const file = files[0];
if (file.type === 'application/pdf') {
setSelectedFile(file);
} else {
alert('Please upload a PDF file');
}
}
}, []);
const handleUpload = () => {
if (selectedFile) {
onFileUpload(selectedFile);
}
};
const formatFileSize = (bytes: number): string => {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
};
return (
<div className="bg-white rounded-xl shadow-lg p-8 max-w-2xl mx-auto">
<h2 className="text-2xl font-bold text-gray-900 mb-2 text-center">
Upload Medical Report
</h2>
<p className="text-gray-600 mb-6 text-center">
Upload a PDF medical report for comprehensive AI analysis
</p>
<div
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
className={`
border-2 border-dashed rounded-lg p-8 text-center transition-all
${isDragging
? 'border-blue-500 bg-blue-50'
: 'border-gray-300 hover:border-blue-400 hover:bg-gray-50'
}
`}
>
<div className="flex flex-col items-center">
<svg
className={`w-16 h-16 mb-4 ${isDragging ? 'text-blue-500' : 'text-gray-400'}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
/>
</svg>
{selectedFile ? (
<div className="space-y-3">
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
<div className="flex items-center gap-3">
<svg className="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<div className="text-left flex-1">
<p className="font-medium text-gray-900">{selectedFile.name}</p>
<p className="text-sm text-gray-500">{formatFileSize(selectedFile.size)}</p>
</div>
<button
onClick={() => setSelectedFile(null)}
className="text-gray-400 hover:text-red-500 transition-colors"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
<button
onClick={handleUpload}
className="w-full px-6 py-3 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors"
>
Start Analysis
</button>
</div>
) : (
<>
<p className="text-lg font-medium text-gray-700 mb-2">
Drop your PDF file here
</p>
<p className="text-sm text-gray-500 mb-4">
or click to browse
</p>
<label className="cursor-pointer">
<span className="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors inline-block">
Select File
</span>
<input
type="file"
accept=".pdf"
onChange={handleFileSelect}
className="hidden"
/>
</label>
</>
)}
</div>
</div>
<div className="mt-6 grid grid-cols-2 gap-4 text-sm text-gray-600">
<div className="flex items-start gap-2">
<svg className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
<span>Supports all medical report types</span>
</div>
<div className="flex items-start gap-2">
<svg className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
<span>Encrypted & secure processing</span>
</div>
<div className="flex items-start gap-2">
<svg className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
<span>Multi-modal AI analysis</span>
</div>
<div className="flex items-start gap-2">
<svg className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
<span>Real-time processing status</span>
</div>
</div>
</div>
);
}