refactor(modules): consolidate nav into a module registry
Extend lib/modules.ts into an ordered ModuleDef registry (id/label/icon/ system/badge/gate) as the single source for the nav rail and the header stepper. Absorb NavSidebar's per-page ICON map; derive moduleOrder / moduleLabelKey / SYSTEM_PAGES from the one array. Render still on the App ternary — this is the scaffold S6b.3 will drive from. (Platform S6b.1)
This commit is contained in:
@@ -4,32 +4,21 @@ import { useTranslation } from "react-i18next";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useNavigation, useNavigationActions } from "./NavigationProvider";
|
||||
import {
|
||||
Activity,
|
||||
BarChart3,
|
||||
Bell,
|
||||
Clapperboard,
|
||||
Download,
|
||||
Home,
|
||||
Info,
|
||||
ListVideo,
|
||||
LogOut,
|
||||
MessageSquare,
|
||||
Pin,
|
||||
PinOff,
|
||||
ScrollText,
|
||||
Settings,
|
||||
Shield,
|
||||
SlidersHorizontal,
|
||||
Users,
|
||||
Tv,
|
||||
UserPlus,
|
||||
type LucideIcon,
|
||||
} from "lucide-react";
|
||||
import { api, clearActiveAccount, setActiveAccount, type Me } from "../lib/api";
|
||||
import * as e2ee from "../lib/e2ee";
|
||||
import { useLiveQuery } from "../lib/useLiveQuery";
|
||||
import { getUnreadCount, subscribe } from "../lib/notifications";
|
||||
import type { Page } from "../lib/urlState";
|
||||
import { moduleLabelKey, moduleOrder, SYSTEM_PAGES } from "../lib/modules";
|
||||
import { moduleDef, moduleLabelKey, moduleOrder, SYSTEM_PAGES } from "../lib/modules";
|
||||
import { useScrollFade } from "../lib/useScrollFade";
|
||||
import { useHoverFocusWithin } from "../lib/useHoverFocusWithin";
|
||||
import { type LangCode } from "../i18n";
|
||||
@@ -177,34 +166,18 @@ export default function NavSidebar({
|
||||
// also used by the side panels) so a high-zoom overflow scrolls without a scrollbar.
|
||||
const listFade = useScrollFade();
|
||||
|
||||
type NavItem = { page: Page; icon: typeof Home; label: string; badge?: number };
|
||||
// Per-page presentation (icon/label/badge). WHICH pages appear and in what order comes from the
|
||||
// shared moduleOrder(me) — the same source the header's ◀/▶ stepper uses — so the two never drift
|
||||
// and a new/gated module updates both at once. Badges live here (nav-only concern).
|
||||
// Icon + badge per page; the label comes from the shared moduleLabelKey so the rail and the
|
||||
// header's ModuleName pill always read the same name.
|
||||
const ICON: Record<Page, typeof Home> = {
|
||||
feed: Home,
|
||||
channels: Tv,
|
||||
playlists: ListVideo,
|
||||
plex: Clapperboard,
|
||||
notifications: Bell,
|
||||
messages: MessageSquare,
|
||||
downloads: Download,
|
||||
stats: BarChart3,
|
||||
scheduler: Activity,
|
||||
config: SlidersHorizontal,
|
||||
users: Users,
|
||||
audit: ScrollText,
|
||||
settings: Settings,
|
||||
};
|
||||
type NavItem = { page: Page; icon: LucideIcon; label: string; badge?: number };
|
||||
// Per-page presentation (icon/label/badge). WHICH pages appear and in what order — and each
|
||||
// module's icon + label — come from the shared module registry (the same source the header's
|
||||
// ◀/▶ stepper uses), so the two never drift and a new/gated module updates both at once. The
|
||||
// badge NUMBERS are the only nav-only concern (they need the live polling queries above).
|
||||
const BADGE: Partial<Record<Page, number>> = {
|
||||
notifications: unread,
|
||||
messages: msgUnread,
|
||||
downloads: dlActive,
|
||||
};
|
||||
const META = (p: Page): Omit<NavItem, "page"> => ({
|
||||
icon: ICON[p],
|
||||
icon: moduleDef(p).icon,
|
||||
label: t(moduleLabelKey[p]),
|
||||
badge: BADGE[p],
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user