This commit is contained in:
Tomáš Dvořák
2025-10-16 13:32:05 +02:00
commit 12cba639b9
663 changed files with 168914 additions and 0 deletions
@@ -0,0 +1,57 @@
import { Navigate, useLocation } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
import { useEffect, useState } from 'react';
import { getSetupStatus } from '../services/setup';
interface ProtectedRouteProps {
children: JSX.Element;
requiredRole?: string;
}
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children, requiredRole }) => {
const { isAuthenticated, isLoading, user } = useAuth();
const location = useLocation();
const [checkingSetup, setCheckingSetup] = useState(true);
const [requiresSetup, setRequiresSetup] = useState<boolean>(false);
// Check if setup is required
useEffect(() => {
let mounted = true;
(async () => {
try {
const s = await getSetupStatus();
if (mounted) setRequiresSetup(!!s.requires_setup);
} catch (_) {
if (mounted) setRequiresSetup(false);
} finally {
if (mounted) setCheckingSetup(false);
}
})();
return () => { mounted = false; };
}, []);
if (isLoading || checkingSetup) {
// Show loading spinner or skeleton
return <div>Načítání</div>;
}
// If setup is required, redirect to setup page
if (requiresSetup) {
return <Navigate to="/setup" replace />;
}
if (!isAuthenticated) {
// Redirect to login page, but save the current location
return <Navigate to="/login" state={{ from: location }} replace />;
}
// Role-based access control
if (requiredRole && user && user.role && user.role !== requiredRole && user.role !== 'admin') {
// Redirect to 403 Forbidden page
return <Navigate to="/403" state={{ from: location.pathname }} replace />;
}
return children;
};
export default ProtectedRoute;