Pathora / frontend /src /components /UploadSection.tsx
malavikapradeep2001's picture
Initial Space
bf5da6b
raw
history blame
5.7 kB
import React, { useRef } from 'react';
import { UploadIcon } from 'lucide-react';
interface UploadSectionProps {
selectedTest: string;
uploadedImage: string | null;
setUploadedImage: (image: string | null) => void;
selectedModel: string;
setSelectedModel: (model: string) => void;
onAnalyze: () => void;
}
export function UploadSection({
selectedTest,
uploadedImage,
setUploadedImage,
selectedModel,
setSelectedModel,
onAnalyze,
}: UploadSectionProps) {
const fileInputRef = useRef<HTMLInputElement>(null);
const modelOptions = {
cytology: [
{ value: 'mwt', label: 'MWT' },
{ value: 'yolo', label: 'YOLOv8' },
],
colposcopy: [
{ value: 'cin', label: 'Logistic-Colpo' },
],
histopathology: [
{ value: 'histopathology', label: 'Path Foundation Model' },
],
};
const sampleImages = {
cytology: [
"/cyto/cyt1.jpg",
"/cyto/cyt2.png",
"/cyto/cyt3.png",
],
colposcopy: [
"/colpo/colp1.jpg",
"/colpo/colp2.jpg",
"/colpo/colp3.jpg",
],
histopathology: [
"/histo/hist1.png",
"/histo/hist2.png",
"/histo/hist3.jpg",
],
};
const currentModels =
modelOptions[selectedTest as keyof typeof modelOptions] || [];
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = (event) => {
setUploadedImage(event.target?.result as string);
};
reader.readAsDataURL(file);
}
};
const handleDrop = (e: React.DragEvent) => {
e.preventDefault();
const file = e.dataTransfer.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (event) => {
setUploadedImage(event.target?.result as string);
};
reader.readAsDataURL(file);
}
};
// Handle click on sample image
const handleSampleClick = (imgUrl: string) => {
setUploadedImage(imgUrl);
};
return (
<div className="bg-white rounded-lg shadow-sm p-6">
<h2 className="text-2xl font-semibold text-gray-900 mb-6">
Upload an image of a tissue sample
</h2>
{/* Upload Area */}
<div
onDrop={handleDrop}
onDragOver={(e) => e.preventDefault()}
onClick={() => fileInputRef.current?.click()}
className="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center cursor-pointer hover:border-blue-400 transition-colors"
>
<input
ref={fileInputRef}
type="file"
accept="image/*"
onChange={handleFileChange}
className="hidden"
/>
<div className="flex flex-col items-center">
<div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4">
<UploadIcon className="w-8 h-8 text-gray-400" />
</div>
{uploadedImage ? (
<>
<p className="text-green-600 font-medium mb-2">
Image uploaded successfully!
</p>
<p className="text-sm text-gray-500 mb-4">
Click to upload a different image
</p>
<div className="w-32 h-32 rounded-lg overflow-hidden border border-gray-200">
<img
src={uploadedImage}
alt="Uploaded sample"
className="w-full h-full object-cover"
/>
</div>
</>
) : (
<p className="text-gray-600">Drag and drop or click to upload</p>
)}
</div>
</div>
{/* Model Selection */}
<div className="mt-6">
<label className="block text-sm font-medium text-gray-700 mb-2">
Select Analysis Model:
</label>
<select
value={selectedModel}
onChange={(e) => setSelectedModel(e.target.value)}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="">Choose a model...</option>
{currentModels.map((model) => (
<option key={model.value} value={model.value}>
{model.label}
</option>
))}
</select>
</div>
{/* Analyze Button */}
<button
onClick={onAnalyze}
disabled={!uploadedImage || !selectedModel}
className="w-full mt-6 bg-blue-600 text-white py-3 rounded-lg font-medium hover:bg-blue-700 disabled:bg-gray-300 disabled:cursor-not-allowed transition-colors"
>
Analyze
</button>
{/* Separator */}
<hr className="my-8 border-gray-200" />
{/* Sample Images Section */}
<div>
<h3 className="text-lg font-semibold text-gray-800 mb-4">
Samples Images
</h3>
<div className="flex flex-wrap gap-4">
{(sampleImages[selectedTest as keyof typeof sampleImages] || []).map(
(img, index) => (
<div
key={index}
className={`w-20 h-20 rounded-lg border-2 cursor-pointer transition-transform hover:scale-105 hover:border-blue-500 overflow-hidden ${
uploadedImage === img ? 'border-blue-600' : 'border-gray-300'
}`}
onClick={() => handleSampleClick(img)}
>
<img
src={img}
alt={`Sample ${index + 1}`}
className="w-full h-full object-cover"
/>
</div>
)
)}
</div>
</div>
</div>
);
}