'use client'; import { useState, useEffect, Suspense } from 'react'; import { useSearchParams } from 'next/navigation'; import { Link, useRouter } from '@/i18n/navigation'; import Image from 'next/image'; import { useTranslations } from 'next-intl'; import { register } from '@/lib/api'; import { verifyInvitation, type InvitationResponse } from '@/lib/api/invitations'; import type { OrganizationType } from '@/types/api'; function RegisterPageContent() { const router = useRouter(); const searchParams = useSearchParams(); const t = useTranslations('auth.register'); const tFooter = useTranslations('auth.footerLinks'); const [step, setStep] = useState<1 | 2>(1); const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [organizationName, setOrganizationName] = useState(''); const [organizationType, setOrganizationType] = useState('FREIGHT_FORWARDER'); const [siren, setSiren] = useState(''); const [siret, setSiret] = useState(''); const [street, setStreet] = useState(''); const [city, setCity] = useState(''); const [state, setState] = useState(''); const [postalCode, setPostalCode] = useState(''); const [country, setCountry] = useState('FR'); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(''); const [invitationToken, setInvitationToken] = useState(null); const [invitation, setInvitation] = useState(null); const [isVerifyingInvitation, setIsVerifyingInvitation] = useState(false); useEffect(() => { const token = searchParams.get('token'); if (token) { setIsVerifyingInvitation(true); verifyInvitation(token) .then(invitationData => { setInvitation(invitationData); setInvitationToken(token); setEmail(invitationData.email); setFirstName(invitationData.firstName); setLastName(invitationData.lastName); }) .catch(() => { setError(t('invitationInvalid')); }) .finally(() => { setIsVerifyingInvitation(false); }); } }, [searchParams, t]); const validateStep1 = (): string | null => { if (!firstName.trim() || firstName.trim().length < 2) return t('fieldErrors.firstNameMin'); if (!lastName.trim() || lastName.trim().length < 2) return t('fieldErrors.lastNameMin'); if (!email.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) return t('fieldErrors.emailInvalid'); if (password.length < 12) return t('fieldErrors.passwordMin'); if (password !== confirmPassword) return t('fieldErrors.passwordsMismatch'); return null; }; const handleStep1 = (e: React.FormEvent) => { e.preventDefault(); setError(''); const err = validateStep1(); if (err) { setError(err); return; } if (invitationToken) { handleFinalSubmit(); } else { setStep(2); } }; const validateStep2 = (): string | null => { if (!organizationName.trim()) return t('fieldErrors.orgNameRequired'); if (!/^[0-9]{9}$/.test(siren)) return t('fieldErrors.sirenRequired'); if (siret && !/^[0-9]{14}$/.test(siret)) return t('fieldErrors.siretInvalid'); if (!street.trim() || !city.trim() || !postalCode.trim() || !country.trim()) { return t('fieldErrors.addressRequired'); } return null; }; const handleStep2 = (e: React.FormEvent) => { e.preventDefault(); setError(''); const err = validateStep2(); if (err) { setError(err); return; } handleFinalSubmit(); }; const handleFinalSubmit = async () => { setIsLoading(true); setError(''); try { await register({ email, password, firstName, lastName, ...(invitationToken ? { invitationToken } : { organization: { name: organizationName, type: organizationType, siren, siret: siret || undefined, street, city, state: state || undefined, postalCode, country: country.toUpperCase(), }, }), }); router.push('/dashboard'); } catch (err: any) { setError(err.message || t('errors.generic')); } finally { setIsLoading(false); } }; const rightPanel = (

{invitation ? t('sidePanel.titleInvitation') : t('sidePanel.titleDefault')}

{t('sidePanel.description')}

{t('sidePanel.features.trial.title')}

{t('sidePanel.features.trial.description')}

{t('sidePanel.features.security.title')}

{t('sidePanel.features.security.description')}

{t('sidePanel.features.support.title')}

{t('sidePanel.features.support.description')}

2k+
{t('sidePanel.stats.companies')}
150+
{t('sidePanel.stats.countries')}
24/7
{t('sidePanel.stats.support')}
); return (
Xpeditis
{!invitation && (
= 1 ? 'bg-brand-navy text-white' : 'bg-neutral-100 text-neutral-400' }`} > {step > 1 ? ( ) : ( '1' )}
= 1 ? 'text-brand-navy' : 'text-neutral-400'}`} > {t('stepAccount')}
= 2 ? 'bg-brand-navy' : 'bg-neutral-200'}`} />
= 2 ? 'bg-brand-navy text-white' : 'bg-neutral-100 text-neutral-400' }`} > 2
= 2 ? 'text-brand-navy' : 'text-neutral-400'}`} > {t('stepOrganization')}
)}
{isVerifyingInvitation ? (

{t('invitationVerifying')}

) : invitation ? ( <>

{t('invitationTitle')}

{t('invitationValid')}

) : step === 1 ? ( <>

{t('title')}

{t('subtitle')}

) : ( <>

{t('orgStepTitle')}

{t('orgStepSubtitle')}

)}
{error && (

{error}

)} {(step === 1 || invitation) && !isVerifyingInvitation && (
setFirstName(e.target.value)} className="input w-full" placeholder={t('firstNamePlaceholder')} disabled={isLoading || !!invitation} />
setLastName(e.target.value)} className="input w-full" placeholder={t('lastNamePlaceholder')} disabled={isLoading || !!invitation} />
setEmail(e.target.value)} className="input w-full" placeholder={t('emailPlaceholder')} autoComplete="email" disabled={isLoading || !!invitation} />
setPassword(e.target.value)} className="input w-full" placeholder={t('passwordPlaceholder')} autoComplete="new-password" disabled={isLoading} />

{t('passwordHint')}

setConfirmPassword(e.target.value)} className="input w-full" placeholder={t('passwordPlaceholder')} autoComplete="new-password" disabled={isLoading} />

{t('termsAccept')}{' '} {t('termsLink')} {' '} {t('termsAnd')}{' '} {t('privacyLink')}

)} {step === 2 && !invitation && (
setOrganizationName(e.target.value)} className="input w-full" placeholder={t('organizationNamePlaceholder')} disabled={isLoading} />
setSiren(e.target.value.replace(/\D/g, '').slice(0, 9))} className="input w-full" placeholder="123456789" maxLength={9} disabled={isLoading} />

{t('sirenHint')}

setSiret(e.target.value.replace(/\D/g, '').slice(0, 14))} className="input w-full" placeholder="12345678900014" maxLength={14} disabled={isLoading} />

{t('siretHint')}

setStreet(e.target.value)} className="input w-full" placeholder={t('streetPlaceholder')} disabled={isLoading} />
setCity(e.target.value)} className="input w-full" placeholder={t('cityPlaceholder')} disabled={isLoading} />
setPostalCode(e.target.value)} className="input w-full" placeholder={t('postalCodePlaceholder')} disabled={isLoading} />
setState(e.target.value)} className="input w-full" placeholder={t('statePlaceholder')} disabled={isLoading} />
setCountry(e.target.value.toUpperCase().slice(0, 2))} className="input w-full" placeholder={t('countryPlaceholder')} maxLength={2} disabled={isLoading} />

{t('countryHint')}

{t('termsAccept')}{' '} {t('termsLink')} {' '} {t('termsAnd')}{' '} {t('privacyLink')}

)}

{t('hasAccount')}{' '} {t('login')}

{tFooter('contact')} {tFooter('privacy')} {tFooter('terms')}
{rightPanel}
); } export default function RegisterPage() { return ( ); }