/** * ProtectedRoute Component * Guards routes that require authentication with role-based access control * Based on gamilit implementation */ import { Navigate, useLocation } from 'react-router-dom'; import { useAuthStore } from '../../stores/authStore'; import { LoadingSpinner } from '../common/LoadingSpinner'; interface ProtectedRouteProps { children: React.ReactNode; /** Roles allowed to access this route */ allowedRoles?: string[]; /** Custom redirect path for unauthenticated users */ redirectTo?: string; } export function ProtectedRoute({ children, allowedRoles, redirectTo = '/auth/login', }: ProtectedRouteProps) { const user = useAuthStore((state) => state.user); const isAuthenticated = useAuthStore((state) => state.isAuthenticated); const isLoading = useAuthStore((state) => state.isLoading); const isInitialized = useAuthStore((state) => state.isInitialized); const checkSession = useAuthStore((state) => state.checkSession); const location = useLocation(); // Show loading while checking auth state if (isLoading || !isInitialized) { return (

Verificando sesión...

); } // Check if session is still valid const sessionValid = checkSession(); // Not authenticated - redirect to login if (!isAuthenticated || !sessionValid) { return ( ); } // Check role-based access if roles are specified if (allowedRoles && allowedRoles.length > 0) { const userRole = user?.role || ''; const hasRequiredRole = allowedRoles.includes(userRole); if (!hasRequiredRole) { // User doesn't have required role - redirect to unauthorized page return ( ); } } // User is authenticated and has required role return <>{children}; } /** * PublicRoute Component * Redirects authenticated users away from public pages (login, register) */ interface PublicRouteProps { children: React.ReactNode; /** Where to redirect authenticated users */ redirectTo?: string; } export function PublicRoute({ children, redirectTo = '/admin/dashboard', }: PublicRouteProps) { const isAuthenticated = useAuthStore((state) => state.isAuthenticated); const isLoading = useAuthStore((state) => state.isLoading); const isInitialized = useAuthStore((state) => state.isInitialized); const location = useLocation(); // Show loading while checking auth state if (isLoading || !isInitialized) { return (
); } // If user is already authenticated, redirect to dashboard if (isAuthenticated) { // Check if there's a "from" location to redirect back to const from = (location.state as { from?: Location })?.from?.pathname || redirectTo; return ; } return <>{children}; } export default ProtectedRoute;