gpt-engineer-app[bot] commited on
Commit ·
c54233a
1
Parent(s): 1db0caf
Changes
Browse files- src/components/severity-badge.tsx +23 -0
- src/components/sidebar.tsx +77 -0
src/components/severity-badge.tsx
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { cn } from "@/lib/utils";
|
| 2 |
+
|
| 3 |
+
const styles: Record<string, string> = {
|
| 4 |
+
critical: "bg-severity-critical/15 text-severity-critical border-severity-critical/40",
|
| 5 |
+
high: "bg-severity-high/15 text-severity-high border-severity-high/40",
|
| 6 |
+
medium: "bg-severity-medium/15 text-severity-medium border-severity-medium/40",
|
| 7 |
+
low: "bg-severity-low/15 text-severity-low border-severity-low/40",
|
| 8 |
+
unknown: "bg-severity-unknown/15 text-muted-foreground border-severity-unknown/40",
|
| 9 |
+
};
|
| 10 |
+
|
| 11 |
+
export function SeverityBadge({ severity, className }: { severity: string; className?: string }) {
|
| 12 |
+
return (
|
| 13 |
+
<span
|
| 14 |
+
className={cn(
|
| 15 |
+
"inline-flex items-center px-2 py-0.5 rounded-full border text-[10px] font-bold uppercase tracking-wider font-mono",
|
| 16 |
+
styles[severity] ?? styles.unknown,
|
| 17 |
+
className
|
| 18 |
+
)}
|
| 19 |
+
>
|
| 20 |
+
{severity}
|
| 21 |
+
</span>
|
| 22 |
+
);
|
| 23 |
+
}
|
src/components/sidebar.tsx
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Link, useLocation, useNavigate } from "@tanstack/react-router";
|
| 2 |
+
import { Radar, AlertTriangle, FileBarChart, GraduationCap, Scale, LogOut, User as UserIcon } from "lucide-react";
|
| 3 |
+
import { supabase } from "@/integrations/supabase/client";
|
| 4 |
+
import { cn } from "@/lib/utils";
|
| 5 |
+
import type { User } from "@supabase/supabase-js";
|
| 6 |
+
|
| 7 |
+
const nav = [
|
| 8 |
+
{ to: "/dashboard", label: "Incidents", icon: AlertTriangle },
|
| 9 |
+
{ to: "/dashboard/reports", label: "Reports", icon: FileBarChart },
|
| 10 |
+
{ to: "/dashboard/coaching", label: "Coaching", icon: GraduationCap },
|
| 11 |
+
{ to: "/dashboard/compliance", label: "Compliance", icon: Scale },
|
| 12 |
+
] as const;
|
| 13 |
+
|
| 14 |
+
export function Sidebar({ user }: { user: User | null }) {
|
| 15 |
+
const loc = useLocation();
|
| 16 |
+
const navigate = useNavigate();
|
| 17 |
+
|
| 18 |
+
const logout = async () => {
|
| 19 |
+
await supabase.auth.signOut();
|
| 20 |
+
navigate({ to: "/auth" });
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
return (
|
| 24 |
+
<aside className="w-64 shrink-0 bg-sidebar border-r border-sidebar-border flex flex-col">
|
| 25 |
+
<div className="p-6 border-b border-sidebar-border">
|
| 26 |
+
<Link to="/dashboard" className="flex items-center gap-3">
|
| 27 |
+
<div className="h-9 w-9 rounded-lg bg-primary text-primary-foreground flex items-center justify-center shadow-[var(--shadow-glow)]">
|
| 28 |
+
<Radar className="h-5 w-5" />
|
| 29 |
+
</div>
|
| 30 |
+
<div>
|
| 31 |
+
<div className="font-bold tracking-tight leading-none">AVISYS</div>
|
| 32 |
+
<div className="text-[10px] uppercase tracking-widest text-muted-foreground mt-1">Safety Console</div>
|
| 33 |
+
</div>
|
| 34 |
+
</Link>
|
| 35 |
+
</div>
|
| 36 |
+
|
| 37 |
+
<nav className="flex-1 p-4 space-y-1">
|
| 38 |
+
{nav.map(({ to, label, icon: Icon }) => {
|
| 39 |
+
const active = loc.pathname === to || (to !== "/dashboard" && loc.pathname.startsWith(to));
|
| 40 |
+
return (
|
| 41 |
+
<Link
|
| 42 |
+
key={to}
|
| 43 |
+
to={to}
|
| 44 |
+
className={cn(
|
| 45 |
+
"flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors",
|
| 46 |
+
active
|
| 47 |
+
? "bg-sidebar-accent text-primary"
|
| 48 |
+
: "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-foreground"
|
| 49 |
+
)}
|
| 50 |
+
>
|
| 51 |
+
<Icon className="h-4 w-4" />
|
| 52 |
+
{label}
|
| 53 |
+
</Link>
|
| 54 |
+
);
|
| 55 |
+
})}
|
| 56 |
+
</nav>
|
| 57 |
+
|
| 58 |
+
<div className="p-4 border-t border-sidebar-border space-y-3">
|
| 59 |
+
<div className="flex items-center gap-3 px-2">
|
| 60 |
+
<div className="h-8 w-8 rounded-full bg-accent flex items-center justify-center">
|
| 61 |
+
<UserIcon className="h-4 w-4" />
|
| 62 |
+
</div>
|
| 63 |
+
<div className="flex-1 min-w-0">
|
| 64 |
+
<div className="text-xs font-medium truncate">{user?.email ?? "—"}</div>
|
| 65 |
+
<div className="text-[10px] uppercase tracking-wider text-muted-foreground">Operator</div>
|
| 66 |
+
</div>
|
| 67 |
+
</div>
|
| 68 |
+
<button
|
| 69 |
+
onClick={logout}
|
| 70 |
+
className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-xs text-muted-foreground hover:bg-sidebar-accent hover:text-foreground"
|
| 71 |
+
>
|
| 72 |
+
<LogOut className="h-3.5 w-3.5" /> Sign out
|
| 73 |
+
</button>
|
| 74 |
+
</div>
|
| 75 |
+
</aside>
|
| 76 |
+
);
|
| 77 |
+
}
|