80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { usePathname } from "next/navigation";
|
|
import { canAccess, featureForPath } from "../lib/features";
|
|
import { useFeatureUser } from "./FeatureGate";
|
|
|
|
export default function HeaderActions() {
|
|
const pathname = usePathname();
|
|
const { user, ready } = useFeatureUser();
|
|
const role = user?.role ?? null;
|
|
const showRequestsNav = canAccess(user, "new_requests");
|
|
if (!ready || !user) return null;
|
|
|
|
const roleItems =
|
|
role === null
|
|
? []
|
|
: role === "admin"
|
|
? [
|
|
{
|
|
href: "/profile/invites",
|
|
label: "Invites",
|
|
match: (path: string) => path.startsWith("/profile/invites"),
|
|
},
|
|
{
|
|
href: "/admin",
|
|
label: "Config",
|
|
match: (path: string) => path.startsWith("/admin") || path.startsWith("/users"),
|
|
},
|
|
]
|
|
: [
|
|
{
|
|
href: "/profile/invites",
|
|
label: "Invites",
|
|
match: (path: string) => path.startsWith("/profile/invites"),
|
|
},
|
|
];
|
|
|
|
const commonItems = [
|
|
...(showRequestsNav
|
|
? [
|
|
{
|
|
href: "/new-requests",
|
|
label: "New Requests",
|
|
match: (path: string) => path === "/new-requests",
|
|
},
|
|
]
|
|
: []),
|
|
{
|
|
href: "/",
|
|
label: "My Requests",
|
|
match: (path: string) => path === "/" || path.startsWith("/requests/"),
|
|
},
|
|
{
|
|
href: "/insights",
|
|
label: "My Stats",
|
|
match: (path: string) => path === "/insights" || path.startsWith("/insights/"),
|
|
},
|
|
{
|
|
href: "/portal/issues",
|
|
label: "Issues",
|
|
match: (path: string) => path === "/portal/issues" || path === "/admin/issues",
|
|
},
|
|
];
|
|
|
|
const items = [...commonItems, ...roleItems].filter((item) => canAccess(user, featureForPath(item.href)));
|
|
|
|
return (
|
|
<nav className="header-actions" aria-label="Primary">
|
|
{items.map((item) => {
|
|
const active = item.match(pathname);
|
|
return (
|
|
<a key={item.href} href={item.href} className={active ? "is-active" : undefined}>
|
|
{item.label}
|
|
</a>
|
|
);
|
|
})}
|
|
</nav>
|
|
);
|
|
}
|