dishplanner/frontend/src/components/layout/AuthGuard.tsx

48 lines
1.8 KiB
TypeScript
Raw Normal View History

2025-10-13 14:57:11 +02:00
'use client';
import { useAuth } from '@/context/AuthContext';
import { useRouter, usePathname } from 'next/navigation';
import React, { useEffect, useState } from 'react';
// Optional Loading spinner component to display while loading
const LoadingSpinner = () => (
<div className="flex justify-center items-center min-h-screen">
<div className="animate-spin w-10 h-10 border-4 border-blue-500 border-t-transparent rounded-full"></div>
</div>
);
export default function AuthGuard({ children }: { children: React.ReactNode }) {
const { isAuthenticated } = useAuth(); // Access the authentication state from AuthContext
const router = useRouter();
const pathname = usePathname();
const [loading, setLoading] = useState(true);
// Define public routes that can be accessed without authentication
const publicRoutes = ['/login', '/register'];
const isPublic = publicRoutes.includes(pathname);
useEffect(() => {
// Determine behavior based on auth state and route type
if (isAuthenticated === null) {
// Await authentication resolution (e.g., token check)
setLoading(true);
} else if (isAuthenticated && isPublic) {
// Redirect authenticated users away from public pages
router.replace('/');
} else if (!isAuthenticated && !isPublic) {
// Redirect unauthenticated users trying to access protected pages
router.replace('/login');
} else {
// Otherwise, stop loading since the state is resolved
setLoading(false);
}
}, [isAuthenticated, pathname, isPublic, router]);
// Show a spinner while authentication state is loading
if (loading) {
return <LoadingSpinner />;
}
// Render children only when the authentication state and path are valid
return <>{children}</>;
}