// QUOTE page — multi-section quote form const { useState: useStateQ } = React; function QuoteApp() { const [lang, setLang] = useLang(); const t = mergeT(lang); const qp = t.quote_page; const f = qp.form; const [submitted, setSubmitted] = useStateQ(false); const [submitting, setSubmitting] = useStateQ(false); const [error, setError] = useStateQ(""); const [files, setFiles] = useStateQ([]); const onFiles = (list) => setFiles(Array.from(list || []).map(x => x.name)); const ICN = { Mail: Icon.Mail, Calendar: Icon.Calendar, Clipboard: Icon.Clipboard }; return ( <>
{ e.preventDefault(); setError(""); setSubmitting(true); const fd = new FormData(e.target); const timeline = fd.get("timeline") || ""; const budget = fd.get("budget") || ""; const payload = { name: fd.get("name") || "", phone: fd.get("phone") || "", email: fd.get("email") || "", address: fd.get("zip") || "", projectType: fd.get("projectType") || "", message: fd.get("message") || "", timeline: timeline, budget: budget, }; try { const res = await fetch("/api/remodeling-quote", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); const j = await res.json(); if (j.success) { setSubmitted(true); window.scrollTo({ top: 0, behavior: "smooth" }); } else { setError(j.error || "Submission failed."); } } catch (err) { setError(lang === "en" ? "Network error. Please call (737) 354-7787." : "Error de red. Llama (737) 354-7787."); } finally { setSubmitting(false); } }}> {submitted && (
✓ {lang === 'en' ? "Thanks — your request is in. Expect to hear from us within one business day." : "Gracias — recibimos tu solicitud. Te contactamos en menos de un día hábil."}
)} {error && (
⚠️ {error}
)}

{f.h}

{f.step1}

{f.step2}

{f.step3}

{f.timeline_options.map((o, i) => ( ))}
{f.budget_options.map((o, i) => ( ))}
{f.scheduling_options.map((o, i) => ( ))}

{f.step4}

{f.consent}

); } ReactDOM.createRoot(document.getElementById("app")).render();