"use client"; import React from "react"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { FeatherBell, FeatherHelpCircle, FeatherSearch } from "@subframe/core"; import { SidebarWithSections } from "@/ui/components/SidebarWithSections"; import { NAV_GRUPPEN, NAV_SEKUNDAER, ANALYSE_SEITEN, type NavEintrag } from "./navigation"; import { FeatherIcon } from "./FeatherIcon"; import { useToast } from "../../context/ToastContext"; import { DATENSATZ_INFO } from "../../data/seed"; import { formatDatum, formatZahl } from "../../utils/formatters"; import { HEUTE } from "../../utils/dateUtils"; /** * Rahmen der Anwendung — Seitenleiste nach dem Vorbild von HiveGrid Cloud. * * Bewusst dieselbe Komponente wie dort (`~/ui/components/SidebarWithSections`) * mit denselben Gruppen und derselben Reihenfolge. Wer den Prototyp neben der * Software öffnet, soll dieselbe Navigation sehen; die Übergabe wird dadurch * eine Frage des Einsetzens und nicht des Übersetzens. * * **Nur „Analytics" führt hier irgendwohin.** Die übrigen Einträge zeigen den * Ort in der fertigen Anwendung und melden beim Klick, dass sie zur Software * gehören — eine tote Schaltfläche ohne Rückmeldung wäre schlechter als gar * keine. */ export function AppShell({ children }: { children: React.ReactNode }) { const pathname = usePathname(); const { zeigeToast } = useToast(); const [eingeklappt, setEingeklappt] = React.useState(false); const istAktiv = (eintrag: NavEintrag) => eintrag.ziel.art === "route" && (eintrag.ziel.href === "/analytics" ? pathname.startsWith("/analytics") : pathname.startsWith(eintrag.ziel.href)); const renderEintrag = (eintrag: NavEintrag) => { const item = ( } selected={istAktiv(eintrag)} variant={eingeklappt ? "icon-only" : "icon-and-text"} > {eintrag.label} ); if (eintrag.ziel.art === "route") { return ( {item} ); } return ( ); }; const aktiveAnalyse = ANALYSE_SEITEN.find((s) => s.href === "/analytics" ? pathname === "/analytics" : pathname.startsWith(s.href) ); const bereich = pathname.startsWith("/komponenten") ? "Komponenten" : "Analytics"; return (
setEingeklappt((wert) => !wert)} toggleLabel={eingeklappt ? "Seitenleiste ausklappen" : "Seitenleiste einklappen"} >
{NAV_GRUPPEN.map((gruppe) => ( {gruppe.eintraege.map(renderEintrag)} ))}
{NAV_SEKUNDAER.map(renderEintrag)} {/* Einzeilig statt als Kasten: Die Seitenleiste soll die der Software spiegeln, und dort steht kein Demo-Hinweis. Die Information bleibt, nimmt aber keinen Navigationsplatz weg. */} {!eingeklappt ? (

Demo-Daten · {formatZahl(DATENSATZ_INFO.auftraege)} Aufträge ·{" "} {formatDatum(HEUTE.toISOString())}

) : null}
{bereich} {aktiveAnalyse ? ( <> / {aktiveAnalyse.label} ) : null}
Suchen ⌘K
MK
{children}
); }