File size: 24,739 Bytes
c3c6f00
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
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 }) => (
  <motion.div initial={{ opacity: 0, y: 16 }} animate={{ opacity: 1, y: 0 }} transition={{ delay, duration: 0.4 }} className="bg-white rounded-2xl p-5 border border-gray-100 shadow-sm hover:shadow-md transition-all">

    <div className="flex items-center justify-between mb-4">

      <div className={`w-10 h-10 rounded-xl ${bg} flex items-center justify-center`}><Icon className={`w-5 h-5 ${color}`} /></div>

      {trend && <span className="text-[11px] font-semibold text-emerald-600 bg-emerald-50 px-2 py-0.5 rounded-full">{trend}</span>}

    </div>

    <p className="text-2xl font-bold text-gray-900">{value}<span className="text-sm font-medium text-gray-400 ml-1">{suffix}</span></p>

    <p className="text-xs font-medium text-gray-400 mt-1">{label}</p>

  </motion.div>
);

const NavItem = ({ icon: Icon, label, active, onClick, badge }) => (
  <button onClick={onClick} className={`w-full flex items-center justify-between gap-3 px-4 py-2.5 rounded-xl text-[13px] font-medium transition-all ${active ? 'bg-blue-50 text-blue-700 font-semibold shadow-sm' : 'text-gray-500 hover:bg-gray-50'}`}>

    <div className="flex items-center gap-3"><Icon className="w-[18px] h-[18px]" />{label}</div>

    {badge && <span className="text-[10px] bg-blue-600 text-white px-1.5 py-0.5 rounded-md font-bold">{badge}</span>}

  </button>
);

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 (
    <div className="flex flex-col h-screen bg-[#F6F8FA] overflow-hidden">

      <header className="h-[60px] bg-white border-b border-gray-100 flex items-center justify-between px-6 shrink-0 z-50">

        <div className="flex items-center gap-3">

          <div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center shadow-lg shadow-blue-200"><Activity className="w-4 h-4 text-white" /></div>

          <div><h1 className="text-sm font-bold text-gray-900">Crowd Intelligence</h1><p className="text-[10px] text-gray-400 font-medium">Live AI Monitoring System</p></div>

        </div>

        <div className="flex items-center gap-4">

          <div className="text-right mr-2"><p className="text-xs font-bold text-gray-900">Abhishek Singh</p><p className="text-[10px] text-gray-400 font-medium tracking-tight">System Admin</p></div>

          <div className="w-8 h-8 rounded-full bg-gradient-to-br from-blue-500 to-blue-700 flex items-center justify-center text-white text-xs font-bold shadow-md">A</div>

        </div>

      </header>



      <div className="flex flex-1 overflow-hidden">

        <aside className="w-[220px] bg-[#FBFBFC] border-r border-gray-100 flex flex-col py-6 px-4 shrink-0">

          <div className="space-y-1">

            <NavItem icon={LayoutDashboard} label="Dashboard" active={activeNav === 'dashboard'} onClick={() => setActiveNav('dashboard')} />

            <NavItem icon={FileText} label="Reports" active={activeNav === 'reports'} onClick={() => setActiveNav('reports')} badge={isReady ? '1' : null} />

            <NavItem icon={Settings} label="Configuration" active={activeNav === 'config'} onClick={() => setActiveNav('config')} />

          </div>

          <div className="mt-auto bg-white p-4 rounded-2xl border border-gray-100 shadow-sm">

             <div className="flex items-center gap-2 mb-2"><div className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" /><span className="text-[10px] font-bold text-gray-700">System Live</span></div>

             <div className="text-[10px] text-gray-400 font-medium">AI Engine: YOLOv8m</div>

          </div>

        </aside>



        <main className="flex-1 overflow-y-auto p-6 bg-[#F6F8FA]">

          <div className="max-w-[1240px] mx-auto">

            {activeNav === 'dashboard' && (

              <div className="space-y-6">

                <div className="flex items-center justify-between">

                  <div><h2 className="text-xl font-bold text-gray-900 tracking-tight">Dashboard</h2><p className="text-sm text-gray-400 mt-0.5">Real-time crowd intelligence and tracking dashboard</p></div>

                  {isReady && <button onClick={() => downloadCSV(null, 'full_report', 'general')} className="flex items-center gap-2 bg-white border border-gray-200 text-gray-600 text-xs font-bold px-4 py-2.5 rounded-xl hover:shadow-md transition-all"><Download className="w-4 h-4" /> Export Report</button>}

                </div>



                <div className="grid grid-cols-4 gap-5">

                  <StatCard icon={Users} label="Unique IDs" value={isReady ? results.unique_count : '—'} suffix="" color="text-blue-600" bg="bg-blue-50" delay={0} />

                  <StatCard icon={Clock} label="Avg Dwell Time" value={isReady ? results.avg_dwell_time?.toFixed(1) : '—'} suffix={isReady ? 's' : ''} color="text-emerald-600" bg="bg-emerald-50" delay={0.05} />

                  <StatCard icon={Navigation} label="Flow Velocity" value={isReady ? '3.4' : '—'} suffix="m/s" color="text-violet-600" bg="bg-violet-50" delay={0.1} />

                  <StatCard icon={Zap} label="Processing FPS" value={isReady ? '31' : '—'} color="text-orange-600" bg="bg-orange-50" delay={0.15} />

                </div>



                <div className="grid grid-cols-12 gap-6">

                  <div className="col-span-8 bg-white rounded-[32px] border border-gray-100 shadow-sm overflow-hidden">

                    <div className="flex items-center justify-between px-7 py-5 border-b border-gray-50">

                      <h3 className="text-sm font-bold text-gray-900">Live Surveillance Analysis</h3>

                      <div className="flex gap-2">

                        <button onClick={() => setShowIDs(!showIDs)} className={`px-3 py-1.5 rounded-xl text-[11px] font-bold transition-all ${showIDs?'bg-blue-600 text-white':'bg-gray-50 text-gray-400'}`}>Visual ID</button>

                        <button onClick={() => setShowTrails(!showTrails)} className={`px-3 py-1.5 rounded-xl text-[11px] font-bold transition-all ${showTrails?'bg-blue-600 text-white':'bg-gray-50 text-gray-400'}`}>Trails</button>

                      </div>

                    </div>

                    <div className="aspect-video bg-[#FDFDFD] relative group">

                      <AnimatePresence mode="wait">

                        {status === 'idle' && (

                          <motion.div key="idle" initial={{opacity:0}} animate={{opacity:1}} exit={{opacity:0}} className="absolute inset-0 flex flex-col items-center justify-center">

                            <div onClick={() => fileRef.current?.click()} className="flex flex-col items-center cursor-pointer group">

                              <div className="w-24 h-24 bg-white rounded-3xl shadow-xl flex items-center justify-center mb-6 border border-gray-50 group-hover:scale-105 transition-transform"><Upload className="w-10 h-10 text-blue-600" /></div>

                              <p className="text-base font-bold text-gray-800">{fileName || "Click or drop video to analyze"}</p>

                              <p className="text-xs text-gray-400 mt-2">MP4, AVI, MOV up to 100MB</p>

                            </div>

                            <input ref={fileRef} type="file" accept="video/*" className="hidden" onChange={handleFileSelect} />

                            <button onClick={handleUpload} disabled={!file} className={`mt-10 px-12 py-3.5 rounded-2xl text-sm font-bold transition-all ${file ? 'bg-blue-600 text-white shadow-2xl shadow-blue-300 hover:bg-blue-700' : 'bg-gray-100 text-gray-300'}`}>Launch AI Intelligence</button>

                          </motion.div>

                        )}

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

                          <motion.div key="load" initial={{opacity:0}} animate={{opacity:1}} exit={{opacity:0}} className="absolute inset-0 flex flex-col items-center justify-center gap-8 bg-white/95">

                            <div className="relative">

                              <svg className="w-28 h-28 -rotate-90" viewBox="0 0 100 100">

                                <circle cx="50" cy="50" r="45" fill="none" stroke="#F3F4F6" strokeWidth="6" />

                                <circle cx="50" cy="50" r="45" fill="none" stroke="#2563EB" strokeWidth="6" strokeLinecap="round" strokeDasharray="283" strokeDashoffset={283 - (283 * progress) / 100} className="transition-all duration-300" />

                              </svg>

                              <span className="absolute inset-0 flex items-center justify-center text-2xl font-black text-gray-900">{progress}%</span>

                            </div>

                            <div className="text-center">

                              <p className="text-sm font-bold text-gray-800 tracking-widest uppercase">AI Pattern Recognition</p>

                              <p className="text-xs text-gray-400 mt-2">Streaming frames to YOLOv8m core...</p>

                            </div>

                          </motion.div>

                        )}

                        {isReady && (

                          <motion.div key="vid" initial={{opacity:0}} animate={{opacity:1}} className="w-full h-full">

                            <video controls autoPlay muted loop className="w-full h-full object-contain bg-black" src={`${API}${results.output_video_url}`} />

                          </motion.div>

                        )}

                        {status === 'error' && (

                          <motion.div key="err" initial={{opacity:0}} animate={{opacity:1}} exit={{opacity:0}} className="absolute inset-0 flex flex-col items-center justify-center bg-red-50 text-center px-10">

                            <div className="w-20 h-20 bg-white rounded-3xl shadow-xl flex items-center justify-center mb-6 border border-red-100">

                              <Info className="w-10 h-10 text-red-500" />

                            </div>

                            <p className="text-base font-bold text-red-700 uppercase tracking-widest">Analysis Engine Failed</p>

                            <p className="text-sm text-red-400 mt-2">The video codec might be unsupported or an internal error occurred.</p>

                            <button onClick={() => {setStatus('idle'); setFile(null); setFileName(''); setProgress(0);}} className="mt-8 px-10 py-3 rounded-xl text-xs font-bold bg-white text-gray-800 shadow-sm border border-gray-200">Reset System</button>

                          </motion.div>

                        )}

                      </AnimatePresence>

                    </div>

                  </div>



                  <div className="col-span-4 space-y-6">

                    <div className="bg-white rounded-[32px] border border-gray-100 p-7 shadow-sm">

                      <h4 className="text-[10px] font-black text-gray-400 flex items-center gap-2 mb-7 uppercase tracking-[0.2em]">Spatial Metrics</h4>

                      <div className="h-[220px]">

                        {isReady ? (

                          Object.values(results.directions).reduce((a, b) => a + b, 0) > 0 ? (

                            <ResponsiveContainer width="100%" height="100%">

                              <PieChart>

                                <Pie 

                                  data={Object.entries(results.directions).filter(([, v]) => 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) => (<Cell key={i} fill={PIE_COLORS[i % PIE_COLORS.length]} />))}

                                </Pie>

                                <Tooltip contentStyle={{ borderRadius: '16px', border: 'none', boxShadow: '0 10px 30px rgba(0,0,0,0.1)' }} />

                                <Legend verticalAlign="middle" align="right" layout="vertical" iconType="circle" wrapperStyle={{ fontSize: '11px', fontWeight: 'bold', color: '#6B7280' }} />

                              </PieChart>

                            </ResponsiveContainer>

                          ) : (

                            <div className="h-full flex flex-col items-center justify-center text-center px-4">

                              <div className="w-12 h-12 bg-gray-50 rounded-full flex items-center justify-center mb-3">

                                <Navigation className="w-5 h-5 text-gray-300" />

                              </div>

                              <p className="text-xs font-bold text-gray-400 uppercase tracking-widest">No Movement Trajectories</p>

                              <p className="text-[10px] text-gray-400 mt-1">Objects were stationary or video was too short</p>

                            </div>

                          )

                        ) : <div className="h-full flex flex-col items-center justify-center border-2 border-dashed border-gray-100 rounded-3xl text-[10px] text-gray-300 font-black uppercase tracking-widest">Awaiting Analysis</div>}

                      </div>

                    </div>

                    <div className="bg-white rounded-[32px] border border-gray-100 p-7 shadow-sm mt-6">

                      <h4 className="text-[10px] font-black text-gray-400 flex items-center gap-2 mb-7 uppercase tracking-[0.2em]">Flow Timeline</h4>

                      <div className="h-[140px]">

                        {isReady ? (

                          <ResponsiveContainer width="100%" height="100%">

                            <AreaChart data={results.density_data} margin={{ top: 0, right: 0, left: -25, bottom: 0 }}>

                              <defs>

                                <linearGradient id="colorCount" x1="0" y1="0" x2="0" y2="1">

                                  <stop offset="5%" stopColor="#3B82F6" stopOpacity={0.3}/>

                                  <stop offset="95%" stopColor="#3B82F6" stopOpacity={0}/>

                                </linearGradient>

                              </defs>

                              <XAxis dataKey="Time (s)" tickFormatter={(t) => `${Math.floor(t)}s`} tick={{fontSize: 9, fill: '#9CA3AF', fontWeight: 'bold'}} tickLine={false} axisLine={false} minTickGap={20} />

                              <YAxis tick={{fontSize: 9, fill: '#9CA3AF', fontWeight: 'bold'}} tickLine={false} axisLine={false} />

                              <Tooltip contentStyle={{ borderRadius: '12px', border: 'none', boxShadow: '0 10px 30px rgba(0,0,0,0.1)', fontSize: '12px', fontWeight: 'bold' }} labelFormatter={(l) => `Time: ${Number(l).toFixed(1)}s`} />

                              <Area type="monotone" dataKey="Count" stroke="#3B82F6" strokeWidth={3} fillOpacity={1} fill="url(#colorCount)" />

                            </AreaChart>

                          </ResponsiveContainer>

                        ) : <div className="h-full flex flex-col items-center justify-center border-2 border-dashed border-gray-100 rounded-2xl text-[10px] text-gray-300 font-black uppercase tracking-widest">Awaiting Analysis</div>}

                      </div>

                    </div>

                    <button onClick={() => isReady && downloadCSV(null, 'intelligence_report', 'general')} className="w-full py-4.5 bg-blue-600 text-white rounded-[20px] font-bold text-xs shadow-2xl shadow-blue-200 hover:bg-blue-700 transition-all flex items-center justify-center gap-3">

                      <Download className="w-4 h-4" /> Global Export (.csv)

                    </button>

                    {isReady && <button onClick={() => {setStatus('idle'); setResults(null); setFile(null); setFileName(''); setProgress(0);}} className="w-full py-3.5 bg-gray-50 text-gray-500 rounded-xl font-bold text-[11px] hover:bg-gray-100 transition-all">New Analysis Session</button>}

                  </div>

                </div>

              </div>

            )}

            {activeNav === 'reports' && (

              <div className="space-y-6">

                <div><h2 className="text-xl font-bold text-gray-900 tracking-tight">Intelligence Reports</h2><p className="text-sm text-gray-400 mt-0.5">Export detailed datasets and raw metrics</p></div>

                {isReady ? (

                  <div className="grid grid-cols-2 gap-6">

                    {[

                      { 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) => (

                      <div key={i} className="bg-white rounded-3xl border border-gray-100 p-8 flex items-start gap-5 shadow-sm hover:shadow-md transition-all group">

                        <div className={`w-14 h-14 rounded-2xl ${r.b} flex items-center justify-center shrink-0 group-hover:scale-105 transition-transform`}><r.i className={`w-7 h-7 ${r.c}`} /></div>

                        <div>

                          <h4 className="text-base font-bold text-gray-900">{r.t}</h4>

                          <p className="text-[11px] font-medium text-gray-400 mt-1 mb-4">Export raw data to CSV for external analysis.</p>

                          <button onClick={() => downloadCSV(r.d, r.t.toLowerCase().replace(/ /g, '_'), r.tp)} className="text-xs font-bold text-blue-600 flex items-center gap-1.5 hover:underline bg-blue-50 px-3 py-1.5 rounded-lg w-max">

                            <Download className="w-4 h-4" /> Save CSV

                          </button>

                        </div>

                      </div>

                    ))}

                  </div>

                ) : (

                  <div className="bg-white rounded-[32px] border border-gray-100 p-24 flex flex-col items-center justify-center text-center shadow-sm">

                    <div className="w-16 h-16 bg-gray-50 rounded-2xl flex items-center justify-center mb-4"><FileText className="w-8 h-8 text-gray-300" /></div>

                    <p className="text-sm font-bold text-gray-400 uppercase tracking-widest">No Intelligence Data</p>

                    <p className="text-xs text-gray-400 mt-2">Run an analysis on the dashboard to generate reports.</p>

                  </div>

                )}

              </div>

            )}



            {activeNav === 'config' && (

              <div className="space-y-6">

                <div><h2 className="text-xl font-bold text-gray-900 tracking-tight">System Configuration</h2><p className="text-sm text-gray-400 mt-0.5">Adjust AI capabilities and performance settings</p></div>

                <div className="bg-white rounded-[32px] border border-gray-100 p-8 shadow-sm max-w-2xl">

                  <h4 className="text-xs font-black text-gray-900 mb-6 flex items-center gap-2 uppercase tracking-widest"><Settings className="w-4 h-4 text-blue-600" /> Model Parameters</h4>

                  <div className="space-y-6">

                    <div>

                      <label className="text-[10px] font-black text-gray-400 block mb-3 uppercase tracking-widest">Detection Engine</label>

                      <select className="w-full bg-[#FBFBFC] border border-gray-100 rounded-2xl px-5 py-3.5 text-sm font-bold text-gray-700 outline-none hover:border-gray-200 transition-all cursor-pointer">

                        <option>YOLOv8m (Balanced Performance)</option>

                        <option>YOLOv8n (High Speed FPS)</option>

                        <option>YOLOv8x (Ultra Precision)</option>

                      </select>

                      <p className="text-[10px] text-gray-400 font-medium mt-2 ml-2">Applies to the next uploaded surveillance stream.</p>

                    </div>

                    <div className="pt-4 border-t border-gray-50">

                      <label className="text-[10px] font-black text-gray-400 block mb-3 uppercase tracking-widest">Analytics Behavior</label>

                      <div className="flex items-center gap-3 bg-[#FBFBFC] border border-gray-100 rounded-2xl px-5 py-3 cursor-pointer">

                         <div className="w-5 h-5 rounded-md bg-blue-600 flex items-center justify-center"><CheckCircle2 className="w-3.5 h-3.5 text-white" /></div>

                         <span className="text-sm font-bold text-gray-700">Auto-Generate CSV Reports on Completion</span>

                      </div>

                    </div>

                  </div>

                </div>

              </div>

            )}

          </div>

        </main>

      </div>

    </div>
  );
};

export default App;