feat(admin): reorganize housekeeping and strengthen shared workflows
CI / check (push) Successful in 1m5s
CI / deploy (push) Successful in 1m4s

This commit is contained in:
Simo committed 2026-09-06 17:17:30 +02:00
1 parent 35f66d879f
commit a070004e7b
35 files changed
+1667 -462

No files matched your search

+16 -25
View File
@@ -11,16 +11,11 @@ import { usePathname } from "next/navigation";
import { useTranslations } from "next-intl";
import { useCallback, useEffect, useMemo, useState } from "react";
import { AdminNavLink } from "@/components/admin/admin-nav-link";
import {
ADMIN_NAV_GROUPS,
type AdminNavItem,
navItemIsAllowed,
} from "@/lib/admin-nav";
import {
type AdminNavConfig,
applyAdminNavConfig,
} from "@/lib/admin-nav-config";
import type { AdminNavItem } from "@/lib/admin-nav";
import type { AdminNavConfig } from "@/lib/admin-nav-config";
import { visibleAdminNavigation } from "@/lib/admin-navigation";
import { cn } from "@/lib/utils";
import { AdminFavorites } from "./admin-favorites";
const STORAGE_KEY = "admin-nav-collapsed";
@@ -67,10 +62,12 @@ function persistCollapsed(next: Record<string, boolean>) {
}
export function AdminSidebarNav({
userId = 0,
allowedPermissions = [],
isSuperAdmin = false,
navConfig = {},
}: {
userId?: number;
/** ACL slugs the staff member holds (ignored when isSuperAdmin). */
allowedPermissions?: string[];
isSuperAdmin?: boolean;
@@ -83,24 +80,12 @@ export function AdminSidebarNav({
const [hydrated, setHydrated] = useState(false);
const [query, setQuery] = useState("");
const allowed = useMemo(
() => new Set(allowedPermissions),
[allowedPermissions],
const groups = useMemo(
() =>
visibleAdminNavigation({ allowedPermissions, isSuperAdmin, navConfig }),
[allowedPermissions, isSuperAdmin, navConfig],
);
const groups = useMemo(() => {
const access = {
isSuperAdmin,
has: (slug: string) => allowed.has(slug),
};
return applyAdminNavConfig(ADMIN_NAV_GROUPS, navConfig)
.map((group) => ({
...group,
items: group.items.filter((item) => navItemIsAllowed(item, access)),
}))
.filter((group) => group.items.length > 0);
}, [allowed, isSuperAdmin, navConfig]);
const search = query.trim().toLocaleLowerCase();
const visibleGroups = useMemo(
() =>
@@ -278,6 +263,12 @@ export function AdminSidebarNav({
</div>
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain px-3 py-3">
{!search && (
<AdminFavorites
userId={userId}
items={groups.flatMap((group) => group.items)}
/>
)}
{visibleGroups.length === 0 && (
<p
role="status"