Apply linen design system across app

This commit is contained in:
t.indorf
2026-05-20 22:47:52 +02:00
parent 99ff978116
commit 1c5d2f10ac
56 changed files with 4698 additions and 2159 deletions
+46 -26
View File
@@ -1,6 +1,5 @@
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import {
LayoutDashboard,
@@ -15,24 +14,28 @@ import {
Megaphone,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { NavItem } from "@/components/ui/nav-item";
import { UserRole } from "@prisma/client";
const navItems = [
{
section: "Heute",
href: "/dashboard",
label: "Übersicht",
icon: LayoutDashboard,
exact: true,
},
{
section: "Heute",
href: "/dashboard/notdienst",
label: "Notdienst (Eltern)",
icon: CalendarCheck2,
exact: true,
badge: "4",
},
{
section: "Heute",
href: "/dashboard/notdienst/plan",
label: "Notdienst-Planung",
icon: CalendarCheck2,
@@ -40,18 +43,21 @@ const navItems = [
allowedRoles: [UserRole.ADMIN, UserRole.KOORDINATOR],
},
{
section: "Heute",
href: "/dashboard/kalender",
label: "Terminkalender",
icon: CalendarDays,
exact: false,
},
{
section: "Heute",
href: "/dashboard/adressbuch",
label: "Adressbuch",
icon: Contact,
exact: false,
},
{
section: "Verwaltung",
href: "/dashboard/families",
label: "Familienverwaltung",
icon: Users,
@@ -59,6 +65,7 @@ const navItems = [
allowedRoles: [UserRole.ADMIN],
},
{
section: "Verwaltung",
href: "/dashboard/admin/dienste",
label: "Dienstplan",
icon: ClipboardList,
@@ -66,6 +73,7 @@ const navItems = [
allowedRoles: [UserRole.ADMIN],
},
{
section: "Verwaltung",
href: "/dashboard/admin/news",
label: "Schwarzes Brett",
icon: Megaphone,
@@ -73,6 +81,7 @@ const navItems = [
allowedRoles: [UserRole.ADMIN],
},
{
section: "Verwaltung",
href: "/dashboard/admin/kalender",
label: "Event-Anmeldungen",
icon: CalendarCheck2,
@@ -80,6 +89,7 @@ const navItems = [
allowedRoles: [UserRole.ADMIN, UserRole.KOORDINATOR],
},
{
section: "Verwaltung",
href: "/dashboard/admin/abwesenheiten",
label: "Abwesenheiten",
icon: Stethoscope,
@@ -87,6 +97,7 @@ const navItems = [
allowedRoles: [UserRole.ADMIN, UserRole.KOORDINATOR, UserRole.ERZIEHER],
},
{
section: "Verwaltung",
href: "/dashboard/erzieher",
label: "ErzieherInnen",
icon: GraduationCap,
@@ -94,6 +105,7 @@ const navItems = [
allowedRoles: [UserRole.ADMIN],
},
{
section: "Verwaltung",
href: "/dashboard/profil",
label: "Mein Profil",
icon: UserCircle,
@@ -103,32 +115,40 @@ const navItems = [
export function SidebarNav({ role }: { role: UserRole }) {
const pathname = usePathname();
const visibleItems = navItems.filter(
({ allowedRoles }) =>
!allowedRoles || (allowedRoles as UserRole[]).includes(role),
);
const sections = ["Heute", "Verwaltung"];
return (
<nav className="flex flex-col gap-1 px-3">
{navItems.map(({ href, label, icon: Icon, exact, allowedRoles }) => {
// Filter out items not allowed for the current role
if (allowedRoles && !(allowedRoles as UserRole[]).includes(role)) {
return null;
}
const isActive = exact ? pathname === href : pathname.startsWith(href);
return (
<Link
key={href}
href={href}
className={cn(
"flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
isActive
? "bg-primary text-primary-foreground"
: "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
)}
>
<Icon className="h-4 w-4 shrink-0" />
{label}
</Link>
);
})}
<nav className="flex flex-col gap-8 px-5">
{sections.map((section) => (
<div key={section}>
<p className="mb-3 px-2.5 text-[11px] font-semibold uppercase text-[var(--ink-muted)] [letter-spacing:0.18em]">
{section}
</p>
<div className="flex flex-col gap-1">
{visibleItems
.filter((item) => item.section === section)
.map(({ href, label, icon, exact, badge }) => {
const isActive = exact
? pathname === href
: pathname.startsWith(href);
return (
<NavItem
key={href}
href={href}
label={label}
icon={icon}
active={isActive}
badge={badge}
/>
);
})}
</div>
</div>
))}
</nav>
);
}