import { motion } from 'framer-motion'; import { CheckCircle2, XCircle, TrendingUp, Info } from 'lucide-react'; interface ImageReportPanelProps { reasons?: string[]; perGeneratorAccuracy?: Record; verdict: string; } const GENERATOR_COLORS: Record = { 'ChatGPT': '#22c55e', 'Adobe': '#22c55e', 'ProGAN': '#f97316', 'Stable': '#eab308', 'SDXL': '#f97316', 'Midjourney': '#ef4444', 'FLUX': '#ef4444', }; function getGeneratorColor(name: string): string { const key = Object.keys(GENERATOR_COLORS).find(k => name.includes(k)); return key ? GENERATOR_COLORS[key] : '#94a3b8'; } function parseAccuracyValue(accuracy: string): number { const match = accuracy.match(/(\d+)/); return match ? parseInt(match[1], 10) : 50; } export default function ImageReportPanel({ reasons, perGeneratorAccuracy, verdict }: ImageReportPanelProps) { return (
{/* Forensic reasons */} {reasons && reasons.length > 0 && (
Logical Arbiter — Forensic Reasoning
{reasons.map((reason, i) => { const isPositive = reason.includes('✓') || reason.includes('○'); const isNegative = reason.includes('✗'); const Icon = isPositive ? CheckCircle2 : isNegative ? XCircle : Info; const color = isPositive ? '#10b981' : isNegative ? '#ef4444' : '#64748b'; // Clean the text by removing the markers const cleanText = reason.replace(/[✓✗○]/g, '').trim(); return ( {cleanText} ); })}
)} {/* Per-generator accuracy table */} {perGeneratorAccuracy && Object.keys(perGeneratorAccuracy).length > 0 && (
Per-Generator Detection Accuracy
{Object.entries(perGeneratorAccuracy).map(([gen, data]) => { const pct = parseAccuracyValue(data.accuracy); const col = getGeneratorColor(gen); return (
{gen} {data.accuracy}
{data.notes}
); })}
Accuracy varies by compression, platform re-encoding, and steganographic post-processing artifacts.
)}
); }