Story 5.6: feedback utilisateur

This commit is contained in:
2026-02-04 21:31:10 +01:00
parent 5b1539a3aa
commit 0545a6e14b
6 changed files with 210 additions and 36 deletions

View File

@@ -324,8 +324,117 @@ const RecaptchaService = {
}
};
class ContactFormSubmit {
constructor(formId) {
this.form = document.getElementById(formId);
if (!this.form) return;
this.submitBtn = document.getElementById('submit-btn');
this.submitText = document.getElementById('submit-text');
this.submitLoading = document.getElementById('submit-loading');
this.successMessage = document.getElementById('success-message');
this.errorMessage = document.getElementById('error-message');
this.errorText = document.getElementById('error-text');
this.isSubmitting = false;
this.init();
}
init() {
this.form.addEventListener('validSubmit', () => this.handleSubmit());
}
async handleSubmit() {
if (this.isSubmitting) return;
this.setLoadingState(true);
this.hideMessages();
try {
const formData = window.contactFormValidator.getFormData();
const csrfInput = this.form.querySelector('[name="csrf_token"]');
if (csrfInput) {
formData.csrf_token = csrfInput.value;
}
formData.recaptcha_token = await RecaptchaService.getToken('contact');
const response = await fetch('/api/contact.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(formData)
});
const result = await response.json();
if (result.success) {
this.handleSuccess(result.message);
} else {
this.handleError(result.error || 'Une erreur est survenue');
}
} catch (error) {
console.error('Erreur envoi formulaire:', error);
this.handleError('Impossible de contacter le serveur. Vérifiez votre connexion.');
} finally {
this.setLoadingState(false);
}
}
setLoadingState(loading) {
this.isSubmitting = loading;
if (this.submitBtn) {
this.submitBtn.disabled = loading;
}
if (this.submitText && this.submitLoading) {
if (loading) {
this.submitText.classList.add('hidden');
this.submitLoading.classList.remove('hidden');
} else {
this.submitText.classList.remove('hidden');
this.submitLoading.classList.add('hidden');
}
}
}
handleSuccess(message) {
this.form.classList.add('hidden');
if (this.successMessage) {
this.successMessage.classList.remove('hidden');
this.successMessage.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
AppState.clearFormData();
this.form.reset();
this.form.dispatchEvent(new CustomEvent('formSuccess'));
}
handleError(message) {
if (this.errorMessage && this.errorText) {
this.errorText.textContent = message;
this.errorMessage.classList.remove('hidden');
this.errorMessage.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}
hideMessages() {
if (this.successMessage) {
this.successMessage.classList.add('hidden');
}
if (this.errorMessage) {
this.errorMessage.classList.add('hidden');
}
}
}
document.addEventListener('DOMContentLoaded', () => {
RecaptchaService.init();
window.contactFormValidator = new FormValidator('contact-form');
window.contactFormPersistence = new ContactFormPersistence('contact-form');
window.contactFormSubmit = new ContactFormSubmit('contact-form');
});