feat: add permission-gated navigation and admin access
This commit is contained in:
22
src/config/app.routes.ts
Normal file
22
src/config/app.routes.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { PERMISSIONS } from '@/constants/permissions';
|
||||
import { ROUTES } from '@/utils/routes';
|
||||
|
||||
export type AppRoute = {
|
||||
path: string;
|
||||
permission?: string;
|
||||
};
|
||||
|
||||
export const appRoutes: AppRoute[] = [
|
||||
{
|
||||
path: ROUTES.ROLES,
|
||||
permission: PERMISSIONS.ROLE.READ,
|
||||
},
|
||||
{
|
||||
path: ROUTES.USERS,
|
||||
permission: PERMISSIONS.USER.READ,
|
||||
},
|
||||
];
|
||||
|
||||
export function getRoutePermission(pathname: string) {
|
||||
return appRoutes.find((route) => route.path === pathname)?.permission;
|
||||
}
|
||||
88
src/config/menu.config.ts
Normal file
88
src/config/menu.config.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import {
|
||||
LayoutDashboard,
|
||||
Layers,
|
||||
Milestone,
|
||||
Package,
|
||||
Plus,
|
||||
Settings,
|
||||
ShieldCheck,
|
||||
Users,
|
||||
} from 'lucide-react';
|
||||
import type { ComponentType, SVGProps } from 'react';
|
||||
|
||||
import { PERMISSIONS } from '@/constants/permissions';
|
||||
import { ROUTES } from '@/utils/routes';
|
||||
|
||||
export type MenuItem = {
|
||||
title: string;
|
||||
path?: string;
|
||||
icon: ComponentType<SVGProps<SVGSVGElement>>;
|
||||
permission?: string;
|
||||
children?: MenuItem[];
|
||||
};
|
||||
|
||||
export const menuItems: MenuItem[] = [
|
||||
{
|
||||
title: 'Dashboard',
|
||||
path: ROUTES.DASHBOARD,
|
||||
icon: LayoutDashboard,
|
||||
},
|
||||
{
|
||||
title: 'New Analysis',
|
||||
path: ROUTES.UPLOAD,
|
||||
icon: Plus,
|
||||
},
|
||||
{
|
||||
title: 'Project',
|
||||
path: ROUTES.PROJECT,
|
||||
icon: Layers,
|
||||
},
|
||||
{
|
||||
title: 'Package',
|
||||
path: ROUTES.PACKAGE,
|
||||
icon: Package,
|
||||
},
|
||||
{
|
||||
title: 'Segment',
|
||||
path: ROUTES.CHAINAGE,
|
||||
icon: Milestone,
|
||||
},
|
||||
{
|
||||
title: 'Administration',
|
||||
icon: Settings,
|
||||
children: [
|
||||
{
|
||||
title: 'Roles',
|
||||
path: ROUTES.ROLES,
|
||||
icon: ShieldCheck,
|
||||
permission: PERMISSIONS.ROLE.READ,
|
||||
},
|
||||
{
|
||||
title: 'Users',
|
||||
path: ROUTES.USERS,
|
||||
icon: Users,
|
||||
permission: PERMISSIONS.USER.READ,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export function filterMenuItems(
|
||||
items: MenuItem[],
|
||||
hasPermission: (permission?: string) => boolean,
|
||||
): MenuItem[] {
|
||||
return items
|
||||
.map((item): MenuItem | null => {
|
||||
if (!hasPermission(item.permission)) return null;
|
||||
|
||||
const children = item.children ? filterMenuItems(item.children, hasPermission) : undefined;
|
||||
|
||||
if (item.children && children?.length === 0 && !item.path) return null;
|
||||
|
||||
return {
|
||||
...item,
|
||||
children,
|
||||
};
|
||||
})
|
||||
.filter((item): item is MenuItem => item !== null);
|
||||
}
|
||||
Reference in New Issue
Block a user