// Contact.jsx — contact form with client-side validation const { useState: useStateC } = React; function Contact() { const [form, setForm] = useStateC({ name: '', email: '', company: '', message: '', budget: '' }); const [errs, setErrs] = useStateC({}); const [sent, setSent] = useStateC(false); const [sending, setSending] = useStateC(false); const set = (k) => (e) => { setForm(f => ({ ...f, [k]: e.target.value })); if (errs[k]) setErrs(prev => ({ ...prev, [k]: null })); }; const setBudget = (b) => setForm(f => ({ ...f, budget: b })); const validate = () => { const e = {}; if (!form.name.trim()) e.name = "Your name, please."; if (!form.email.trim()) e.email = "We'll need this to reply."; else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) e.email = "Doesn't look like a valid email."; if (!form.message.trim()) e.message = "Tell us a little about what you need."; else if (form.message.trim().length < 12) e.message = "A few more words would help."; return e; }; const submit = (e) => { e.preventDefault(); const v = validate(); if (Object.keys(v).length) { setErrs(v); return; } setSending(true); setTimeout(() => { setSending(false); setSent(true); }, 850); }; return (
04  /  Contact

Tell us about your week.

Book a chat

A 30-minute call, no pitch, no slide deck. You talk us through what's eating your time, we'll say whether we think we can help — or who else you should talk to.

Taking on two new projects for Q3. We'll reply within one working day.

Based
London & Kent, UK
Hours
Mon–Fri, 9–6 GMT
{!sent ? ( <>

Book a chat

Available
{errs.name &&
{errs.name}
}
{errs.email &&
{errs.email}
}
{["Under £2k", "£2–5k", "£5–10k", "£10k+"].map(b => ( ))}