82 lines
1.8 KiB
TypeScript
82 lines
1.8 KiB
TypeScript
import { ReactNode } from "react";
|
|
import { usePermissions } from "@/hooks/usePermissions";
|
|
|
|
interface PermissionGuardProps {
|
|
/**
|
|
* Permission code required to render children
|
|
*/
|
|
permission?: string;
|
|
|
|
/**
|
|
* Array of permission codes - if ANY are matched, children will render
|
|
*/
|
|
anyPermissions?: string[];
|
|
|
|
/**
|
|
* Array of permission codes - ALL must match to render children
|
|
*/
|
|
allPermissions?: string[];
|
|
|
|
/**
|
|
* If true, renders children if the user is an admin
|
|
*/
|
|
adminOnly?: boolean;
|
|
|
|
/**
|
|
* If true, renders children if the user can access the specified page
|
|
*/
|
|
page?: string;
|
|
|
|
/**
|
|
* Fallback component to render if permissions check fails
|
|
*/
|
|
fallback?: ReactNode;
|
|
|
|
/**
|
|
* Children to render if permissions check passes
|
|
*/
|
|
children: ReactNode;
|
|
}
|
|
|
|
/**
|
|
* Component that conditionally renders its children based on user permissions
|
|
*/
|
|
export function PermissionGuard({
|
|
permission,
|
|
anyPermissions,
|
|
allPermissions,
|
|
adminOnly,
|
|
page,
|
|
fallback = null,
|
|
children
|
|
}: PermissionGuardProps) {
|
|
const { hasPermission, hasAnyPermission, hasAllPermissions, hasPageAccess, isAdmin } = usePermissions();
|
|
|
|
// Admin check
|
|
if (adminOnly && !isAdmin) {
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
// Page access check
|
|
if (page && !hasPageAccess(page)) {
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
// Single permission check
|
|
if (permission && !hasPermission(permission)) {
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
// Any permissions check
|
|
if (anyPermissions && !hasAnyPermission(anyPermissions)) {
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
// All permissions check
|
|
if (allPermissions && !hasAllPermissions(allPermissions)) {
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
// If all checks pass, render children
|
|
return <>{children}</>;
|
|
}
|