Files
Portfolio-Skycel/assets/js/state.js
skycel 9180f116ec ✉️ Feature: Epic 5 - Formulaire de Contact (Stories 5.1-5.7)
- 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>
2026-01-24 01:43:13 +01:00

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
}
}
};