deckhearth/components/ProtectedRoute.js

57 lines
1.8 KiB
JavaScript
Raw Permalink Normal View History

import { useEffect } from 'react';
import { useRouter } from 'next/router';
import { useAuth } from '../lib/use-auth';
import Layout from './Layout';
export default function ProtectedRoute({ children, adminOnly = false, allowPublic = false, publicFallback = null }) {
const { user, loading } = useAuth();
const router = useRouter();
useEffect(() => {
if (!loading) {
// If authentication is required and user is not logged in
if (!allowPublic && !user) {
router.push('/login');
return;
}
// If admin access is required and user is not admin
if (adminOnly && (!user || user.role !== 'admin')) {
router.push('/login');
return;
}
}
}, [user, loading, router, adminOnly, allowPublic]);
// Show loading while checking authentication
if (loading) {
return (
<Layout user={null}>
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<div className="animate-spin rounded-full h-32 w-32 border-b-2 mx-auto mb-4" style={{ borderColor: 'var(--accent-ember)' }}></div>
<p style={{ color: 'var(--text-secondary)' }}>Loading...</p>
</div>
</div>
</Layout>
);
}
// If public access is allowed but user is not logged in, show public fallback
if (allowPublic && !user && publicFallback) {
return publicFallback;
}
// If authentication is required but user is not logged in, don't render anything (redirect will happen)
if (!allowPublic && !user) {
return null;
}
// If admin access is required but user is not admin, don't render anything (redirect will happen)
if (adminOnly && (!user || user.role !== 'admin')) {
return null;
}
// Render the protected content
return children;
}