document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('contactForm'); const formLoadedAtInput = document.getElementById('form_loaded_at'); const formStatusDiv = document.getElementById('formStatus'); // Set form_loaded_at to current timestamp in milliseconds if (formLoadedAtInput) { formLoadedAtInput.value = Date.now().toString(); } // Initialize Altcha const altchaElement = document.getElementById('altcha-widget'); if (altchaElement) { window.altcha = new Altcha({ challengeUrl: '/altcha-challenge/', element: altchaElement }); } // Form submit handler if (form) { form.addEventListener('submit', async function(e) { e.preventDefault(); // Clear previous status messages formStatusDiv.innerHTML = ''; formStatusDiv.className = ''; // Validate required fields const name = form.elements['name']?.value.trim(); const email = form.elements['email']?.value.trim(); if (!name || !email) { formStatusDiv.className = 'form-status form-status--error'; formStatusDiv.innerHTML = '

Please fill in all required fields.

'; return; } if (!email.includes('@')) { formStatusDiv.className = 'form-status form-status--error'; formStatusDiv.innerHTML = '

Please enter a valid email address.

'; return; } // Check honeypot const honeypot = form.elements['website']?.value; if (honeypot) { formStatusDiv.className = 'form-status form-status--error'; formStatusDiv.innerHTML = '

Form validation failed.

'; return; } // Solve Altcha if available let altchaPayload = ''; if (window.altcha && !window.altcha.didSubmit) { try { await window.altcha.solve(); altchaPayload = window.altcha.getFormData().altcha; } catch (err) { formStatusDiv.className = 'form-status form-status--error'; formStatusDiv.innerHTML = '

Spam check failed. Please try again.

'; return; } } else if (window.altcha) { const formData = window.altcha.getFormData(); altchaPayload = formData.altcha || ''; } // Build JSON payload const payload = { name: form.elements['name'].value.trim(), email: form.elements['email'].value.trim(), phone: form.elements['phone']?.value.trim() || '', message: form.elements['message']?.value.trim() || '', website: form.elements['website']?.value || '', form_loaded_at: form.elements['form_loaded_at']?.value || '', altcha: altchaPayload }; // POST to /contact/ try { const response = await fetch('/contact/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const data = await response.json(); if (data.ok) { formStatusDiv.className = 'form-status form-status--success'; formStatusDiv.innerHTML = '

Thank you! Your message has been sent. We\'ll be in touch soon.

'; form.reset(); if (formLoadedAtInput) { formLoadedAtInput.value = Date.now().toString(); } if (window.altcha) { window.altcha = new Altcha({ challengeUrl: '/altcha-challenge/', element: document.getElementById('altcha-widget') }); } } else { formStatusDiv.className = 'form-status form-status--error'; formStatusDiv.innerHTML = '

' + (data.error || 'An error occurred. Please try again.') + '

'; } } catch (err) { formStatusDiv.className = 'form-status form-status--error'; formStatusDiv.innerHTML = '

Network error. Please try again.

'; } }); } });