const { useState, useEffect } = React; // SVG flag components — true-to-spec, used in Direct Contact and footer const FlagUS = ({ size = 28 }) => ( {/* 13 stripes */} {Array.from({ length: 7 }).map((_, i) => ( ))} {/* Canton */} {/* Stars (simplified — 9 dots) */} {Array.from({ length: 9 }).map((_, i) => { const col = i % 3; const row = Math.floor(i / 3); return ; })} ); const FlagIN = ({ size = 28 }) => ( {/* Ashoka chakra */} {Array.from({ length: 24 }).map((_, i) => ( ))} ); const CTAFooter = () => { return ( <> {/* Big CTA */}
Start now

Start your AI
transformation.

Tell us where the friction is. We'll come back with an AIDD pilot scope, a measurable outcome, and a 6-week plan to ship it.

{/* Form */} {/* Side: direct contact */} {/* Office locations */}
Where we are

India HQ. Global delivery.

1 office
{/* Footer */} ); }; const ContactForm = () => { const [form, setForm] = useState({ name: '', email: '', company: '', role: '', message: '', captcha_answer: '', hp: '', }); const [captcha, setCaptcha] = useState({ id: '', question: 'Loading…', loading: true, error: false }); const [status, setStatus] = useState({ state: 'idle', msg: '' }); // idle | sending | success | error const isFile = typeof window !== 'undefined' && window.location && window.location.protocol === 'file:'; const loadCaptcha = async () => { setCaptcha(c => ({ ...c, loading: true, error: false })); if (isFile) { // Demo mode — generate a captcha client-side (server PHP can't run on file://) const a = 2 + Math.floor(Math.random() * 8); const b = 2 + Math.floor(Math.random() * 8); setCaptcha({ id: `demo:${a + b}`, question: `What is ${a} + ${b}?`, loading: false, error: false }); return; } try { const r = await fetch('api/captcha.php', { cache: 'no-store', credentials: 'same-origin' }); if (!r.ok) throw new Error('captcha_fetch'); const j = await r.json(); if (!j.id) throw new Error('captcha_payload'); setCaptcha({ id: j.id, question: j.question, loading: false, error: false }); } catch (e) { setCaptcha({ id: '', question: 'Could not load captcha — refresh', loading: false, error: true }); } }; useEffect(() => { loadCaptcha(); }, []); const update = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value })); const submit = async (e) => { e.preventDefault(); if (status.state === 'sending') return; // Client-side validation mirroring the server if (!form.name.trim()) return setStatus({ state: 'error', msg: 'Please enter your name.' }); if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) return setStatus({ state: 'error', msg: 'Please enter a valid work email.' }); if (!form.message.trim()) return setStatus({ state: 'error', msg: 'Tell us briefly what you want to automate.' }); if (!form.captcha_answer.trim()) return setStatus({ state: 'error', msg: 'Please solve the captcha.' }); setStatus({ state: 'sending', msg: '' }); if (isFile) { // Demo mode — verify captcha locally, then pretend success const expected = captcha.id.replace(/^demo:/, ''); await new Promise(r => setTimeout(r, 600)); if (parseInt(form.captcha_answer, 10) !== parseInt(expected, 10)) { setStatus({ state: 'error', msg: 'Captcha answer is incorrect.' }); loadCaptcha(); setForm(f => ({ ...f, captcha_answer: '' })); return; } setStatus({ state: 'success', msg: 'Demo only — running off file://. On the deployed PHP host this would email connect@rocketberry.co.' }); return; } try { const r = await fetch('api/mail.php', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: form.name, email: form.email, company: form.company, role: form.role, message: form.message, captcha_id: captcha.id, captcha_answer: form.captcha_answer, hp: form.hp, }), }); const j = await r.json().catch(() => ({})); if (r.ok && j.ok) { setStatus({ state: 'success', msg: 'Thanks — a Rocketberry AI engineer will reach out within one business day.' }); setForm({ name: '', email: '', company: '', role: '', message: '', captcha_answer: '', hp: '' }); loadCaptcha(); return; } const map = { invalid_name: 'Please enter a valid name.', invalid_email: 'Please enter a valid email address.', invalid_message: 'Please describe what you want to automate.', captcha_required:'Please solve the captcha.', captcha_invalid: 'Captcha is invalid — refreshing…', captcha_expired: 'Captcha expired — refreshing…', captcha_wrong: 'Captcha answer is incorrect.', too_many_links: 'Please remove most links from your message.', rate_limited: 'Too many submissions from this network — please try again later.', origin_not_allowed: 'This origin is not authorised to submit.', send_failed: 'Email server temporarily unavailable — please try again or call us directly.', }; setStatus({ state: 'error', msg: map[j.error] || 'Something went wrong — please try again.' }); if (['captcha_invalid', 'captcha_expired', 'captcha_wrong'].includes(j.error)) { loadCaptcha(); setForm(f => ({ ...f, captcha_answer: '' })); } } catch (err) { setStatus({ state: 'error', msg: 'Network error — please try again.' }); } }; if (status.state === 'success') { return (
Message sent

We've got your brief.

{status.msg}

); } return (