import { useState } from "react"; import { DownloadIcon, FileTextIcon, Loader2Icon } from "lucide-react"; import { ImageWithFallback } from "./ImageWithFallback"; import { ReportModal } from "./ReportModal"; import axios from "axios"; interface ResultsPanelProps { uploadedImage: string | null; result?: any; loading?: boolean; } export function ResultsPanel({ uploadedImage, result, loading }: ResultsPanelProps) { const [showReportModal, setShowReportModal] = useState(false); const handleGenerateReport = async (formData: FormData) => { try { const baseURL = import.meta.env.MODE === "development" ? "http://127.0.0.1:7860" : window.location.origin; const response = await axios.post(`${baseURL}/reports/`, formData, { headers: { "Content-Type": "multipart/form-data" }, }); if (response.data.html_url) { // Open report in new tab window.open(`${baseURL}${response.data.html_url}`, "_blank"); } if (response.data.pdf_url) { // Open PDF in new tab when available window.open(`${baseURL}${response.data.pdf_url}`, "_blank"); } setShowReportModal(false); } catch (err: any) { console.error("Failed to generate report:", err); alert(err.response?.data?.error || "Failed to generate report"); } }; if (loading) { return (

Analyzing image...

); } if (!result) { return (
No analysis result available yet.
); } const { model_used, detections, annotated_image_url, summary, // prediction (not used here) confidence, } = result; const handleDownload = () => { if (annotated_image_url) { const link = document.createElement("a"); link.href = annotated_image_url; link.download = "analysis_result.jpg"; link.click(); } }; return (
{/* Header */}

{model_used || "Analysis Result"}

Automated Image Analysis

{annotated_image_url && ( )}
{/* Image */}
{/* Summary Section */} {summary && (

AI Summary

Abnormal Cells: {summary.abnormal_cells}
Normal Cells: {summary.normal_cells}
Average Confidence: {summary.avg_confidence?.toFixed(2)}%

{summary.ai_interpretation || "No AI interpretation available."}
)} {/* Detection list */} {detections && detections.length > 0 && (

Detected Objects

)} {/* Probability / MWT visualization */} {confidence && (

Confidence Levels

{/* If MWT, CIN, or Histopathology classifier, show a visual bar for average confidence and per-class bars */} {model_used && /mwt|cin|histopathology/i.test(model_used) ? (
{/* Average confidence bar */}
Average confidence {summary?.avg_confidence ? `${summary.avg_confidence.toFixed(2)}%` : "-"}
{/* Per-class bars */}
{Object.entries(confidence).map(([cls, val]) => { const num = Number(val as any) || 0; const pct = (num * 100); // Color coding: Positive/Malignant/High-grade = red, Negative/Benign/Low-grade = green const isNegative = cls.toLowerCase().includes("negative") || cls.toLowerCase().includes("benign") || cls.toLowerCase().includes("low-grade"); return (
{cls} {pct.toFixed(2)}%
); })}
{/* Mistral comment */}
{summary?.ai_interpretation || "No AI interpretation available."}
) : ( // Fallback display for non-MWT models
          {JSON.stringify(confidence, null, 2)}
        
)}
)} {/* Report Generation Modal */} setShowReportModal(false)} onSubmit={handleGenerateReport} analysisId={annotated_image_url || ""} analysisSummaryJson={summary ? JSON.stringify({ ...summary, model_used, confidence }) : "{}"} />
); }