2026-04-06 15:51:15 +02:00
|
|
|
import { Navigate, Outlet } from 'react-router';
|
2026-04-09 18:28:45 +02:00
|
|
|
import { useAuthStore, useIsAdmin } from './auth-store';
|
2026-04-06 15:51:15 +02:00
|
|
|
|
2026-04-09 18:28:45 +02:00
|
|
|
/**
|
|
|
|
|
* Route guard for admin pages.
|
|
|
|
|
*
|
|
|
|
|
* Redirects non-admin users to '/'. The guard is intentionally lenient when
|
|
|
|
|
* the user is authenticated but their roles array is transiently empty (e.g.
|
|
|
|
|
* during a token refresh). In that case we render nothing rather than
|
|
|
|
|
* navigating away — the refresh will restore the roles within milliseconds and
|
|
|
|
|
* avoid losing unsaved form state on admin pages.
|
|
|
|
|
*/
|
2026-04-06 15:51:15 +02:00
|
|
|
export function RequireAdmin() {
|
|
|
|
|
const isAdmin = useIsAdmin();
|
2026-04-09 18:28:45 +02:00
|
|
|
const roles = useAuthStore((s) => s.roles);
|
|
|
|
|
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
|
|
|
|
|
|
|
|
|
|
// Authenticated but roles not yet populated (token refresh in progress) —
|
|
|
|
|
// render nothing and wait rather than redirecting.
|
|
|
|
|
if (isAuthenticated && roles.length === 0) return null;
|
|
|
|
|
|
2026-04-06 15:51:15 +02:00
|
|
|
if (!isAdmin) return <Navigate to="/" replace />;
|
|
|
|
|
return <Outlet />;
|
|
|
|
|
}
|