import React, { useState, useEffect, useRef } from 'react'; import axios from 'axios'; import { Upload, Play, BarChart3, Users, Clock, ArrowRight, Activity, CheckCircle2, RotateCcw, Download, ChevronRight, LayoutDashboard, Globe, Settings, FileText, Bell, Search, Navigation, Layers, Zap, ArrowUpRight, TrendingUp, Video, Eye, EyeOff, Info, HelpCircle, Sliders, Flame } from 'lucide-react'; import { motion, AnimatePresence } from 'framer-motion'; import { ResponsiveContainer, AreaChart, Area, PieChart, Pie, Cell, Tooltip, Legend, XAxis, YAxis, CartesianGrid } from 'recharts'; const API = import.meta.env.VITE_API_URL || "http://localhost:8001"; const StatCard = ({ icon: Icon, label, value, suffix, trend, color, bg, delay }) => (
{trend && {trend}}

{value}{suffix}

{label}

); const NavItem = ({ icon: Icon, label, active, onClick, badge }) => ( ); const App = () => { const [file, setFile] = useState(null); const [fileName, setFileName] = useState(''); const [taskId, setTaskId] = useState(null); const [status, setStatus] = useState('idle'); const [progress, setProgress] = useState(0); const [results, setResults] = useState(null); const [activeNav, setActiveNav] = useState('dashboard'); const [showIDs, setShowIDs] = useState(true); const [showTrails, setShowTrails] = useState(true); const fileRef = useRef(null); useEffect(() => { let interval; if (status === 'processing' && taskId) { interval = setInterval(async () => { try { const res = await axios.get(`${API}/status/${taskId}`); if (res.data.progress !== undefined) { // Keep percentage at 99% until results are fully loaded setProgress(res.data.status === 'completed' ? 100 : Math.min(res.data.progress, 99)); } if (res.data.status === 'completed' && res.data.results) { setResults(res.data.results); setStatus('completed'); clearInterval(interval); } else if (res.data.status === 'failed') { setStatus('error'); clearInterval(interval); } } catch(err) { console.error("Polling error:", err); } }, 800); } return () => clearInterval(interval); }, [status, taskId]); const handleFileSelect = (e) => { const selected = e.target.files[0]; if (selected) { setFile(selected); setFileName(selected.name); } }; const handleUpload = async () => { if (!file) return; setStatus('uploading'); setProgress(1); setResults(null); setTaskId(null); const formData = new FormData(); formData.append('file', file); try { const res = await axios.post(`${API}/analyze`, formData); setTaskId(res.data.task_id); setStatus('processing'); } catch { setStatus('error'); } }; const downloadCSV = (data, filename, type) => { if (!results) return; let csvContent = ""; if (type === 'density' && data) { csvContent = "Frame,Count\n" + data.map(r => `${r.Frame},${r.Count}`).join("\n"); } else if (type === 'directions' && data) { csvContent = "Direction,Count\n" + Object.entries(data).map(([k, v]) => `${k},${v}`).join("\n"); } else { csvContent = `Metric,Value\nUnique IDs,${results.unique_count}\nAvg Dwell Time,${results.avg_dwell_time?.toFixed(2)}s\nTimestamp,${new Date().toLocaleString()}`; } const blob = new Blob([csvContent], { type: 'text/csv' }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `${filename}.csv`; a.click(); }; const isReady = status === 'completed' && results; const PIE_COLORS = ['#3B82F6', '#10B981', '#F59E0B', '#6366F1', '#DC2626']; return (

Crowd Intelligence

Live AI Monitoring System

Abhishek Singh

System Admin

A
{activeNav === 'dashboard' && (

Dashboard

Real-time crowd intelligence and tracking dashboard

{isReady && }

Live Surveillance Analysis

{status === 'idle' && (
fileRef.current?.click()} className="flex flex-col items-center cursor-pointer group">

{fileName || "Click or drop video to analyze"}

MP4, AVI, MOV up to 100MB

)} {(status === 'uploading' || status === 'processing' || (status === 'completed' && !results)) && (
{progress}%

AI Pattern Recognition

Streaming frames to YOLOv8m core...

)} {isReady && ( )} {status === 'error' && (

Analysis Engine Failed

The video codec might be unsupported or an internal error occurred.

)}

Spatial Metrics

{isReady ? ( Object.values(results.directions).reduce((a, b) => a + b, 0) > 0 ? ( v > 0).map(([name, value]) => ({ name, value }))} innerRadius={50} outerRadius={75} paddingAngle={4} dataKey="value" stroke="none" > {Object.entries(results.directions).filter(([, v]) => v > 0).map((_, i) => ())} ) : (

No Movement Trajectories

Objects were stationary or video was too short

) ) :
Awaiting Analysis
}

Flow Timeline

{isReady ? ( `${Math.floor(t)}s`} tick={{fontSize: 9, fill: '#9CA3AF', fontWeight: 'bold'}} tickLine={false} axisLine={false} minTickGap={20} /> `Time: ${Number(l).toFixed(1)}s`} /> ) :
Awaiting Analysis
}
{isReady && }
)} {activeNav === 'reports' && (

Intelligence Reports

Export detailed datasets and raw metrics

{isReady ? (
{[ { t: 'Flow Timeline (Density)', d: results.density_data, tp: 'density', i: BarChart3, c: 'text-orange-600', b: 'bg-orange-50' }, { t: 'Directional Vectors', d: results.directions, tp: 'directions', i: Navigation, c: 'text-violet-600', b: 'bg-violet-50' }, { t: 'Metrics Summary', d: null, tp: 'general', i: FileText, c: 'text-blue-600', b: 'bg-blue-50' }, ].map((r, i) => (

{r.t}

Export raw data to CSV for external analysis.

))}
) : (

No Intelligence Data

Run an analysis on the dashboard to generate reports.

)}
)} {activeNav === 'config' && (

System Configuration

Adjust AI capabilities and performance settings

Model Parameters

Applies to the next uploaded surveillance stream.

Auto-Generate CSV Reports on Completion
)}
); }; export default App;