85 أسطر
3.1 KiB
TypeScript
85 أسطر
3.1 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { useMemo, useState } from "react";
|
|
import { usePathname } from "next/navigation";
|
|
import { Search, ShieldCheck } from "lucide-react";
|
|
|
|
import { useSuperAdminSession } from "@/components/auth/session-context";
|
|
import { Input } from "@/components/ui/input";
|
|
import { dashboardNav } from "@/lib/navigation";
|
|
import { matchesPermissions } from "@/lib/permissions";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export function DashboardSidebar() {
|
|
const pathname = usePathname();
|
|
const [search, setSearch] = useState("");
|
|
const { permissions } = useSuperAdminSession();
|
|
|
|
const accessibleNav = useMemo(
|
|
() =>
|
|
dashboardNav.filter((item) =>
|
|
matchesPermissions(permissions, item.requiredPermissions, item.permissionMode),
|
|
),
|
|
[permissions],
|
|
);
|
|
|
|
const filteredNav = useMemo(() => {
|
|
const needle = search.trim().toLowerCase();
|
|
if (!needle) return accessibleNav;
|
|
return accessibleNav.filter((item) => item.label.toLowerCase().includes(needle));
|
|
}, [accessibleNav, search]);
|
|
|
|
return (
|
|
<aside className="frame-panel ornament-grid sticky top-4 hidden h-[calc(100vh-2rem)] w-72 shrink-0 flex-col border-border/70 p-4 lg:flex">
|
|
<div className="mb-5 rounded-xl border border-border/60 bg-background/70 p-4">
|
|
<p className="font-heading text-xl font-bold tracking-wide text-primary">Oudelaa</p>
|
|
<p className="text-xs text-muted-foreground">SuperAdmin Command Console</p>
|
|
</div>
|
|
|
|
<div className="relative mb-4">
|
|
<Search className="pointer-events-none absolute right-3 top-3 h-4 w-4 text-muted-foreground" />
|
|
<Input
|
|
className="pr-9"
|
|
placeholder="Search sections..."
|
|
value={search}
|
|
onChange={(event) => setSearch(event.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<nav className="space-y-1">
|
|
{filteredNav.map((item) => {
|
|
const isActive = pathname === item.href;
|
|
return (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className={cn(
|
|
"group flex items-center gap-3 rounded-lg border px-3 py-2 text-sm transition",
|
|
isActive
|
|
? "border-primary/40 bg-primary/15 text-primary"
|
|
: "border-transparent text-muted-foreground hover:border-border hover:bg-secondary/70 hover:text-foreground",
|
|
)}
|
|
>
|
|
<item.icon className="h-4 w-4" />
|
|
<span>{item.label}</span>
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
|
|
<div className="mt-auto space-y-3 rounded-xl border border-border/70 bg-secondary/40 p-4">
|
|
<div className="flex items-center justify-between text-xs text-muted-foreground">
|
|
<span>Moderation mode</span>
|
|
<ShieldCheck className="h-4 w-4" />
|
|
</div>
|
|
<p className="text-sm text-foreground">
|
|
This console manages users, marketplace items, content, reports, and SuperAdmin sessions
|
|
through dedicated admin API routes.
|
|
</p>
|
|
<p className="text-xs text-muted-foreground">Data is loaded from the live API, not mock data.</p>
|
|
</div>
|
|
</aside>
|
|
);
|
|
}
|