109 lines
4.4 KiB
TypeScript
109 lines
4.4 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
import { useMemo } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
import {
|
|
Sidebar,
|
|
SidebarContent,
|
|
SidebarGroup,
|
|
SidebarGroupContent,
|
|
SidebarGroupLabel,
|
|
SidebarHeader,
|
|
SidebarMenu,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
SidebarRail,
|
|
SidebarSeparator,
|
|
} from "@/components/ui/sidebar";
|
|
import { adminNavIconBySegment } from "@/modules/_config/admin-nav-icons";
|
|
import { ADMIN_BASE } from "@/modules/_config/admin-nav";
|
|
import { useAdminProfile } from "@/stores/admin-session";
|
|
|
|
function isActive(pathname: string, item: { href: string; activeMatchPrefix?: string; segment?: string }): boolean {
|
|
const { href, activeMatchPrefix, segment } = item;
|
|
const prefix = activeMatchPrefix ?? href;
|
|
if (prefix === ADMIN_BASE || prefix === `${ADMIN_BASE}/`) {
|
|
return pathname === ADMIN_BASE || pathname === `${ADMIN_BASE}/`;
|
|
}
|
|
// Keep "settings" independent from its child routes like /admin/settings/currencies.
|
|
if (segment === "settings") {
|
|
return pathname === href;
|
|
}
|
|
return pathname === prefix || pathname.startsWith(`${prefix}/`);
|
|
}
|
|
|
|
export function AdminAppSidebar() {
|
|
const { t } = useTranslation(["common", "dashboard", "players", "draws", "config", "wallet", "risk", "settlement", "jackpot", "reconcile", "tickets", "audit"]);
|
|
const pathname = usePathname();
|
|
const profile = useAdminProfile();
|
|
const visibleNav = useMemo(
|
|
() => (profile?.navigation ?? []).filter((item) => item.segment !== "risk"),
|
|
[profile?.navigation],
|
|
);
|
|
|
|
return (
|
|
<Sidebar collapsible="icon" className="overflow-hidden">
|
|
<SidebarHeader className="flex h-14 shrink-0 items-center gap-0 border-b border-sidebar-border p-0 px-2">
|
|
<SidebarMenu className="h-full w-full">
|
|
<SidebarMenuItem className="h-full">
|
|
<SidebarMenuButton
|
|
render={<Link href={ADMIN_BASE} />}
|
|
className="h-full min-h-0 justify-start px-1 py-0 hover:bg-transparent group-data-[collapsible=icon]:justify-center"
|
|
>
|
|
<div className="flex h-12 w-full items-center group-data-[collapsible=icon]:size-10 group-data-[collapsible=icon]:justify-center">
|
|
<img
|
|
src="/logo.png"
|
|
alt="N lotto"
|
|
className="h-auto max-h-11 w-full object-contain object-left group-data-[collapsible=icon]:max-h-8 group-data-[collapsible=icon]:object-center"
|
|
/>
|
|
</div>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
</SidebarHeader>
|
|
<SidebarContent className="relative overflow-hidden">
|
|
<div
|
|
className="pointer-events-none absolute inset-x-0 bottom-0 h-[22rem] opacity-55 group-data-[collapsible=icon]:hidden"
|
|
aria-hidden
|
|
>
|
|
<img
|
|
src="/image6.png"
|
|
alt=""
|
|
className="h-full w-full object-cover object-bottom"
|
|
/>
|
|
<div className="absolute inset-x-0 top-0 h-28 bg-linear-to-b from-sidebar to-transparent" />
|
|
<div className="absolute inset-0 bg-sidebar/20" />
|
|
</div>
|
|
<SidebarGroup>
|
|
<SidebarGroupLabel>{t("sidebar.workspace", { ns: "common", defaultValue: "Workspace" })}</SidebarGroupLabel>
|
|
<SidebarGroupContent>
|
|
<SidebarMenu>
|
|
{visibleNav.map((item) => {
|
|
const Icon = adminNavIconBySegment[item.segment];
|
|
return (
|
|
<SidebarMenuItem key={item.segment}>
|
|
<SidebarMenuButton
|
|
tooltip={t(`nav.${item.segment}`, { ns: "common", defaultValue: item.label })}
|
|
isActive={isActive(pathname, item)}
|
|
render={<Link href={item.href} />}
|
|
className="font-medium text-sidebar-foreground/90 hover:text-sidebar-accent-foreground data-active:bg-red-600 data-active:text-white data-active:shadow-sm"
|
|
>
|
|
<Icon data-icon="inline-start" aria-hidden />
|
|
<span>{t(`nav.${item.segment}`, { ns: "common", defaultValue: item.label })}</span>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
);
|
|
})}
|
|
</SidebarMenu>
|
|
</SidebarGroupContent>
|
|
</SidebarGroup>
|
|
</SidebarContent>
|
|
<SidebarSeparator />
|
|
<SidebarRail />
|
|
</Sidebar>
|
|
);
|
|
}
|