// Contact.jsx const Contact = () => { const t = useT(); const [topic, setTopic] = React.useState('mentoring'); // 'idle' | 'sending' | 'failed' (success is handled by `sent` below) const [status, setStatus] = React.useState('idle'); // mailto: fallback built from the form fields when the service is unreachable const [mailtoHref, setMailtoHref] = React.useState(''); // After a successful FormSubmit round-trip, we come back with ?sent=1 const [sent, setSent] = React.useState(false); React.useEffect(() => { try { const p = new URLSearchParams(window.location.search); if (p.get('sent') === '1') { setSent(true); // clean the URL so a refresh doesn't keep the state const clean = window.location.origin + window.location.pathname + '#contact'; window.history.replaceState({}, '', clean); } } catch (e) {} }, []); const topicLabel = (t.contact.topics.find(([k]) => k === topic) || [, ''])[1]; // redirect back to this same page (wherever it is hosted) with a success flag const nextUrl = (() => { try { return window.location.origin + window.location.pathname + '?sent=1'; } catch (e) { return ''; } })(); // Web3Forms — reliable static-form backend (Amazon-powered, no server needed). // The access key is public by design (an alias for the inbox email). const WEB3FORMS_KEY = 'a3871556-0323-48b2-aac3-aadabd1c1403'; const ENDPOINT = 'https://api.web3forms.com/submit'; const FALLBACK_EMAIL = 'hello@beep-consult.com'; // Build a pre-filled mailto: so a visitor is never blocked if the form service is down const buildMailto = (data) => { const subject = 'Contact — beep-consult.com (' + (data.topic || '') + ')'; const body = 'Name: ' + (data.name || '') + '\n' + 'Email: ' + (data.email || '') + '\n' + 'Topic: ' + (data.topic || '') + '\n\n' + (data.message || ''); return 'mailto:' + FALLBACK_EMAIL + '?subject=' + encodeURIComponent(subject) + '&body=' + encodeURIComponent(body); }; const handleSubmit = async (e) => { e.preventDefault(); if (status === 'sending') return; const form = e.target; const fd = new FormData(form); const data = { name: fd.get('name'), email: fd.get('email'), topic: fd.get('topic'), message: fd.get('message'), }; // Honeypot — silently accept and pretend success if (fd.get('botcheck')) { setSent(true); return; } setStatus('sending'); try { const res = await fetch(ENDPOINT, { method: 'POST', headers: { 'Accept': 'application/json' }, body: fd, }); // Web3Forms returns 200 with { success: true } on a delivered message if (!res.ok) throw new Error('HTTP ' + res.status); const json = await res.json().catch(() => ({})); if (json && (json.success === 'true' || json.success === true)) { setStatus('idle'); setSent(true); } else { throw new Error('Unexpected response'); } } catch (err) { // Service unreachable (e.g. Cloudflare 521) — fall back to email setMailtoHref(buildMailto(data)); setStatus('failed'); } }; return (
{t.contact.eyebrow}

{t.contact.title}

{t.contact.sub}

{sent ? (

{t.contact.okTitle}

{t.contact.okBody}

) : status === 'failed' ? (

{t.contact.failTitle}

{t.contact.failBody}

{t.contact.failCta}
) : (
{/* Web3Forms configuration */}
{t.contact.topics.map(([k, v]) => )}
)}
); }; window.Contact = Contact;