74 lines
3.1 KiB
TypeScript
74 lines
3.1 KiB
TypeScript
"use client";
|
|
import { useEffect, useState } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import Link from "next/link";
|
|
import {
|
|
ShieldHalf, Building2, CreditCard, FileText, LogOut, BarChart3,
|
|
PieChart, RefreshCw, LifeBuoy, LayoutGrid,
|
|
} from "lucide-react";
|
|
import { api, clearToken } from "@/lib/api";
|
|
|
|
const nav = [
|
|
{ href: "/admin", label: "Dashboard", icon: LayoutGrid },
|
|
{ href: "/admin/organizations", label: "Organizations", icon: Building2 },
|
|
{ href: "/admin/utilization", label: "Utilization", icon: PieChart },
|
|
{ href: "/admin/retention", label: "Retention", icon: RefreshCw },
|
|
{ href: "/admin/plans", label: "Plans & Pricing", icon: CreditCard },
|
|
{ href: "/admin/revenue", label: "Revenue", icon: BarChart3 },
|
|
{ href: "/admin/support", label: "Support View", icon: LifeBuoy },
|
|
{ href: "/admin/audit", label: "Audit Logs", icon: FileText },
|
|
];
|
|
|
|
export default function AdminLayout({ children }: { children: React.ReactNode }) {
|
|
const router = useRouter();
|
|
const [me, setMe] = useState<any>(null);
|
|
|
|
useEffect(() => {
|
|
api("/me")
|
|
.then((m) => {
|
|
if (!m.is_product_admin) { router.replace("/dashboard"); return; }
|
|
setMe(m);
|
|
})
|
|
.catch(() => { clearToken(); router.replace("/login"); });
|
|
}, [router]);
|
|
|
|
if (!me) return <div className="min-h-screen grid place-items-center text-slate-400">Loading…</div>;
|
|
|
|
function logout() { clearToken(); window.location.href = "/login"; }
|
|
|
|
return (
|
|
<div className="flex min-h-screen bg-slate-50">
|
|
<aside className="w-64 shrink-0 bg-sidebar text-white flex flex-col h-screen sticky top-0">
|
|
<div className="px-6 py-6 flex items-center gap-3">
|
|
<div className="h-10 w-10 rounded-xl bg-white/10 grid place-items-center">
|
|
<ShieldHalf className="h-6 w-6" />
|
|
</div>
|
|
<div>
|
|
<div className="font-extrabold text-lg leading-none">VerifyPack</div>
|
|
<div className="text-[10px] text-white/50 mt-1">Super Admin Panel</div>
|
|
</div>
|
|
</div>
|
|
<nav className="flex-1 overflow-y-auto px-3 space-y-1 mt-2">
|
|
{nav.map(({ href, label, icon: Icon }) => (
|
|
<Link key={href} href={href}
|
|
className="flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium text-white/70 hover:bg-white/10 hover:text-white">
|
|
<Icon className="h-[18px] w-[18px]" /> {label}
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
<div className="p-4 space-y-2">
|
|
<div className="rounded-xl bg-white/5 px-4 py-3 text-[11px]">
|
|
<div className="text-white font-semibold">{me.name}</div>
|
|
<div className="text-white/50 capitalize">{me.product_admin_role?.replace("_", " ")}</div>
|
|
</div>
|
|
<button onClick={logout}
|
|
className="w-full flex items-center gap-2 px-3 py-2.5 rounded-xl text-sm font-medium text-white/70 hover:bg-white/10">
|
|
<LogOut className="h-[18px] w-[18px]" /> Log out
|
|
</button>
|
|
</div>
|
|
</aside>
|
|
<main className="flex-1 min-w-0 p-8">{children}</main>
|
|
</div>
|
|
);
|
|
}
|