nicer package layout, also in checkout step 1, fixed missing registration language strings, registration error handling, email verification redirect, email verification error handling and messaging,

This commit is contained in:
Codex Agent
2025-11-19 20:21:54 +01:00
parent 91d3e61b0e
commit 8d2075bdd2
24 changed files with 1000 additions and 363 deletions

View File

@@ -1,6 +1,6 @@
import { FormEvent, useEffect, useMemo, useState } from 'react';
import type { ReactNode } from 'react';
import { Head, useForm } from '@inertiajs/react';
import { Head, useForm, usePage } from '@inertiajs/react';
import { useTranslation } from 'react-i18next';
import InputError from '@/components/input-error';
import TextLink from '@/components/text-link';
@@ -13,6 +13,7 @@ import AppLayout from '@/layouts/app/AppLayout';
import { register } from '@/routes';
import { request } from '@/routes/password';
import { LoaderCircle } from 'lucide-react';
import toast from 'react-hot-toast';
interface LoginProps {
status?: string;
@@ -24,6 +25,8 @@ export default function Login({ status, canResetPassword }: LoginProps) {
const [rawReturnTo, setRawReturnTo] = useState<string | null>(null);
const [isRedirectingToGoogle, setIsRedirectingToGoogle] = useState(false);
const { t } = useTranslation('auth');
const page = usePage<{ flash?: { verification?: { status: string; title?: string; message?: string } } }>();
const verificationFlash = page.props.flash?.verification;
const { data, setData, post, processing, errors, clearErrors } = useForm({
login: '',
@@ -50,7 +53,15 @@ export default function Login({ status, canResetPassword }: LoginProps) {
const searchParams = new URLSearchParams(window.location.search);
setRawReturnTo(searchParams.get('return_to'));
}, []);
if (searchParams.get('verified') === '1') {
toast.success(t('verification.toast_success', 'Email verified successfully.'));
searchParams.delete('verified');
const nextQuery = searchParams.toString();
const nextUrl = `${window.location.pathname}${nextQuery ? `?${nextQuery}` : ''}`;
window.history.replaceState({}, '', nextUrl);
}
}, [t]);
useEffect(() => {
setData('return_to', rawReturnTo ?? '');
@@ -213,6 +224,20 @@ export default function Login({ status, canResetPassword }: LoginProps) {
</div>
)}
{verificationFlash && (
<div
className={[
'rounded-2xl border p-3 text-center font-medium shadow-sm',
verificationFlash.status === 'success'
? 'border-emerald-200/70 bg-emerald-50/90 text-emerald-700'
: 'border-rose-200/70 bg-rose-50/90 text-rose-700',
].join(' ')}
>
<div className="font-semibold">{verificationFlash.title ?? ''}</div>
<div className="text-sm">{verificationFlash.message}</div>
</div>
)}
{hasErrors && (
<div
key={`general-errors-${errorKeys.join('-')}`}