Netra / frontend /src /components /Pipeline.jsx
chikentikka's picture
Add violation rules, NETRA UI overhaul, MongoDB challan store, and model weights
f184c04
Raw
History Blame Contribute Delete
1.97 kB
import { useEffect, useState } from "react";
import {
AlertTriangle,
Check,
FileCheck2,
Loader2,
ScanLine,
ScanText,
Wand2,
} from "lucide-react";
const STAGES = [
{ key: "prep", label: "Enhance", icon: Wand2 },
{ key: "detect", label: "Detect", icon: ScanLine },
{ key: "classify", label: "Classify", icon: AlertTriangle },
{ key: "plates", label: "Read plates", icon: ScanText },
{ key: "evidence", label: "Evidence", icon: FileCheck2 },
];
export default function Pipeline({ analyzing, result }) {
const [active, setActive] = useState(0);
useEffect(() => {
if (!analyzing) return;
const id = setInterval(() => setActive((a) => (a + 1) % STAGES.length), 520);
return () => clearInterval(id);
}, [analyzing]);
const stat = (key) => {
if (!result) return null;
const plates = result.violations.filter((v) => v.license_plate).length;
return {
prep: `${result.quality.score}/100`,
detect: `${result.detections} users`,
classify: `${result.violations.length} flags`,
plates: `${plates} read`,
evidence: "ready",
}[key];
};
const done = result && !analyzing;
return (
<div className="pipeline">
{STAGES.map((s, i) => {
const isActive = analyzing && i === active;
const Icon = done ? Check : isActive ? Loader2 : s.icon;
return (
<div
key={s.key}
className={`stage${done ? " done" : ""}${isActive ? " active" : ""}`}
>
<span className="stage-icon">
<Icon size={16} strokeWidth={2} className={isActive ? "spin" : ""} />
</span>
<div className="stage-text">
<span className="stage-label">{s.label}</span>
<span className="stage-stat">{done ? stat(s.key) : " "}</span>
</div>
{i < STAGES.length - 1 && <span className="stage-link" />}
</div>
);
})}
</div>
);
}