/** * WP Register Page * * Simplified registration form for WordPress plugin users. * B2B-only: TWWIM is pure B2B SaaS, every account is a Business. * No plan selection, no captcha. * * (c) 2026 TWWIM UG. All rights reserved. (www.twwim.com) */ import { useState } from 'react'; import { useForm, Controller } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { PasswordInput } from '@/features/auth/components/PasswordInput'; import { AuthLayout } from '@/features/auth/components/AuthLayout'; import { AlertCircle } from 'lucide-react'; import { apiClient } from '@/infrastructure/http/ApiClient'; import { useTranslation } from '@/i18n/TranslationProvider'; import { CountrySelect } from '@archer/ui/components'; import { CompanyType } from '@archer/domain'; const wpRegisterSchema = z.object({ email: z.string().email(), password: z.string().min(8).max(100), firstName: z.string().min(1).max(100), lastName: z.string().min(1).max(100), /** ISO-3166-1 alpha-2 — drives billing currency via CurrencyResolver on the backend. */ country: z.string().length(2, 'Select a country'), companyName: z.string().min(1, 'Company name is required').max(200), vatId: z.string().max(50).optional(), agreeToTerms: z.literal(true, { errorMap: () => ({ message: 'terms-required' }), }), }); type WpRegisterFormData = z.infer; /** * Best-effort ISO-2 country from the browser locale (e.g. 'de-DE' → 'DE'). * Returns '' when the locale lacks a region — the CountrySelect just starts * empty and the user picks manually. */ function guessBrowserCountry(): string { if (typeof navigator === 'undefined') return ''; const loc = navigator.language || ''; const m = loc.match(/-([A-Z]{2})$/i); return m ? m[1].toUpperCase() : ''; } export function WpRegisterPage({ onBack }: { onBack: () => void }) { const { t, locale } = useTranslation(); const [apiError, setApiError] = useState(null); const [success, setSuccess] = useState(false); const { register, handleSubmit, control, formState: { errors, isSubmitting }, } = useForm({ resolver: zodResolver(wpRegisterSchema), // Default to the browser's locale region when detectable — matches the // landing-web wizard's geo-default behaviour. Server is still authoritative. defaultValues: { country: guessBrowserCountry() }, }); const termsUrl = `https://www.twwim.ai/${locale}/terms-of-service`; const privacyUrl = `https://www.twwim.ai/${locale}/privacy-policy`; const onSubmit = async (data: WpRegisterFormData) => { setApiError(null); try { await apiClient.post('/auth/register', { email: data.email, password: data.password, firstName: data.firstName, lastName: data.lastName, country: data.country, companyName: data.companyName, companyType: CompanyType.BUSINESS, vatId: data.vatId || undefined, agreeToTerms: data.agreeToTerms, legalAcceptance: { agb: true as const, datenschutz: true as const, avv: true as const }, }); // Registration successful — show success message setSuccess(true); } catch (err: any) { const msg = err?.response?.data?.message || err?.message || 'Registration failed'; setApiError(msg); } }; if (success) { return (

Account Created

Please check your email to verify your account, then sign in.

); } return (

Create Business Account

TWWIM AI is a B2B SaaS — accounts are for businesses only.

{errors.firstName &&

{errors.firstName.message}

}
{errors.lastName &&

{errors.lastName.message}

}
{errors.email &&

{errors.email.message}

}
{errors.password &&

{errors.password.message}

}
( )} /> {errors.country &&

{errors.country.message}

}

Determines your billing currency.

{errors.companyName && (

{errors.companyName.message}

)}
{errors.agreeToTerms && (

{t('auth.register.terms.required')}

)}
{apiError && ( {apiError} )}
); }