feat(contact): ajouter un backend pour le traitement des formulaires de contact avec validation et envoi d'e-mails
This commit is contained in:
@@ -1,18 +1,60 @@
|
||||
{{ $form := .Page.Params.contactForm }}
|
||||
<form class="max-w-lg mx-auto p-6 bg-white rounded shadow" method="POST" action="/contact">
|
||||
|
||||
<div id="contact-result" class="max-w-lg mx-auto mb-4"></div>
|
||||
<form id="contactForm" class="max-w-lg mx-auto p-6 bg-white rounded shadow" method="POST" action="{{ $form.action | default "http://localhost:3001/contact" }}">
|
||||
{{ range $form.fields }}
|
||||
<div class="mb-4">
|
||||
<label for="{{ .name }}" class="block text-gray-700 font-bold mb-2">{{ .label }}</label>
|
||||
{{ if eq .type "textarea" }}
|
||||
<textarea id="{{ .name }}" name="{{ .name }}" rows="5" {{ if .required }}required{{ end }} class="w-full px-3 py-2 border rounded focus:outline-none focus:ring focus:border-blue-300"></textarea>
|
||||
{{ else if eq .type "select" }}
|
||||
<select id="{{ .name }}" name="{{ .name }}" {{ if .required }}required{{ end }} class="w-full px-3 py-2 border rounded focus:outline-none focus:ring focus:border-blue-300">
|
||||
{{ range .options }}
|
||||
<option value="{{ .value }}">{{ .label | default .value }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
{{ else }}
|
||||
<input type="{{ .type }}" id="{{ .name }}" name="{{ .name }}" {{ if .required }}required{{ end }} class="w-full px-3 py-2 border rounded focus:outline-none focus:ring focus:border-blue-300" />
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="flex justify-end mt-4">
|
||||
<button type="submit" class="px-6 py-3 rounded-lg font-bold transition duration-200 ease-in-out border-2 text-primary-400 border-primary-400 hover:border-primary-400 hover:text-primary-400 hover:scale-105">
|
||||
{{ $form.button.label | default "Envoyer" }}
|
||||
</button>
|
||||
</div>
|
||||
<!-- Champ honeypot invisible pour les robots -->
|
||||
<div style="position:absolute; left:-9999px; top:auto; width:1px; height:1px; overflow:hidden;">
|
||||
<label for="website">Ne pas remplir ce champ</label>
|
||||
<input type="text" id="website" name="website" tabindex="-1" autocomplete="off" />
|
||||
</div>
|
||||
<!-- (Plus de champ caché Formspree, tout est géré côté backend) -->
|
||||
<div class="flex justify-end mt-4">
|
||||
<button type="submit" class="px-6 py-3 rounded-lg font-bold transition duration-200 ease-in-out border-2 text-primary-400 border-primary-400 hover:border-primary-400 hover:text-primary-400 hover:scale-105">
|
||||
{{ $form.button.label | default "Envoyer" }}
|
||||
</button>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const form = document.getElementById('contactForm');
|
||||
const resultDiv = document.getElementById('contact-result');
|
||||
form.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
resultDiv.innerHTML = '';
|
||||
const formData = new FormData(form);
|
||||
console.log('Submitting form to:', formData);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(async response => {
|
||||
const text = await response.text();
|
||||
if (response.status === 200) {
|
||||
resultDiv.innerHTML = `<div style='background:#e6ffed;color:#228B22;padding:1em;border-radius:6px;border:1px solid #228B22;'>${text}</div>`;
|
||||
form.reset();
|
||||
} else {
|
||||
resultDiv.innerHTML = `<div style='background:#ffe6e6;color:#b22222;padding:1em;border-radius:6px;border:1px solid #b22222;'>${text}</div>`;
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
resultDiv.innerHTML = `<div style='background:#ffe6e6;color:#b22222;padding:1em;border-radius:6px;border:1px solid #b22222;'>Erreur réseau</div>`;
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user