/* ------------------------------------------------------------------ * * Contact page (i18n) * ------------------------------------------------------------------ */ function PageContact({ quoteItems, removeQuoteItem }) { const { t } = useLang(); const { format } = useCurrency(); const roles = [0,1,2,3,4,5].map(i => t(`contact.role.${i}`)); const interestKeys = ["tray","box","bar","custom","sample","showroom"]; const interests = interestKeys.map(k => t(`contact.interest.${k}`)); const timelines = [0,1,2,3].map(i => t(`contact.timeline.${i}`)); const [form, setForm] = useState({ name: "", company: "", email: "", phone: "", role: roles[0], location: "", interests: [interests[0]], message: "", timeline: timelines[1], website: "", // honeypot — must stay empty }); const [errors, setErrors] = useState({}); const [sent, setSent] = useState(false); const [sending, setSending] = useState(false); const [sendError, setSendError] = useState(""); // Honor sample-pack prefill from product page React.useEffect(() => { try { if (localStorage.getItem("aqua_prefill_interest") === "sample") { const sampleLabel = t("contact.interest.sample"); setForm((f) => ({ ...f, interests: f.interests.includes(sampleLabel) ? f.interests : [...f.interests.filter(x => x !== interests[0]), sampleLabel], })); localStorage.removeItem("aqua_prefill_interest"); } } catch (e) {} }, []); const update = (k) => (e) => { const v = e && e.target ? e.target.value : e; setForm((f) => ({ ...f, [k]: v })); setErrors((er) => ({ ...er, [k]: undefined })); }; const toggleInterest = (i) => { setForm((f) => ({ ...f, interests: f.interests.includes(i) ? f.interests.filter((x) => x !== i) : [...f.interests, i], })); }; const submit = async (e) => { e.preventDefault(); const er = {}; if (!form.name.trim()) er.name = t("common.required"); if (!form.email.trim()) er.email = t("common.required"); else if (!/^\S+@\S+\.\S+$/.test(form.email)) er.email = t("contact.email.invalid"); if (!form.message.trim()) er.message = t("contact.field.message.err"); setErrors(er); if (Object.keys(er).length > 0) return; setSendError(""); setSending(true); try { const payload = { ...form, interests: form.interests.join(", ") }; if (quoteItems && quoteItems.length) { payload.quote = quoteItems .map((q) => `${q.product.name} \u00b7 ${q.color.name} \u00b7 \u00d7${q.qty}`) .join("\n"); } const res = await fetch("/contact.php", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify(payload), }); const out = await res.json().catch(() => ({})); // Only claim success once the server actually accepted the mail. if (!res.ok || !out.ok) throw new Error(out.error || t("contact.send.err")); setSent(true); window.scrollTo({ top: 0, behavior: "smooth" }); } catch (err) { setSendError(t("contact.send.err")); } finally { setSending(false); } }; if (sent) { const firstName = form.name.split(" ")[0]; return (
{t("contact.received")} #{Math.floor(Math.random() * 90000 + 10000)}

{t("contact.thanks.a")}{firstName}.

{t("contact.thanks.body.a")} {form.email} {t("contact.thanks.body.b")}

); } const showroomLines = t("contact.showrooms.addr").split("\n"); return (
{t("contact.eyebrow")}

{t("contact.title.a")}
{t("contact.title.em")}

{t("contact.body")}

{quoteItems && quoteItems.length > 0 && (
{t("contact.quote.in")} {quoteItems.length}
{quoteItems.map((q, i) => (
{q.product.name}
{q.color.name} · ×{q.qty}
{format(q.total)}
))}
)}
{errors.name && {errors.name}} {errors.email && {errors.email}}
{interests.map((it) => ( ))}
{timelines.map((tl) => ( ))}