mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 00:38:11 +00:00
feat: better navigation in backoffice
This commit is contained in:
@@ -1,30 +1,42 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { Navigate } from "react-router-dom";
|
||||
import { Navigate, useLocation } from "react-router-dom";
|
||||
|
||||
import { useAuth } from "@/auth/useAuth";
|
||||
import { resolveLandingPath } from "@/lib/landing";
|
||||
import { hasPermission } from "@/lib/permissions";
|
||||
import NoAccessPage from "@/pages/NoAccessPage";
|
||||
|
||||
interface RequirePermissionProps {
|
||||
/** Permission key(s); access is granted if the user has ANY of them. */
|
||||
permission: string | string[];
|
||||
/** Where to send users who lack the permission. */
|
||||
/** Where to send users who lack the permission. Defaults to their landing page. */
|
||||
redirectTo?: string;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page-level guard: renders children only when the current user holds one of
|
||||
* the given permissions, otherwise redirects (default: overview).
|
||||
* the given permissions, otherwise redirects to a page they can actually reach.
|
||||
*
|
||||
* The fallback must not be a fixed path. It used to be `/dashboard/overview`,
|
||||
* which is itself gated on `overview:view` — a user without that key was sent
|
||||
* to the page that had just rejected them, and React Router rendered a blank
|
||||
* frame instead of navigating.
|
||||
*/
|
||||
export function RequirePermission({
|
||||
permission,
|
||||
redirectTo = "/dashboard/overview",
|
||||
redirectTo,
|
||||
children,
|
||||
}: RequirePermissionProps) {
|
||||
const { user } = useAuth();
|
||||
const location = useLocation();
|
||||
const keys = Array.isArray(permission) ? permission : [permission];
|
||||
const allowed = keys.some((key) => hasPermission(user, key));
|
||||
|
||||
if (!allowed) return <Navigate to={redirectTo} replace />;
|
||||
return <>{children}</>;
|
||||
if (allowed) return <>{children}</>;
|
||||
|
||||
const target = redirectTo ?? resolveLandingPath(user);
|
||||
// Belt and braces: never navigate to the page we are already on.
|
||||
if (target === location.pathname) return <NoAccessPage />;
|
||||
return <Navigate to={target} replace />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user