import React, { useState, useRef } from 'react'; import axios from 'axios'; import { useAuth } from './useAuth'; import { LogOut, Activity, UploadCloud, XCircle, CheckCircle2, AlertTriangle, Loader2, ThumbsUp, ThumbsDown } from 'lucide-react'; export default function Dashboard() { const { user, logout } = useAuth(); // UI State const [dragActive, setDragActive] = useState(false); const [selectedFile, setSelectedFile] = useState(null); const [previewUrl, setPreviewUrl] = useState(null); // API State const [loading, setLoading] = useState(false); const [result, setResult] = useState(null); const [error, setError] = useState(null); // Feedback State const [feedbackStatus, setFeedbackStatus] = useState(null); // null, 'loading', 'success', 'error' const inputRef = useRef(null); // --- Drag and Drop Handlers --- const handleDrag = (e) => { e.preventDefault(); e.stopPropagation(); if (e.type === "dragenter" || e.type === "dragover") { setDragActive(true); } else if (e.type === "dragleave") { setDragActive(false); } }; const handleDrop = (e) => { e.preventDefault(); e.stopPropagation(); setDragActive(false); if (e.dataTransfer.files && e.dataTransfer.files[0]) { processFile(e.dataTransfer.files[0]); } }; const handleChange = (e) => { e.preventDefault(); if (e.target.files && e.target.files[0]) { processFile(e.target.files[0]); } }; const processFile = (file) => { if (!file.type.startsWith("image/")) { setError("Please upload a valid image file (JPEG/PNG)."); return; } setError(null); setResult(null); setFeedbackStatus(null); setSelectedFile(file); setPreviewUrl(URL.createObjectURL(file)); }; const clearSelection = () => { setSelectedFile(null); setPreviewUrl(null); setResult(null); setError(null); setFeedbackStatus(null); if (inputRef.current) inputRef.current.value = ""; }; // --- API Integration --- const analyzeXRay = async () => { if (!selectedFile) return; setLoading(true); setError(null); setFeedbackStatus(null); const formData = new FormData(); formData.append("file", selectedFile); try { const API_URL = import.meta.env.VITE_API_URI; const response = await axios.post(`${API_URL}/api/v1/predict`, formData, { headers: { "Content-Type": "multipart/form-data" } }); setResult(response.data); } catch (err) { console.error("API Error:", err); setError("Failed to connect to the diagnostic engine. Is the Hugging Face space running?"); } finally { setLoading(false); } }; // --- A/B Testing Feedback Loop --- const submitFeedback = async (isAgree) => { if (!result?.record_id) return; setFeedbackStatus('loading'); try { const API_URL = import.meta.env.VITE_API_URI; // If the doctor agrees, override is FALSE. If they disagree, override is TRUE. const payload = { physician_override: !isAgree, notes: isAgree ? "Agreed with AI" : "Physician disagreed with AI diagnosis" }; await axios.put(`${API_URL}/api/v1/override/${result.record_id}`, payload); setFeedbackStatus('success'); } catch (err) { console.error("Feedback Error:", err); setFeedbackStatus('error'); } }; return (

Diagnostic Workbench

Upload a pediatric chest X-Ray for automated pneumonia screening.

{/* Left Column: Upload & Preview */}

Patient Scan

{!previewUrl ? (

Drag & Drop X-Ray image here

or click to browse files

) : (
X-Ray Preview
)} {error && (
{error}
)}
{/* Right Column: AI Results */}

AI Analysis Report

{!result && !loading ? (

Awaiting scan data...

) : loading ? (

Running DenseNet121 Inference...

) : result && (
{/* Status Badge */}
{result.prediction === 'PNEUMONIA' ? ( ) : ( )}

Detection Result

{result.prediction}

Confidence

{(result.confidence * 100).toFixed(1)}%

{/* Heatmap Image */}

Grad-CAM Explainability Heatmap

AI Heatmap
{/* The New Feedback Loop */}

Do you agree with this AI diagnosis?

{feedbackStatus === 'success' ? (
Feedback recorded. Thank you.
) : (
)} {feedbackStatus === 'error' && (

Failed to connect to database.

)}
Record ID: {result.record_id}
)}
); }