Files
EpicNext-Cms/src/components/admin/admin-nav-link.tsx
T
SimoandCursor 363c9b3d56
Local Build and Deploy / deploy (push) Successful in 57s
Reorganize admin into tabbed hubs with a condensed sidebar.
Replace the long flat nav with hub entries, shared AdminHubChrome tabs, and AdminPageShell. Existing URLs stay stable; Settings/Radio and other sections now share one chrome.

Co-authored-by: Cursor <[email protected]>
2026-07-15 21:29:36 +02:00

64 lines
1.9 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import type { ReactNode } from "react";
import { useAdminMobile } from "@/components/admin/admin-mobile-wrapper";
/**
* Sidebar link that highlights when its route is active.
* Optional matchPrefixes cover multi-page hubs (e.g. Settings → theme/vpn).
*/
export function AdminNavLink({
href,
icon,
matchPrefixes,
children,
}: {
href: string;
icon?: ReactNode;
matchPrefixes?: string[];
children: ReactNode;
}) {
const pathname = usePathname() ?? "";
const { close } = useAdminMobile();
let active: boolean;
if (href === "/admin") {
active = pathname === "/admin";
} else if (matchPrefixes?.length) {
active = matchPrefixes.some(
(p) => pathname === p || pathname.startsWith(`${p}/`),
);
} else {
active = pathname === href || pathname.startsWith(`${href}/`);
}
return (
<Link
href={href}
onClick={close}
aria-current={active ? "page" : undefined}
className={`group flex items-center gap-2.5 rounded-xl px-3 py-2 text-sm no-underline transition-colors duration-150
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--admin-accent)] focus-visible:ring-offset-1 focus-visible:ring-offset-[var(--admin-sidebar-background)] ${
active
? "bg-[var(--admin-accent)]/25 font-semibold text-[var(--admin-sidebar-text-readable)] border-l-2 border-[var(--admin-accent)] shadow-sm"
: "font-medium text-[var(--admin-sidebar-text-readable)] hover:bg-[var(--admin-accent)]/10 hover:no-underline"
}`}
>
{icon ? (
<span
className={`flex-none transition-colors ${
active
? "text-[var(--admin-accent)]"
: "text-[var(--admin-sidebar-text-readable)] opacity-75 group-hover:opacity-100"
}`}
>
{icon}
</span>
) : null}
<span className="truncate">{children}</span>
</Link>
);
}