forked from baron/baron-sso
41 lines
873 B
TypeScript
41 lines
873 B
TypeScript
import { useQuery } from "@tanstack/react-query";
|
|
import type * as React from "react";
|
|
import { fetchMe } from "../../lib/adminApi";
|
|
|
|
interface RoleGuardProps {
|
|
children: React.ReactNode;
|
|
roles: string[];
|
|
fallback?: React.ReactNode;
|
|
}
|
|
|
|
/**
|
|
* RoleGuard conditionally renders children based on the current user's role.
|
|
*
|
|
* Usage:
|
|
* <RoleGuard roles={['super_admin']}>
|
|
* <button>System Only Action</button>
|
|
* </RoleGuard>
|
|
*/
|
|
export function RoleGuard({
|
|
children,
|
|
roles,
|
|
fallback = null,
|
|
}: RoleGuardProps) {
|
|
const { data: profile, isLoading } = useQuery({
|
|
queryKey: ["me"],
|
|
queryFn: fetchMe,
|
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
});
|
|
|
|
if (isLoading) return null;
|
|
|
|
const userRole = profile?.role || "user";
|
|
const hasAccess = roles.includes(userRole);
|
|
|
|
if (!hasAccess) {
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
return <>{children}</>;
|
|
}
|