diff --git a/src/layout/AppShell.tsx b/src/layout/AppShell.tsx index 28ad39a..864187a 100644 --- a/src/layout/AppShell.tsx +++ b/src/layout/AppShell.tsx @@ -1,11 +1,6 @@ "use client"; -import React, { createContext, useContext } from "react"; - -import { Navbar } from "./Navbar"; -import { Sidebar, type SidebarNavItem } from "./Sidebar"; -import { Footer, type FooterNavItem } from "./Footer"; -import { PageShell } from "./PageShell"; +import React, { createContext, useContext, useEffect, useState } from "react"; // ─── ShellConfig types ──────────────────────────────────────────────────────── // @@ -62,13 +57,13 @@ const ShellContext = createContext(null); /** Read the current ShellConfig from anywhere inside . */ export function useShell(): ShellConfig { const cfg = useContext(ShellContext); - if (!cfg) { - throw new Error("useShell must be used inside "); - } + if (!cfg) throw new Error("useShell must be used inside "); return cfg; } -// ─── AppShell — pure renderer ───────────────────────────────────────────────── +// ─── AppShell — chronos-style detached layout, parameterized by ShellConfig ─── + +const SIDEBAR_COLLAPSED_KEY = "gsc-shell-sidebar-collapsed"; export type AppShellProps = { /** @@ -87,14 +82,11 @@ export type AppShellProps = { /** Optional: signs the user out. Hook this up to your NextAuth/Keycloak signout. */ onSignOut?: () => void; - /** Optional content for the slot (breadcrumbs, page title, etc.). */ - pageHeader?: React.ReactNode; + /** Optional: extra elements (notifications, search, etc.) injected into the right of the navbar. */ + navbarExtras?: React.ReactNode; /** Page content. */ children: React.ReactNode; - - /** Optional className on the outer wrapper. */ - className?: string; }; export function AppShell({ @@ -102,139 +94,357 @@ export function AppShell({ currentPath, translate, onSignOut, - pageHeader, - className, + navbarExtras, children, }: AppShellProps) { const t = translate ?? ((k: string) => k); const path = currentPath ?? (typeof window !== "undefined" ? window.location.pathname : "/"); - const sidebarItems = (config.menus.sidebar ?? []).map((m) => toSidebarNavItem(m, path, t)); - const footerNavItems: FooterNavItem[] = (config.menus.footer ?? []).map((m) => ({ - label: t(m.translationKey), - href: m.href, - icon: m.icon ? : undefined, - })); - - const navbarBrand = ( - - - {config.branding.productName} - - ); - - const userMenuItems = (config.menus["user-menu"] ?? []).map((m) => { - const isLogout = m.key === "logout"; - return ( - { e.preventDefault(); onSignOut(); } : undefined} - > - {m.icon ? : null} - {t(m.translationKey)} - - ); - }); - - const navbarEnd = ( -
    -
  • - -
    {userMenuItems}
    -
  • -
- ); - return ( - - } - pageHeader={pageHeader} - mainSidebar={ - - } - footer={ -