You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
1.7 KiB
TypeScript

'use client';
import { useEffect, ReactNode } from 'react';
import { useRouter } from 'next/navigation';
import { useSwissOIDAuth } from 'swissoid-front';
import { Loader2 } from 'lucide-react';
import useTranslation from '@/src/hooks/useTranslation';
interface AdminAuthGuardProps {
children: ReactNode;
}
/**
* Auth guard for /admin routes
* Redirects unauthenticated users to login while preserving locale
*/
export default function AdminAuthGuard({ children }: AdminAuthGuardProps) {
const { user, loading } = useSwissOIDAuth();
const router = useRouter();
const { locale, t } = useTranslation();
useEffect(() => {
if (!loading && !user) {
// Build login URL with locale-aware return path
const loginUrl = process.env.NEXT_PUBLIC_AUTH_BACKEND_URL
? `${process.env.NEXT_PUBLIC_AUTH_BACKEND_URL}/login`
: '/login';
// Redirect to login
window.location.href = loginUrl;
}
}, [user, loading, locale, router]);
// Show loading state while checking auth
if (loading) {
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<Loader2 className="w-12 h-12 text-indigo-600 animate-spin mb-4" />
<p className="text-gray-600">{t('Checking authentication...')}</p>
</div>
);
}
// Show loading state while redirecting
if (!user) {
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<Loader2 className="w-12 h-12 text-indigo-600 animate-spin mb-4" />
<p className="text-gray-600">{t('Redirecting to login...')}</p>
</div>
);
}
// User is authenticated, render children
return <>{children}</>;
}