/** * Can Component - Permission-based conditional rendering * Wraps children and only renders them if the user has required permissions */ 'use client'; import { ReactNode } from 'react'; import { usePermissions } from '@/lib/hooks/use-permissions'; export interface CanProps { /** * Single permission required to render children * @example "invoice:create" */ permission?: string; /** * Multiple permissions - user must have ANY (OR logic) * @example ["invoice:view", "invoice:create"] */ anyPermission?: string[]; /** * Multiple permissions - user must have ALL (AND logic) * @example ["invoice:view", "approval:approve"] */ allPermissions?: string[]; /** * Single role required to render children * @example "admin" */ role?: string; /** * Multiple roles - user must have ANY (OR logic) * @example ["admin", "manager"] */ anyRole?: string[]; /** * Multiple roles - user must have ALL (AND logic) * @example ["admin", "member"] */ allRoles?: string[]; /** * Render this when user doesn't have permission */ fallback?: ReactNode; /** * Children to render when permission check passes */ children: ReactNode; } /** * Permission wrapper component * * @example * // Single permission * * * * * @example * // Any of multiple permissions * * * * * @example * // All permissions required * * * * * @example * // With fallback * }> * * * * @example * // Role-based * * * */ export function Can({ permission, anyPermission, allPermissions, role, anyRole, allRoles, fallback = null, children, }: CanProps) { const { hasPermission: checkPermission, hasAnyPermission: checkAnyPermission, hasAllPermissions: checkAllPermissions, hasRole: checkRole, hasAnyRole: checkAnyRole, hasAllRoles: checkAllRoles, } = usePermissions(); // Check permission-based conditions if (permission && !checkPermission(permission)) { return <>{fallback}; } if (anyPermission && !checkAnyPermission(anyPermission)) { return <>{fallback}; } if (allPermissions && !checkAllPermissions(allPermissions)) { return <>{fallback}; } // Check role-based conditions if (role && !checkRole(role)) { return <>{fallback}; } if (anyRole && !checkAnyRole(anyRole)) { return <>{fallback}; } if (allRoles && !checkAllRoles(allRoles)) { return <>{fallback}; } // All checks passed, render children return <>{children}; }