Files
star-erp/resources/js/Components/Permission/Can.tsx

85 lines
1.9 KiB
TypeScript

import { usePermission } from '@/hooks/usePermission';
import { ReactNode } from 'react';
interface CanProps {
permission: string | string[];
children: ReactNode;
fallback?: ReactNode;
}
/**
* 權限判斷元件 - 類似 Blade 的 @can 指令
*
* @example
* ```tsx
* <Can permission="products.create">
* <button>新增商品</button>
* </Can>
*
* <Can permission={['products.edit', 'products.delete']}>
* <div>管理操作</div>
* </Can>
* ```
*/
export function Can({ permission, children, fallback = null }: CanProps) {
const { can, canAny } = usePermission();
const hasPermission = Array.isArray(permission)
? canAny(permission)
: can(permission);
return hasPermission ? <>{children}</> : <>{fallback}</>;
}
interface HasRoleProps {
role: string | string[];
children: ReactNode;
fallback?: ReactNode;
}
/**
* 角色判斷元件 - 類似 Blade 的 @role 指令
*
* @example
* ```tsx
* <HasRole role="admin">
* <Link href="/admin">管理後台</Link>
* </HasRole>
*
* <HasRole role={['admin', 'manager']}>
* <button>管理選項</button>
* </HasRole>
* ```
*/
export function HasRole({ role, children, fallback = null }: HasRoleProps) {
const { hasRole, hasAnyRole } = usePermission();
const hasRequiredRole = Array.isArray(role)
? hasAnyRole(role)
: hasRole(role);
return hasRequiredRole ? <>{children}</> : <>{fallback}</>;
}
interface CanAllProps {
permissions: string[];
children: ReactNode;
fallback?: ReactNode;
}
/**
* 檢查是否擁有所有權限
*
* @example
* ```tsx
* <CanAll permissions={['products.edit', 'products.delete']}>
* <button>完整管理</button>
* </CanAll>
* ```
*/
export function CanAll({ permissions, children, fallback = null }: CanAllProps) {
const { canAll } = usePermission();
return canAll(permissions) ? <>{children}</> : <>{fallback}</>;
}