Add functional contact form with API backend
- Replaced placeholder form submission with real POST to /api/contact - Added honeypot field for spam protection - Success/error feedback states - Rate limiting handled by backend
This commit is contained in:
parent
e1a234d3dc
commit
c5c14d2fad
2 changed files with 66 additions and 4 deletions
|
|
@ -42,6 +42,11 @@
|
||||||
<div class="column is-8">
|
<div class="column is-8">
|
||||||
<div class="box kp-card">
|
<div class="box kp-card">
|
||||||
<form id="contact-form">
|
<form id="contact-form">
|
||||||
|
<!-- Honeypot field for spam protection - hidden from users -->
|
||||||
|
<div class="field" style="position: absolute; left: -5000px;" aria-hidden="true">
|
||||||
|
<label class="label" for="website">Website</label>
|
||||||
|
<div class="control"><input class="input" type="text" name="website" id="website" tabindex="-1" autocomplete="off" /></div>
|
||||||
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Name</label>
|
<label class="label">Name</label>
|
||||||
<div class="control"><input class="input" type="text" name="name" placeholder="Your name or alias" required /></div>
|
<div class="control"><input class="input" type="text" name="name" placeholder="Your name or alias" required /></div>
|
||||||
|
|
|
||||||
65
js/main.js
65
js/main.js
|
|
@ -39,13 +39,70 @@ document.getElementById('nav-toggle').addEventListener('click', function() {
|
||||||
menu.classList.toggle('is-active');
|
menu.classList.toggle('is-active');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Contact form (placeholder)
|
// Contact form - sends to backend API
|
||||||
var form = document.getElementById('contact-form');
|
var form = document.getElementById('contact-form');
|
||||||
if (form) {
|
if (form) {
|
||||||
form.addEventListener('submit', function(e) {
|
form.addEventListener('submit', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
var status = document.getElementById('form-status');
|
var status = document.getElementById('form-status');
|
||||||
status.style.display = 'block';
|
var submitBtn = form.querySelector('button[type="submit"]');
|
||||||
form.querySelector('button[type="submit"]').disabled = true;
|
var originalBtnText = submitBtn.textContent;
|
||||||
|
|
||||||
|
// Collect form data
|
||||||
|
var formData = new FormData(form);
|
||||||
|
var data = {
|
||||||
|
name: formData.get('name'),
|
||||||
|
email: formData.get('email'),
|
||||||
|
service: formData.get('service'),
|
||||||
|
message: formData.get('message')
|
||||||
|
};
|
||||||
|
|
||||||
|
// Honeypot for spam
|
||||||
|
var honeypot = formData.get('website') || formData.get('url') || formData.get('honey');
|
||||||
|
if (honeypot) {
|
||||||
|
// Bot detected - pretend success
|
||||||
|
status.className = 'notification is-success';
|
||||||
|
status.textContent = 'Message received. We\'ll respond within 48 hours.';
|
||||||
|
status.style.display = 'block';
|
||||||
|
form.reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable button and show sending state
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
submitBtn.textContent = 'Sending...';
|
||||||
|
status.style.display = 'none';
|
||||||
|
|
||||||
|
// Send to API
|
||||||
|
fetch('/api/contact', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
.then(function(response) {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function(result) {
|
||||||
|
if (result.success) {
|
||||||
|
status.className = 'notification is-success';
|
||||||
|
status.textContent = result.message || 'Message received. We\'ll respond within 48 hours.';
|
||||||
|
status.style.display = 'block';
|
||||||
|
form.reset();
|
||||||
|
} else {
|
||||||
|
throw new Error(result.error || 'Failed to send message');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function(error) {
|
||||||
|
status.className = 'notification is-danger';
|
||||||
|
status.textContent = error.message || 'Failed to send message. Please try again.';
|
||||||
|
status.style.display = 'block';
|
||||||
|
})
|
||||||
|
.finally(function() {
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
submitBtn.textContent = originalBtnText;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue