// Basin AJAX submission with lazily-loaded reCAPTCHA v3 for the contact form // and job apply forms. The reCAPTCHA script is not loaded until the visitor // first interacts with a form (or submits), keeping it off the initial page load. (function () { "use strict"; const SITE_KEY = "6Les66kUAAAAANyLrgkl7iuN4JUpNlB5upaMovI4"; const forms = document.querySelectorAll(".contact-form form, form.contact-form, form.apply-form"); if (!forms.length) return; // ── Lazy reCAPTCHA loader ────────────────────────────────────── let loadStarted = false; function loadRecaptcha() { if (loadStarted) return; loadStarted = true; const s = document.createElement("script"); s.src = "https://www.google.com/recaptcha/api.js?render=" + SITE_KEY; s.async = true; document.head.appendChild(s); } // Resolves once grecaptcha is ready; loads the script if not already loading. function readyRecaptcha() { loadRecaptcha(); return new Promise((resolve, reject) => { const start = Date.now(); (function check() { if (window.grecaptcha && window.grecaptcha.execute) { window.grecaptcha.ready(resolve); } else if (Date.now() - start > 10000) { reject(new Error("reCAPTCHA failed to load")); } else { setTimeout(check, 100); } })(); }); } forms.forEach((form) => { // Warm the loader as soon as the user engages with the form. form.addEventListener("focusin", loadRecaptcha, { once: true }); const success = document.getElementById("form-success"); const statusEl = document.getElementById("form-status"); // optional role="status" region const tokenField = form.querySelector("#g-recaptcha-response"); const btn = form.querySelector('button[type="submit"]'); const originalLabel = btn ? btn.textContent : ""; const announce = (msg) => { if (statusEl) statusEl.textContent = msg; else if (msg) alert(msg); }; form.addEventListener("submit", async (e) => { e.preventDefault(); if (btn) { btn.textContent = btn.dataset.sending || "Sending…"; btn.disabled = true; } announce(""); try { await readyRecaptcha(); const token = await window.grecaptcha.execute(SITE_KEY, { action: "submit" }); if (tokenField) tokenField.value = token; const res = await fetch(form.action, { method: "POST", body: new FormData(form), headers: { Accept: "application/json" }, }); if (!res.ok) throw new Error("Submission failed"); form.reset(); form.style.display = "none"; if (success) { success.style.display = "block"; success.scrollIntoView({ behavior: "smooth", block: "center" }); } } catch (err) { if (btn) { btn.textContent = originalLabel; btn.disabled = false; } announce( "Something went wrong. Please try again or email us directly at work-orders@seahaven.com" ); } }); }); })();