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
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}</>;
|
|
}
|