almeira-web/src/components/publications/PermissionGuard.tsx
Carlos (Almeira) dda9ae0f4a feat: implement robust publications module with real-time validation and state management
- Refactor dashboard entity pages to support dynamic publications management.
- Add Publications Module with Atomic Design components (PostCard, PublicationsList, FormSection).
- Implement Zod-based real-time validation for publication forms.
- Manage state using Zustand for optimistic UI and in-place relations.
- Add RBAC protection with PermissionGuard and server-side API validation.
- Fix: Resolve TypeScript type error in AdWrappers.tsx to ensure successful build.
- Add ToastProvider and ErrorBoundary for improved user experience.
- Update dependencies for publications logic.
2026-03-28 08:47:40 -05:00

54 lines
1.4 KiB
TypeScript

'use client';
/**
* @file PermissionGuard.tsx
* @description Role-Based Access Control (RBAC) HOC/Wrapper component.
* Only renders children if the user's role is in the allowedRoles list.
* Use this to protect any UI element that requires authorization.
*
* @example
* // Only admins and editors can see the edit button
* <PermissionGuard allowedRoles={['admin', 'editor']} userRole={user.prefs.role}>
* <button onClick={handleEdit}>Editar</button>
* </PermissionGuard>
*/
import React from 'react';
import { PermissionGuardProps, UserRole } from '@/types/publications';
/** Priority order of roles (higher index = more permissions) */
const ROLE_HIERARCHY: Record<UserRole, number> = {
guest: 0,
viewer: 1,
editor: 2,
admin: 3,
};
/**
* Checks if a given role meets the minimum required role.
*/
export function hasPermission(userRole: UserRole, allowedRoles: UserRole[]): boolean {
return allowedRoles.some(
(allowed) => ROLE_HIERARCHY[userRole] >= ROLE_HIERARCHY[allowed]
);
}
/**
* PermissionGuard — Renders children only if userRole is in allowedRoles.
* Renders `fallback` (or null) otherwise.
*/
export const PermissionGuard: React.FC<PermissionGuardProps> = ({
allowedRoles,
userRole,
children,
fallback = null,
}) => {
if (!hasPermission(userRole, allowedRoles)) {
return <>{fallback}</>;
}
return <>{children}</>;
};
export default PermissionGuard;