'use client'; import Link from 'next/link'; import { Suspense, type FormEvent, useEffect, useMemo, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { AuthShell } from '@/components/auth/auth-shell'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { authClient } from '@/lib/auth-client'; function sanitizeNextPath(value: string | null) { if (!value || !value.startsWith('/')) { return '/'; } return value; } export default function SignInPage() { return ( Loading sign in...}> ); } function SignInPageContent() { const router = useRouter(); const searchParams = useSearchParams(); const nextPath = useMemo(() => sanitizeNextPath(searchParams.get('next')), [searchParams]); const { data: rawSession, isPending } = authClient.useSession(); const session = (rawSession ?? null) as { user?: { id?: string } } | null; const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(null); const [message, setMessage] = useState(null); const [busyAction, setBusyAction] = useState<'password' | 'magic' | null>(null); useEffect(() => { if (!isPending && session?.user?.id) { router.replace(nextPath); } }, [isPending, nextPath, router, session]); const signInWithPassword = async (event: FormEvent) => { event.preventDefault(); setError(null); setMessage(null); setBusyAction('password'); const { error: signInError } = await authClient.signIn.email({ email: email.trim(), password, callbackURL: nextPath }); setBusyAction(null); if (signInError) { setError(signInError.message || 'Sign in failed.'); return; } router.replace(nextPath); }; const signInWithMagicLink = async () => { const targetEmail = email.trim(); if (!targetEmail) { setError('Email is required for magic link sign in.'); return; } setError(null); setMessage(null); setBusyAction('magic'); const { error: magicError } = await authClient.signIn.magicLink({ email: targetEmail, callbackURL: nextPath }); setBusyAction(null); if (magicError) { setError(magicError.message || 'Unable to send magic link.'); return; } setMessage('Magic link sent. Check your inbox and open the link on this device.'); }; return ( Need an account?{' '} Create one )} >
setEmail(event.target.value)} required />
setPassword(event.target.value)} required />
{error ?

{error}

: null} {message ?

{message}

: null}
); }