49 lines
1.0 KiB
TypeScript
49 lines
1.0 KiB
TypeScript
import { Navigate } from 'react-router-dom';
|
|
import { Spin, Result } from 'antd';
|
|
import { useAuthStore } from '@/stores/auth.store';
|
|
import { hasAnyRole } from '@/utils/roles';
|
|
import type { UserRole } from '@/types/api';
|
|
|
|
interface ProtectedRouteProps {
|
|
children: React.ReactNode;
|
|
requiredRoles?: UserRole[];
|
|
}
|
|
|
|
export default function ProtectedRoute({
|
|
children,
|
|
requiredRoles,
|
|
}: ProtectedRouteProps) {
|
|
const { isAuthenticated, isLoading, user } = useAuthStore();
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
height: '100vh',
|
|
}}
|
|
>
|
|
<Spin size="large" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!isAuthenticated) {
|
|
return <Navigate to="/login" replace />;
|
|
}
|
|
|
|
if (requiredRoles && user && !hasAnyRole(user, requiredRoles)) {
|
|
return (
|
|
<Result
|
|
status="403"
|
|
title="403"
|
|
subTitle="You do not have permission to access this page."
|
|
/>
|
|
);
|
|
}
|
|
|
|
return <>{children}</>;
|
|
}
|