import React, { useMemo, useState } from 'react'; type ContactValues = { firstName: string; lastName: string; email: string; phone: string; message: string; }; type ContactErrors = Partial>; const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const phoneRegex = /^[+()\-.\s0-9]{8,20}$/; const ContactForm: React.FC = () => { const [values, setValues] = useState({ firstName: '', lastName: '', email: '', phone: '', message: '' }); const [touched, setTouched] = useState>>({}); const [errors, setErrors] = useState({}); const [submitted, setSubmitted] = useState(false); 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.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.'; 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: '', email: '', phone: '', message: '' }); setTouched({}); setErrors({}); setSubmitted(false); }; const showError = (key: keyof ContactValues) => { const shouldShow = submitted || touched[key]; return shouldShow ? errors[key] : undefined; }; return (

Contact form