diff --git a/apps/web/src/app/[locale]/login/page.tsx b/apps/web/src/app/[locale]/login/page.tsx index a7acd1e..f1b8d6e 100644 --- a/apps/web/src/app/[locale]/login/page.tsx +++ b/apps/web/src/app/[locale]/login/page.tsx @@ -3,7 +3,7 @@ import { signIn, useSession } from 'next-auth/react'; import { useRouter, useSearchParams } from 'next/navigation'; import { useTranslations } from 'next-intl'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { motion } from 'framer-motion'; import { Loader2, KeyRound } from 'lucide-react'; @@ -16,7 +16,7 @@ interface LoginPageProps { /** * Login page component - * Handles authentication via Keycloak + * Automatically redirects to Keycloak. Only shows UI on auth errors. */ export default function LoginPage({ params: { locale } }: LoginPageProps) { const { status } = useSession(); @@ -24,6 +24,7 @@ export default function LoginPage({ params: { locale } }: LoginPageProps) { const searchParams = useSearchParams(); const t = useTranslations('auth'); const [isLoading, setIsLoading] = useState(false); + const autoSignInTriggered = useRef(false); const callbackUrl = searchParams.get('callbackUrl') || `/${locale}/dashboard`; const error = searchParams.get('error'); @@ -35,6 +36,14 @@ export default function LoginPage({ params: { locale } }: LoginPageProps) { } }, [status, router, callbackUrl]); + // Auto-redirect to Keycloak if no error + useEffect(() => { + if (status === 'unauthenticated' && !error && !autoSignInTriggered.current) { + autoSignInTriggered.current = true; + signIn('keycloak', { callbackUrl }); + } + }, [status, error, callbackUrl]); + const handleLogin = async () => { setIsLoading(true); try { @@ -44,8 +53,8 @@ export default function LoginPage({ params: { locale } }: LoginPageProps) { } }; - // Show loading state while checking session - if (status === 'loading') { + // Show loading spinner during auto-redirect or session check + if (!error) { return (