initial commit after split

This commit is contained in:
2026-06-24 01:43:10 +02:00
parent b1d6c0150f
commit 30c11a6dcf
173 changed files with 25380 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
import { Settings, Shield } from "lucide-react";
import { NavLink } from "react-router-dom";
import type { AuthInfo, PlatformNavItem } from "../types";
import { adminReadScopes, hasAnyScope, hasScope } from "../utils/permissions";
function visibleNavItems(auth: AuthInfo | null | undefined, navItems: PlatformNavItem[]): PlatformNavItem[] {
return [...navItems]
.sort((left, right) => (left.order ?? 100) - (right.order ?? 100))
.filter((item) => {
if (item.allOf?.length && !item.allOf.every((scope) => hasScope(auth, scope))) return false;
if (item.anyOf?.length && !hasAnyScope(auth, item.anyOf)) return false;
return true;
});
}
export default function IconRail({
compact = false,
auth = null,
navItems = []
}: {
compact?: boolean;
auth?: AuthInfo | null;
navItems?: PlatformNavItem[];
}) {
const visibleItems = visibleNavItems(auth, navItems);
const items = hasAnyScope(auth, adminReadScopes)
? [...visibleItems, { to: "/admin", label: "Admin", icon: Shield }]
: visibleItems;
return (
<aside className={`icon-rail ${compact ? "compact" : ""}`}>
<div className="brand-mark" title="GovOPlaN">G</div>
{!compact && (
<>
<nav className="icon-nav">
{items.map(({ to, label, icon: Icon }) => (
<NavLink key={to} to={to} className={({ isActive }) => `icon-nav-item ${isActive ? "active" : ""}`} title={label}>
{Icon ? <Icon size={20} /> : label.slice(0, 1)}
</NavLink>
))}
</nav>
<div className="icon-rail-bottom">
<NavLink to="/settings" className={({ isActive }) => `icon-nav-item ${isActive ? "active" : ""}`} title="Settings">
<Settings size={20} />
</NavLink>
</div>
</>
)}
</aside>
);
}