import { useState, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Eye, EyeOff, ZoomIn, ZoomOut, RotateCcw, Layers, Info } from 'lucide-react'; import styles from './MediaPanel.module.css'; function HeatmapLayer({ regions, opacity }) { return (
{regions.map((region, i) => { const isHigh = region.intensity > 0.8; const isMedium = region.intensity > 0.5; const color = isHigh ? 'var(--ai-generated)' : isMedium ? 'var(--suspect)' : 'var(--authentic)'; const baseAlpha = 0.22 + region.intensity * 0.58; const scaledAlpha = Math.min(0.98, baseAlpha * (0.55 + opacity * 1.2)); const blur = Math.max(10, 28 - opacity * 14 - region.intensity * 8); const scale = 1 + region.intensity * 0.2 + opacity * 0.08; return ( ); })}
); } export default function MediaPanel({ result, previewUrl }) { const [heatmapOn, setHeatmapOn] = useState(false); const [heatmapOpacity, setHeatmapOpacity] = useState(0.78); const [zoom, setZoom] = useState(1); const imgRef = useRef(null); const isVideo = result.type === 'video'; const regions = result.gradcam?.regions || []; const handleZoomIn = () => setZoom((value) => Math.min(value + 0.25, 2.5)); const handleZoomOut = () => setZoom((value) => Math.max(value - 0.25, 0.5)); const handleReset = () => { setZoom(1); }; return (
{Math.round(zoom * 100)}%
{heatmapOn && ( Intensity setHeatmapOpacity(parseFloat(event.target.value))} className={styles.opacitySlider} /> {Math.round(heatmapOpacity * 100)}% )}
{isVideo ? (
{heatmapOn && ( Artifact Intensity
High (>80%)
Medium (50–80%)
Low (<50%)
)}
{heatmapOn && regions.length > 0 && (
Localised Artifact Regions
{regions.map((region, index) => (
0.8 ? 'var(--ai-generated)' : region.intensity > 0.5 ? 'var(--suspect)' : 'var(--authentic)', }} /> {region.label} {Math.round(region.intensity * 100)}%
))}
)}
Format {result.format}
Resolution {result.resolution}
Size {result.filesize}
{result.type === 'video' && ( <>
Duration {result.duration}
Frames {result.totalFrames}
)}
); }