@@ -22,7 +22,9 @@ const { reveal } = Astro.props;
2222 </a >
2323 </div >
2424 <div class =" contact-panel" >
25- <form id =" contact-form" action ={ contact .endpoint } method =" get" >
25+ <form id =" contact-form" action ={ contact .endpoint } method =" post" >
26+ <input type =" hidden" name =" _subject" value ={ contact .subject } />
27+ <input type =" hidden" name =" _honey" tabindex =" -1" autocomplete =" off" />
2628 <label >
2729 { contact .name }
2830 <input type =" text" name =" name" autocomplete =" name" required />
@@ -40,22 +42,55 @@ const { reveal } = Astro.props;
4042 { contact .submit }
4143 <Arrow />
4244 </button >
45+ <p class =" contact-status" role =" status" aria-live =" polite" ></p >
4346 </form >
4447 </div >
4548</section >
4649
47- <script define:vars ={ { recipient: site .email , subject: contact .subject }} >
48- document
49- .querySelector("#contact-form")
50- ?.addEventListener("submit", (event) => {
51- event.preventDefault();
52- const form = event.currentTarget;
53- if (!(form instanceof HTMLFormElement) || !form.reportValidity()) return;
54- const data = new FormData(form);
55- const name = String(data.get("name") || "");
56- const sender = String(data.get("email") || "");
57- const message = String(data.get("message") || "");
58- const body = `${message}\n\nFrom: ${name}\nReply to: ${sender}`;
59- window.location.href = `mailto:${recipient}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
60- });
50+ <script define:vars ={ { contact }} >
51+ const form = document.querySelector("#contact-form");
52+ form?.addEventListener("submit", async (event) => {
53+ event.preventDefault();
54+ if (!(form instanceof HTMLFormElement) || !form.reportValidity()) return;
55+
56+ const button = form.querySelector('button[type="submit"]');
57+ const status = form.querySelector(".contact-status");
58+ if (
59+ !(button instanceof HTMLButtonElement) ||
60+ !(status instanceof HTMLElement)
61+ )
62+ return;
63+
64+ const fields = Object.fromEntries(new FormData(form));
65+ fields._replyto = fields.email;
66+ button.disabled = true;
67+ form.setAttribute("aria-busy", "true");
68+ status.textContent = contact.sending;
69+
70+ try {
71+ const response = await fetch(contact.ajaxEndpoint, {
72+ method: "POST",
73+ headers: {
74+ "Content-Type": "application/json",
75+ Accept: "application/json",
76+ },
77+ body: JSON.stringify(fields),
78+ });
79+ const result = await response.json();
80+ if (
81+ !response.ok ||
82+ result.success === false ||
83+ result.success === "false"
84+ ) {
85+ throw new Error("FormSubmit rejected the submission");
86+ }
87+ form.reset();
88+ status.textContent = contact.sent;
89+ } catch {
90+ status.textContent = contact.sendError;
91+ } finally {
92+ button.disabled = false;
93+ form.removeAttribute("aria-busy");
94+ }
95+ });
6196</script >
0 commit comments