(function () { const form = document.getElementById('contactForm'); if (!form) return; const dropzone = document.getElementById('dropzone'); const photoInput = document.getElementById('photoInput'); const photoPreview = document.getElementById('photoPreview'); const photoError = document.getElementById('photoError'); const formAlert = document.getElementById('formAlert'); const submitBtn = document.getElementById('submitBtn'); const textarea = form.querySelector('textarea[name="message"]'); const phoneInput = form.querySelector('input[name="phone"]'); let selectedFiles = []; // Textarea auto-resize textarea.style.overflow = 'hidden'; textarea.addEventListener('input', function () { this.style.height = 'auto'; this.style.height = this.scrollHeight + 'px'; }); // Phone auto-format phoneInput.addEventListener('input', function () { const digits = this.value.replace(/\D/g, '').slice(0, 10); if (digits.length >= 7) this.value = '(' + digits.slice(0,3) + ') ' + digits.slice(3,6) + '-' + digits.slice(6); else if (digits.length >= 4) this.value = '(' + digits.slice(0,3) + ') ' + digits.slice(3); else this.value = digits; }); // Clear inline errors on input form.querySelectorAll('.input, .textarea').forEach(el => { el.addEventListener('input', () => clearErr(el)); }); function setErr(input, msg) { input.classList.add('is-danger'); const el = document.getElementById('err-' + input.name); if (el) { el.textContent = msg; el.style.display = ''; } } function clearErr(input) { input.classList.remove('is-danger'); const el = document.getElementById('err-' + input.name); if (el) el.style.display = 'none'; } function validate() { let ok = true; const firstName = form.querySelector('[name="firstName"]'); if (!firstName.value.trim()) { setErr(firstName, 'Please enter your first name.'); ok = false; } else clearErr(firstName); const lastName = form.querySelector('[name="lastName"]'); if (!lastName.value.trim()) { setErr(lastName, 'Please enter your last name.'); ok = false; } else clearErr(lastName); const email = form.querySelector('[name="email"]'); if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value.trim())) { setErr(email, 'Please enter a valid email address.'); ok = false; } else clearErr(email); const phone = form.querySelector('[name="phone"]'); if (phone.value.replace(/\D/g, '').length < 10) { setErr(phone, 'Please enter a valid 10-digit phone number.'); ok = false; } else clearErr(phone); const msg = form.querySelector('[name="message"]'); if (!msg.value.trim()) { setErr(msg, 'Please enter a message.'); ok = false; } else clearErr(msg); return ok; } // Dropzone dropzone.addEventListener('click', () => photoInput.click()); dropzone.addEventListener('dragover', e => { e.preventDefault(); dropzone.classList.add('drag-over'); }); dropzone.addEventListener('dragleave', () => dropzone.classList.remove('drag-over')); dropzone.addEventListener('drop', e => { e.preventDefault(); dropzone.classList.remove('drag-over'); addFiles(Array.from(e.dataTransfer.files)); }); photoInput.addEventListener('change', () => { addFiles(Array.from(photoInput.files)); photoInput.value = ''; }); function addFiles(newFiles) { const images = newFiles.filter(f => f.type.startsWith('image/')); const tooBig = images.filter(f => f.size > 10 * 1024 * 1024); if (tooBig.length) showAlert('One or more photos exceed 10 MB and were skipped.', 'is-warning'); const ok = images.filter(f => f.size <= 10 * 1024 * 1024); const combined = [...selectedFiles, ...ok]; photoError.style.display = combined.length > 3 ? '' : 'none'; selectedFiles = combined.slice(0, 3); renderPreviews(); } function renderPreviews() { photoPreview.innerHTML = ''; selectedFiles.forEach((file, i) => { const url = URL.createObjectURL(file); const wrap = document.createElement('div'); wrap.className = 'preview-wrap'; const img = document.createElement('img'); img.src = url; const btn = document.createElement('button'); btn.type = 'button'; btn.className = 'remove-btn'; btn.innerHTML = '×'; btn.addEventListener('click', () => { URL.revokeObjectURL(url); selectedFiles.splice(i, 1); photoError.style.display = 'none'; renderPreviews(); }); wrap.appendChild(img); wrap.appendChild(btn); photoPreview.appendChild(wrap); }); } // Submit form.addEventListener('submit', async e => { e.preventDefault(); formAlert.style.display = 'none'; if (!validate()) { showAlert('Please correct the errors below.', 'is-danger'); // Scroll to first error const first = form.querySelector('.is-danger'); if (first) first.scrollIntoView({ behavior: 'smooth', block: 'center' }); return; } const fd = new FormData(); fd.append('firstName', form.querySelector('[name="firstName"]').value.trim()); fd.append('lastName', form.querySelector('[name="lastName"]').value.trim()); fd.append('email', form.querySelector('[name="email"]').value.trim()); fd.append('phone', form.querySelector('[name="phone"]').value.trim()); fd.append('message', form.querySelector('[name="message"]').value.trim()); const et = form.querySelector('[name="eventType"]'); if (et) fd.append('eventType', et.value); const ed = form.querySelector('[name="eventDate"]'); if (ed) fd.append('eventDate', ed.value); const hp = form.querySelector('[name="website"]'); if (hp) fd.append('website', hp.value); selectedFiles.forEach(f => fd.append('photos', f)); submitBtn.classList.add('is-loading'); submitBtn.disabled = true; try { const res = await fetch('/api/contact', { method: 'POST', body: fd }); const data = await res.json(); if (data.success) { showAlert("Message sent! We’ll get back to you soon. Check your email for a confirmation.", 'is-success'); form.reset(); selectedFiles = []; renderPreviews(); textarea.style.height = 'auto'; } else { showAlert(data.message || 'Something went wrong. Please try again.', 'is-danger'); } } catch { showAlert('Network error. Please try again or email us directly.', 'is-danger'); } finally { submitBtn.classList.remove('is-loading'); submitBtn.disabled = false; } }); function showAlert(msg, cls) { formAlert.className = 'notification ' + cls; formAlert.textContent = msg; formAlert.style.display = ''; formAlert.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } })();