/* ============================================================ New Liberty Homes — Shared components ============================================================ */ const { useState } = React; const Icon = window.Icon; // ── Lead delivery ─────────────────────────────────────────── // All website form submissions are emailed to this address. const LEAD_EMAIL = 'info@newlibertyhomes.com'; // ...and also POSTed to the CRM via this Zapier Catch Hook. const CRM_WEBHOOK = 'https://hooks.zapier.com/hooks/catch/985690/434nvhk/'; // Uses FormSubmit (https://formsubmit.co) — no backend required. The FIRST // submission triggers a one-time confirmation email to LEAD_EMAIL; click the // link in it once to activate delivery. After that every submission is emailed. function sendLead(formName, fields) { const flat = { 'Form': formName, 'Submitted': new Date().toLocaleString() }; for (const [k, v] of Object.entries(fields || {})) { const label = k.replace(/([A-Z])/g, ' $1').replace(/^./, c => c.toUpperCase()).trim(); flat[label] = Array.isArray(v) ? (v.length ? v.join(', ') : '—') : (v === '' || v == null ? '—' : v); } // 1) Email via FormSubmit const payload = { _subject: `New Liberty Homes — ${formName}`, _template: 'table', _captcha: 'false', ...flat }; try { fetch('https://formsubmit.co/ajax/' + LEAD_EMAIL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(payload), }).catch(() => {}); } catch (e) { /* fire-and-forget */ } // 2) Send to CRM via Zapier webhook (all fields, clean keys + metadata) try { const crmPayload = { form: formName, source: 'newlibertyhomes.com', submittedAt: new Date().toISOString(), pageUrl: (typeof window !== 'undefined' && window.location) ? window.location.href : '', ...(fields || {}), }; // Normalize arrays (e.g. checkbox groups) to comma-joined strings for the CRM. for (const [k, v] of Object.entries(crmPayload)) { if (Array.isArray(v)) crmPayload[k] = v.join(', '); } fetch(CRM_WEBHOOK, { method: 'POST', // text/plain avoids a CORS preflight; Zapier still parses the JSON body. headers: { 'Content-Type': 'text/plain;charset=UTF-8' }, body: JSON.stringify(crmPayload), }).catch(() => {}); } catch (e) { /* fire-and-forget */ } } // ── Logo Mark ──────────────────────────────────────────────── function BrandMark({ size = 52 }) { return (
{/* Stylized house with star */}
); } // ── Status Badge ───────────────────────────────────────────── function StatusBadge({ status }) { const cls = status.toLowerCase(); return {status}; } // ── 3D Tour Modal (embedded iframe — stays on same tab) ────── function Tour3DModal({ url, title, onClose }) { React.useEffect(() => { const onKey = (e) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', onKey); const prev = document.body.style.overflow; document.body.style.overflow = 'hidden'; return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = prev; }; }, [onClose]); return (
e.stopPropagation()}>
▶ 3D Tour{title ? ` — ${title}` : ''}