import { FormEvent, useEffect, useMemo, useState } from 'react'; import type { ReactNode } from 'react'; import { Head, useForm } from '@inertiajs/react'; import { useTranslation } from 'react-i18next'; import InputError from '@/components/input-error'; import TextLink from '@/components/text-link'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import AuthLayout from '@/layouts/auth-layout'; import AppLayout from '@/layouts/app/AppLayout'; import { register } from '@/routes'; import { request } from '@/routes/password'; import { LoaderCircle } from 'lucide-react'; interface LoginProps { status?: string; canResetPassword: boolean; } export default function Login({ status, canResetPassword }: LoginProps) { const [hasTriedSubmit, setHasTriedSubmit] = useState(false); const [rawReturnTo, setRawReturnTo] = useState(null); const [isRedirectingToGoogle, setIsRedirectingToGoogle] = useState(false); const { t } = useTranslation('auth'); const { data, setData, post, processing, errors, clearErrors } = useForm({ login: '', password: '', remember: false, return_to: '', }); const submit = (e: FormEvent) => { e.preventDefault(); setHasTriedSubmit(true); post(window.location.pathname, { preserveScroll: true, }); }; const errorKeys = Object.keys(errors); const hasErrors = errorKeys.length > 0; useEffect(() => { if (typeof window === 'undefined') { return; } const searchParams = new URLSearchParams(window.location.search); setRawReturnTo(searchParams.get('return_to')); }, []); useEffect(() => { setData('return_to', rawReturnTo ?? ''); }, [rawReturnTo, setData]); useEffect(() => { if (!hasTriedSubmit) { return; } const keys = Object.keys(errors); if (keys.length === 0) { return; } const field = document.querySelector(`[name="${keys[0]}"]`); if (field) { field.scrollIntoView({ behavior: 'smooth', block: 'center' }); field.focus(); } }, [errors, hasTriedSubmit]); const googleHref = useMemo(() => { if (!rawReturnTo) { return '/event-admin/auth/google'; } const params = new URLSearchParams({ return_to: rawReturnTo, }); return `/event-admin/auth/google?${params.toString()}`; }, [rawReturnTo]); const handleGoogleLogin = () => { if (typeof window === 'undefined') { return; } setIsRedirectingToGoogle(true); window.location.href = googleHref; }; return (
{ setData('login', e.target.value); if (errors.login) { clearErrors('login'); } }} className="h-12 rounded-xl border-gray-200/80 bg-white/90 px-4 text-base shadow-inner shadow-gray-200/40 focus-visible:ring-[#ff8bb1]/40 dark:border-gray-800/70 dark:bg-gray-900/60 dark:text-gray-100" />
{canResetPassword && ( {t('login.forgot')} )}
{ setData('password', e.target.value); if (errors.password) { clearErrors('password'); } }} className="h-12 rounded-xl border-gray-200/80 bg-white/90 px-4 text-base shadow-inner shadow-gray-200/40 focus-visible:ring-[#ff8bb1]/40 dark:border-gray-800/70 dark:bg-gray-900/60 dark:text-gray-100" />
setData('remember', Boolean(checked))} />
{status && (
{status}
)} {hasErrors && (
{Object.values(errors).join(' ')}
)}
{t('login.oauth_divider', 'oder')}

{t('login.google_helper', 'Nutze dein Google-Konto, um dich sicher bei der Eventverwaltung anzumelden.')}

{t('login.no_account')}{' '} {t('login.sign_up')}
); } Login.layout = (page: ReactNode) => }>{page}; function GoogleIcon({ className }: { className?: string }) { return ( ); }