import React, { useMemo, useState } from 'react'; import Icon from '../../shared/components/icon'; type ContactValues = { firstName: string; lastName: string; dateOfBirth: string; nationality: string; email: string; phone: string; message: string; street: string; houseNumber: string; box: string; postalCode: string; city: string; country: string; // traveler 1 bookingType1: 'leisure' | 'business' | ''; gender1: 'female' | 'male' | 'other' | ''; // traveler 2 bookingType2: 'leisure' | 'business' | ''; gender2: 'female' | 'male' | 'other' | ''; }; type ContactErrors = Partial>; // const [touched, setTouched] = useState>>({}); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const phoneRegex = /^[+()\-.\s0-9]{8,20}$/; // Small helper: checks YYYY-MM-DD parses to a real date const isValidISODate = (value: string) => { if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return false; const d = new Date(value); return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === value; }; // You can expand this list later (or load from API) const nationalityOptions = [ { value: '', label: 'Selecteer nationaliteit' }, { value: 'BE', label: 'Belgisch' }, { value: 'NL', label: 'Nederlands' }, { value: 'FR', label: 'Frans' }, { value: 'DE', label: 'Duits' }, { value: 'UK', label: 'Brits' }, { value: 'US', label: 'Amerikaans' } ]; const countryOptions = [ { value: '', label: 'Selecteer land' }, { value: 'BE', label: 'Belgiƫ' }, { value: 'NL', label: 'Nederland' }, { value: 'FR', label: 'Frankrijk' }, { value: 'DE', label: 'Duitsland' }, { value: 'LU', label: 'Luxemburg' }, { value: 'UK', label: 'Verenigd Koninkrijk' } ]; const PersonalContactForm: React.FC = () => { const [values, setValues] = useState({ firstName: '', lastName: '', dateOfBirth: '', nationality: '', email: '', phone: '', message: '', street: '', houseNumber: '', box: '', postalCode: '', city: '', country: '', bookingType1: '', gender1: '', bookingType2: '', gender2: '' }); const [touched, setTouched] = useState>>({}); const [errors, setErrors] = useState({}); const [submitted, setSubmitted] = useState(false); const [isNationalityOpen, setIsNationalityOpen] = useState(false); const [isCountryOpen, setIsCountryOpen] = useState(false); const postalCodeRegex = /^[0-9A-Za-z\s-]{3,10}$/; const validate = (v: ContactValues): ContactErrors => { const e: ContactErrors = {}; if (!v.firstName.trim()) e.firstName = 'Voornaam is verplicht.'; if (!v.lastName.trim()) e.lastName = 'Achternaam is verplicht.'; if (!v.dateOfBirth.trim()) e.dateOfBirth = 'Geboortedatum is verplicht.'; else if (!isValidISODate(v.dateOfBirth.trim())) e.dateOfBirth = 'Vul een geldige geboortedatum in.'; if (!v.nationality.trim()) e.nationality = 'Nationaliteit is verplicht.'; if (!v.email.trim()) e.email = 'Email is verplicht.'; else if (!emailRegex.test(v.email.trim())) e.email = 'Vul een geldig e-mailadres in.'; if (v.phone.trim() && !phoneRegex.test(v.phone.trim())) { e.phone = 'Vul een geldig telefoonnummer in.'; } if (!v.message.trim()) e.message = 'Bericht is verplicht.'; else if (v.message.trim().length < 10) e.message = 'Bericht moet minstens 10 tekens zijn.'; if (!v.street.trim()) e.street = 'Straat is verplicht.'; if (!v.houseNumber.trim()) e.houseNumber = 'Nummer is verplicht.'; if (!v.postalCode.trim()) e.postalCode = 'Postcode is verplicht.'; else if (!postalCodeRegex.test(v.postalCode.trim())) e.postalCode = 'Vul een geldige postcode in.'; if (!v.city.trim()) e.city = 'Woonplaats is verplicht.'; if (!v.country.trim()) e.country = 'Land is verplicht.'; if (!v.gender1) e.gender1 = 'Geslacht is verplicht.'; if (!v.gender2) e.gender2 = 'Geslacht is verplicht.'; if (!v.bookingType1) e.bookingType1 = 'Type boeking is verplicht.'; if (!v.bookingType2) e.bookingType2 = 'Type boeking is verplicht.'; return e; }; const currentErrors = useMemo(() => validate(values), [values]); const setField = (key: K, val: ContactValues[K]) => { setValues((p) => ({ ...p, [key]: val })); if (submitted || touched[key]) { setErrors(validate({ ...values, [key]: val } as ContactValues)); } }; const onBlur = (key: keyof ContactValues) => { setTouched((p) => ({ ...p, [key]: true })); setErrors(validate(values)); }; const onSubmit = (e: React.FormEvent) => { e.preventDefault(); setSubmitted(true); const eMap = validate(values); setErrors(eMap); if (Object.keys(eMap).length > 0) return; console.log('Contact form submit:', values); setValues({ firstName: '', lastName: '', dateOfBirth: '', nationality: '', email: '', phone: '', message: '', street: '', houseNumber: '', box: '', postalCode: '', city: '', country: '', bookingType1: '', gender1: '', bookingType2: '', gender2: '' }); setTouched({}); setErrors({}); setSubmitted(false); }; const showError = (key: keyof ContactValues) => { const shouldShow = submitted || touched[key]; return shouldShow ? errors[key] : undefined; }; return (

Persoonlijke informatie

Gaat de hoofdboeker mee op reis?

Reiziger 1

volwassenen, hoofdboeker
Type boeking{/** add * if required */}
{showError('bookingType1') && ( {showError('bookingType1')} )}
Geslacht*
{showError('gender1') && ( {showError('gender1')} )}

Reiziger 2

volwassenen
Geslacht*
{showError('gender2') && ( {showError('gender2')} )}
); }; export default PersonalContactForm;