Audio_Deepfake_Detection / frontend /src /components /InferenceProgress.tsx
vipan-kumar's picture
Initial commit: Audio Deepfake Detector with 8 detectors trained on jay15k
e6a1f55
Raw
History Blame Contribute Delete
2.61 kB
import { Loader2, CheckCircle2, Circle } from "lucide-react";
import { motion } from "framer-motion";
interface Props {
isInferring: boolean;
modelIds: string[];
completedIds: Set<string>;
}
/** Per-detector progress chips. Smoothly animates from queued → running → done. */
export default function InferenceProgress({
isInferring,
modelIds,
completedIds,
}: Props) {
if (!isInferring && completedIds.size === 0) {
return null;
}
const totalDone = completedIds.size;
const totalActive = modelIds.length;
const progressPct =
totalActive > 0 ? (totalDone / totalActive) * 100 : 0;
return (
<motion.div
initial={{ opacity: 0, y: -4 }}
animate={{ opacity: 1, y: 0 }}
className="panel-alt p-3"
>
<div className="flex items-center justify-between gap-2">
<div className="flex items-center gap-2">
{isInferring ? (
<Loader2 className="h-3.5 w-3.5 animate-spin text-cyber" />
) : (
<CheckCircle2 className="h-3.5 w-3.5 text-cyber" />
)}
<span className="font-mono text-xs text-ink-dim">
{isInferring
? `running ${totalDone}/${totalActive} detectors…`
: `complete · ${totalActive}/${totalActive}`}
</span>
</div>
<span className="font-mono text-[10px] text-ink-mute">
{progressPct.toFixed(0)}%
</span>
</div>
{/* Overall progress bar */}
<div className="mt-2 h-1 overflow-hidden rounded-full bg-bg/50">
<motion.div
initial={{ width: 0 }}
animate={{ width: `${progressPct}%` }}
transition={{ duration: 0.3 }}
className="h-full bg-cyber"
/>
</div>
{/* Per-detector chips */}
<div className="mt-2 grid gap-1.5 sm:grid-cols-2 lg:grid-cols-4">
{modelIds.map((id) => {
const done = completedIds.has(id);
return (
<div
key={id}
className="flex items-center justify-between gap-2 rounded-md border border-line bg-bg/40 px-2 py-1 font-mono text-[10px]"
>
<span className="truncate text-ink">{id}</span>
{done ? (
<CheckCircle2 className="h-3 w-3 shrink-0 text-cyber" />
) : isInferring ? (
<Loader2 className="h-3 w-3 shrink-0 animate-spin text-ink-dim" />
) : (
<Circle className="h-3 w-3 shrink-0 text-ink-mute" />
)}
</div>
);
})}
</div>
</motion.div>
);
}