Static landing page with Express backend for lead capture. Navy/Gold branding, mobile-responsive, SQLite storage, Mailcow SMTP notifications, rate limiting, TCPA compliance. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
113 lines
4.2 KiB
JavaScript
113 lines
4.2 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function () {
|
|
var form = document.getElementById('lead-form');
|
|
var errorBox = document.getElementById('form-error');
|
|
var successBox = document.getElementById('form-success');
|
|
var submitBtn = document.getElementById('form-submit');
|
|
var formFields = document.getElementById('form-fields');
|
|
|
|
if (!form) return;
|
|
|
|
// FAQ accordion
|
|
document.querySelectorAll('.faq-item__q').forEach(function (btn) {
|
|
btn.addEventListener('click', function () {
|
|
var item = btn.closest('.faq-item');
|
|
var wasActive = item.classList.contains('active');
|
|
document.querySelectorAll('.faq-item').forEach(function (i) { i.classList.remove('active'); });
|
|
if (!wasActive) item.classList.add('active');
|
|
});
|
|
});
|
|
|
|
// Smooth scroll for anchor links
|
|
document.querySelectorAll('a[href^="#"]').forEach(function (link) {
|
|
link.addEventListener('click', function (e) {
|
|
var target = document.querySelector(link.getAttribute('href'));
|
|
if (target) {
|
|
e.preventDefault();
|
|
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
}
|
|
});
|
|
});
|
|
|
|
// Phone formatting
|
|
var phoneInput = document.getElementById('phone');
|
|
if (phoneInput) {
|
|
phoneInput.addEventListener('input', function () {
|
|
var val = phoneInput.value.replace(/\D/g, '').slice(0, 10);
|
|
if (val.length >= 7) {
|
|
phoneInput.value = '(' + val.slice(0, 3) + ') ' + val.slice(3, 6) + '-' + val.slice(6);
|
|
} else if (val.length >= 4) {
|
|
phoneInput.value = '(' + val.slice(0, 3) + ') ' + val.slice(3);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Form submission
|
|
form.addEventListener('submit', function (e) {
|
|
e.preventDefault();
|
|
errorBox.style.display = 'none';
|
|
|
|
// Clear previous errors
|
|
form.querySelectorAll('.error').forEach(function (el) { el.classList.remove('error'); });
|
|
|
|
var name = form.querySelector('#name').value.trim();
|
|
var email = form.querySelector('#email').value.trim();
|
|
var phone = form.querySelector('#phone').value.trim();
|
|
var address = form.querySelector('#address').value.trim();
|
|
var condition = form.querySelector('#condition').value;
|
|
var timeline = form.querySelector('#timeline').value;
|
|
var consent = form.querySelector('#tcpa_consent').checked;
|
|
var honeypot = form.querySelector('#website_url').value;
|
|
|
|
// Validation
|
|
var errors = [];
|
|
if (!name) { errors.push('Name is required'); form.querySelector('#name').classList.add('error'); }
|
|
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { errors.push('Valid email is required'); form.querySelector('#email').classList.add('error'); }
|
|
if (!phone || phone.replace(/\D/g, '').length < 7) { errors.push('Valid phone is required'); form.querySelector('#phone').classList.add('error'); }
|
|
if (!address) { errors.push('Property address is required'); form.querySelector('#address').classList.add('error'); }
|
|
if (!consent) { errors.push('Please agree to be contacted'); }
|
|
|
|
if (errors.length) {
|
|
errorBox.textContent = errors[0];
|
|
errorBox.style.display = 'block';
|
|
return;
|
|
}
|
|
|
|
// Disable button
|
|
submitBtn.disabled = true;
|
|
submitBtn.textContent = 'Submitting...';
|
|
|
|
fetch('/api/submit-lead', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
name: name,
|
|
email: email,
|
|
phone: phone,
|
|
address: address,
|
|
condition: condition,
|
|
timeline: timeline,
|
|
tcpa_consent: true,
|
|
honeypot: honeypot,
|
|
}),
|
|
})
|
|
.then(function (res) { return res.json(); })
|
|
.then(function (data) {
|
|
if (data.success) {
|
|
formFields.style.display = 'none';
|
|
successBox.style.display = 'block';
|
|
} else {
|
|
errorBox.textContent = data.error || 'Something went wrong. Please try again.';
|
|
errorBox.style.display = 'block';
|
|
submitBtn.disabled = false;
|
|
submitBtn.textContent = 'Get My Cash Offer';
|
|
}
|
|
})
|
|
.catch(function () {
|
|
errorBox.textContent = 'Connection error. Please try again.';
|
|
errorBox.style.display = 'block';
|
|
submitBtn.disabled = false;
|
|
submitBtn.textContent = 'Get My Cash Offer';
|
|
});
|
|
});
|
|
});
|