- Formulaire HTML5 avec validation (nom, prénom, email, entreprise, catégorie, objet, message) - Validation JavaScript côté client (FormValidator) - Persistance localStorage des données (AppState) - Intégration reCAPTCHA v3 avec dégradation gracieuse - Traitement PHP sécurisé (CSRF, validation, envoi email) - Feedback utilisateur AJAX (succès/erreur) - Liens contact secondaires (LinkedIn, GitHub, Email protégé) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
77 lines
2.0 KiB
JavaScript
77 lines
2.0 KiB
JavaScript
/**
|
|
* Gestionnaire d'état pour le localStorage
|
|
* Persiste les données du formulaire de contact
|
|
*/
|
|
|
|
const AppState = {
|
|
STORAGE_KEY: 'portfolio_contact_form',
|
|
|
|
// Champs à ne jamais stocker (sécurité)
|
|
EXCLUDED_FIELDS: ['csrf_token', 'password', 'recaptcha_token'],
|
|
|
|
/**
|
|
* Vérifie si localStorage est disponible
|
|
*/
|
|
isStorageAvailable() {
|
|
try {
|
|
const test = '__storage_test__';
|
|
localStorage.setItem(test, test);
|
|
localStorage.removeItem(test);
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Sauvegarde les données du formulaire
|
|
* @param {Object} data - Données du formulaire
|
|
*/
|
|
saveFormData(data) {
|
|
if (!this.isStorageAvailable()) return;
|
|
|
|
try {
|
|
// Filtrer les champs exclus
|
|
const filteredData = {};
|
|
Object.keys(data).forEach(key => {
|
|
if (!this.EXCLUDED_FIELDS.includes(key)) {
|
|
filteredData[key] = data[key];
|
|
}
|
|
});
|
|
|
|
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(filteredData));
|
|
} catch (e) {
|
|
console.warn('Impossible de sauvegarder dans localStorage:', e);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Charge les données sauvegardées
|
|
* @returns {Object|null} Données ou null si absentes
|
|
*/
|
|
getFormData() {
|
|
if (!this.isStorageAvailable()) return null;
|
|
|
|
try {
|
|
const data = localStorage.getItem(this.STORAGE_KEY);
|
|
return data ? JSON.parse(data) : null;
|
|
} catch (e) {
|
|
console.warn('Impossible de charger depuis localStorage:', e);
|
|
return null;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Efface les données sauvegardées
|
|
*/
|
|
clearFormData() {
|
|
if (!this.isStorageAvailable()) return;
|
|
|
|
try {
|
|
localStorage.removeItem(this.STORAGE_KEY);
|
|
} catch (e) {
|
|
// Silencieux
|
|
}
|
|
}
|
|
};
|