Spaces:
Sleeping
Sleeping
File size: 3,055 Bytes
8c07df8 | 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 | "use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { LayoutDashboard, UploadCloud, ShieldAlert, Cctv, Map as MapIcon, Radio, FlaskConical } from "lucide-react";
import { cn } from "@/lib/utils";
import { Badge } from "@/components/ui/badge";
const NAV = [
{ href: "/", label: "Command Center", icon: LayoutDashboard },
{ href: "/upload", label: "Upload & Analyze", icon: UploadCloud },
{ href: "/violations", label: "Violations", icon: ShieldAlert },
{ href: "/cameras", label: "Live Cameras", icon: Cctv },
{ href: "/playground", label: "Model Playground", icon: FlaskConical },
{ href: "/map", label: "Hotspot Map", icon: MapIcon },
];
export default function Shell({ children }: { children: React.ReactNode }) {
const path = usePathname();
return (
<div className="flex min-h-full">
<aside className="w-64 shrink-0 border-r border-border bg-card p-4 flex flex-col gap-1.5">
<div className="px-2 py-3 mb-2">
<div className="text-xl font-extrabold tracking-wide flex items-center gap-2">
<Radio className="size-5 text-accent" />
DRISHTI<span className="text-accent">路</span>ITMS
</div>
<div className="text-xs text-muted-foreground mt-1 pl-7">
AI Traffic Violation Enforcement
</div>
</div>
{NAV.map((n) => {
const active = path === n.href;
const Icon = n.icon;
return (
<Link
key={n.href}
href={n.href}
className={cn(
"flex items-center gap-3 px-3 py-2 rounded-lg text-sm font-medium transition-colors",
active ? "bg-accent/15 text-accent" : "text-muted-foreground hover:bg-secondary hover:text-foreground"
)}
>
<Icon className="size-4 shrink-0" />
{n.label}
</Link>
);
})}
<div className="mt-auto rounded-lg border border-border bg-secondary/50 p-3 text-xs text-muted-foreground">
<div className="flex items-center gap-2 mb-1">
<span className="size-2 rounded-full bg-[var(--success)] animate-pulse" /> Engine online
</div>
Any-camera enforcement 路 edge + cloud
</div>
</aside>
<main className="flex-1 min-w-0">
<header className="h-14 border-b border-border bg-card/60 backdrop-blur flex items-center justify-between px-6 sticky top-0 z-30">
<div className="text-sm text-muted-foreground">
Bengaluru Traffic Police 路 ASTraM-compatible
</div>
<div className="flex items-center gap-3 text-sm">
<Badge variant="success" className="gap-1.5">
<span className="size-1.5 rounded-full bg-[var(--success)] animate-pulse" /> Live
</Badge>
<span className="text-muted-foreground">Officer: aman</span>
</div>
</header>
<div className="p-6">{children}</div>
</main>
</div>
);
}
|