feat(rbac): add roles and permissions

This commit is contained in:
Schubert Ferenc 2026-07-02 23:05:59 +02:00
parent 86a32a942c
commit 694b7bd09a
37 changed files with 2682 additions and 218 deletions

View file

@ -1,14 +1,22 @@
"use client";
import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import {
FileText,
LayoutDashboard,
Package,
Settings,
Shield,
ShoppingCart,
Users,
Wrench,
Package,
FileText,
Settings,
ShoppingCart,
} from "lucide-react";
import { api } from "@/lib/api";
import { hasPermission } from "@/lib/permissions";
import type { CurrentUser, PermissionName } from "@/types/rbac";
const menu = [
{
icon: LayoutDashboard,
@ -19,6 +27,13 @@ const menu = [
icon: Users,
name: "Benutzer",
href: "/users",
permission: "users.read",
},
{
icon: Shield,
name: "Rollen & Rechte",
href: "/roles",
permission: "roles.read",
},
{
icon: Users,
@ -50,21 +65,45 @@ const menu = [
name: "Einstellungen",
href: "/settings",
},
];
] satisfies Array<{
icon: typeof LayoutDashboard;
name: string;
href: string;
permission?: PermissionName;
}>;
export default function Sidebar() {
const [currentUser, setCurrentUser] = useState<CurrentUser | null>(null);
const loadCurrentUser = useCallback(async () => {
try {
const response = await api.get<CurrentUser>("/me");
setCurrentUser(response.data);
} catch {
setCurrentUser(null);
}
}, []);
useEffect(() => {
queueMicrotask(() => {
void loadCurrentUser();
});
}, [loadCurrentUser]);
const visibleMenu = menu.filter((item) => (
!item.permission || hasPermission(currentUser, item.permission)
));
return (
<aside className="w-64 h-screen bg-slate-900 text-white flex flex-col">
<div className="p-6 border-b border-slate-800">
<h1 className="text-3xl font-bold">
🏛 Olympus
Olympus
</h1>
</div>
<nav className="flex-1 p-4 space-y-2">
{menu.map((item) => (
{visibleMenu.map((item) => (
<Link
key={item.name}
href={item.href}
@ -74,13 +113,11 @@ export default function Sidebar() {
<span>{item.name}</span>
</Link>
))}
</nav>
<div className="border-t border-slate-800 p-4 text-sm text-slate-400">
Olympus ERP v0.1
Olympus CRM v0.1
</div>
</aside>
);
}