Machine_Learning_Training / js /feedback-storage.js
maalouf imad
V1
47f1575 verified
Raw
History Blame Contribute Delete
7.14 kB
/* ═══════════════════════════════════════════════════════════════════════════
ML ACADEMY — FEEDBACK STORAGE SYSTEM
Stocke les feedbacks au format JSON pour traitement ulterieur
═══════════════════════════════════════════════════════════════════════════ */
class FeedbackStorage {
constructor() {
this.storageKey = 'ml_academy_feedbacks';
this.feedbacks = this.loadFeedbacks();
}
// Charge tous les feedbacks depuis le stockage
loadFeedbacks() {
try {
const stored = localStorage.getItem(this.storageKey);
return stored ? JSON.parse(stored) : [];
} catch (e) {
console.error('Erreur lors du chargement des feedbacks:', e);
return [];
}
}
// Sauvegarde tous les feedbacks
saveFeedbacks() {
try {
localStorage.setItem(this.storageKey, JSON.stringify(this.feedbacks));
return true;
} catch (e) {
console.error('Erreur lors de la sauvegarde des feedbacks:', e);
return false;
}
}
// Ajoute un nouveau feedback
addFeedback(feedbackData) {
const feedback = {
id: this.generateId(),
timestamp: new Date().toISOString(),
...feedbackData
};
this.feedbacks.push(feedback);
this.saveFeedbacks();
// Exporte automatiquement vers un fichier JSON telechargeable
this.exportToFile();
return feedback;
}
// Genere un ID unique
generateId() {
return 'fb_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
}
// Recupere tous les feedbacks
getAllFeedbacks() {
return this.feedbacks;
}
// Recupere les feedbacks par date
getFeedbacksByDateRange(startDate, endDate) {
return this.feedbacks.filter(fb => {
const fbDate = new Date(fb.timestamp);
return fbDate >= startDate && fbDate <= endDate;
});
}
// Recupere les statistiques
getStatistics() {
if (this.feedbacks.length === 0) {
return {
total: 0,
averageRating: 0,
difficultyDistribution: {},
commonDifficulties: [],
commonSuggestions: []
};
}
const ratings = this.feedbacks.map(fb => parseInt(fb.rating) || 0);
const averageRating = ratings.reduce((a, b) => a + b, 0) / ratings.length;
// Distribution des difficultes
const difficultyDistribution = {};
this.feedbacks.forEach(fb => {
const diff = fb.difficulty || 'non-specifie';
difficultyDistribution[diff] = (difficultyDistribution[diff] || 0) + 1;
});
// Points difficiles communs
const difficultyCount = {};
this.feedbacks.forEach(fb => {
if (fb.difficiles && Array.isArray(fb.difficiles)) {
fb.difficiles.forEach(d => {
difficultyCount[d] = (difficultyCount[d] || 0) + 1;
});
}
});
const commonDifficulties = Object.entries(difficultyCount)
.sort((a, b) => b[1] - a[1])
.slice(0, 5);
// Suggestions communes
const suggestionCount = {};
this.feedbacks.forEach(fb => {
if (fb.suggestions && Array.isArray(fb.suggestions)) {
fb.suggestions.forEach(s => {
suggestionCount[s] = (suggestionCount[s] || 0) + 1;
});
}
});
const commonSuggestions = Object.entries(suggestionCount)
.sort((a, b) => b[1] - a[1])
.slice(0, 5);
return {
total: this.feedbacks.length,
averageRating: averageRating.toFixed(2),
difficultyDistribution,
commonDifficulties,
commonSuggestions
};
}
// Exporte les feedbacks vers un fichier JSON
exportToFile() {
const data = {
exportDate: new Date().toISOString(),
totalFeedbacks: this.feedbacks.length,
feedbacks: this.feedbacks,
statistics: this.getStatistics()
};
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
// Stocke l'URL pour telechargement ulterieur
this.lastExportUrl = url;
return url;
}
// Telecharge le fichier JSON
downloadFeedbacks() {
const url = this.exportToFile();
const a = document.createElement('a');
a.href = url;
a.download = `ml_academy_feedbacks_${new Date().toISOString().split('T')[0]}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
// Exporte vers CSV pour Excel
exportToCSV() {
if (this.feedbacks.length === 0) return null;
const headers = [
'ID', 'Date', 'Nom', 'Email', 'Projet',
'Note', 'Difficulte', 'Rythme',
'Parties Utiles', 'Points Difficiles',
'Question Principale', 'Commentaire'
];
const rows = this.feedbacks.map(fb => [
fb.id,
fb.timestamp,
fb.name || '',
fb.email || '',
fb.project || '',
fb.rating || '',
fb.difficulty || '',
fb.rythme || '',
(fb.utiles || []).join(';'),
(fb.difficiles || []).join(';'),
(fb.mainQuestion || '').replace(/"/g, '""'),
(fb.freeComment || '').replace(/"/g, '""')
]);
const csv = [
headers.join(','),
...rows.map(row => row.map(cell => `"${cell}"`).join(','))
].join('\n');
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `ml_academy_feedbacks_${new Date().toISOString().split('T')[0]}.csv`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
// Efface tous les feedbacks (avec confirmation)
clearAll() {
if (confirm('Attention : Cette action supprimera tous les feedbacks. Continuer ?')) {
this.feedbacks = [];
this.saveFeedbacks();
return true;
}
return false;
}
}
// Instance globale
const feedbackStorage = new FeedbackStorage();
// Fonction pour soumettre un feedback depuis le formulaire
function submitFeedback(formData) {
const feedback = feedbackStorage.addFeedback(formData);
console.log('Feedback enregistre:', feedback);
return feedback;
}
// Fonction pour afficher les statistiques dans la console
function showFeedbackStats() {
const stats = feedbackStorage.getStatistics();
console.log('=== Statistiques des Feedbacks ===');
console.log(`Total: ${stats.total}`);
console.log(`Note moyenne: ${stats.averageRating}/5`);
console.log('Distribution des difficultes:', stats.difficultyDistribution);
console.log('Points difficiles communs:', stats.commonDifficulties);
console.log('Suggestions communes:', stats.commonSuggestions);
return stats;
}
// Exporte pour utilisation externe
window.FeedbackStorage = FeedbackStorage;
window.feedbackStorage = feedbackStorage;
window.submitFeedback = submitFeedback;
window.showFeedbackStats = showFeedbackStats;