279 lines
8.8 KiB
Markdown
279 lines
8.8 KiB
Markdown
# 📊 Fonctionnalité d'Export ODS - Statistiques de Vote
|
||
|
||
## 🎯 Vue d'ensemble
|
||
|
||
La fonctionnalité d'export ODS permet d'exporter les statistiques de vote d'une campagne dans un format tableur compatible avec LibreOffice Calc, OpenOffice Calc et Microsoft Excel.
|
||
|
||
## 📋 Fonctionnalités
|
||
|
||
### ✅ **Export complet des données**
|
||
- **Onglet principal** : "Synthèse des votes" - Matrice des votes (participants × propositions)
|
||
- **6 onglets de tri** : Un pour chaque critère de tri des propositions
|
||
- **Toutes les propositions** en colonnes
|
||
- **Tous les participants** (votants ou non) en lignes
|
||
- **Montants investis** à l'intersection colonne/ligne
|
||
- **Totaux par ligne** (total voté par participant)
|
||
- **Totaux par colonne** (total reçu par proposition)
|
||
- **Budget restant** par participant
|
||
- **Anonymisation RGPD** : 3 niveaux de protection des données personnelles
|
||
|
||
### 📊 **Structure du fichier exporté**
|
||
|
||
#### **Onglet principal : "Synthèse des votes"**
|
||
```
|
||
Statistiques de vote - [Nom de la campagne]
|
||
|
||
Participant | Proposition 1 | Proposition 2 | ... | Total voté | Budget restant
|
||
-----------|---------------|---------------|-----|------------|---------------
|
||
Alice Doe | 50 | 30 | ... | 80 | 20
|
||
Bob Smith | 40 | 0 | ... | 40 | 60
|
||
... | ... | ... | ... | ... | ...
|
||
TOTAL | 90 | 30 | ... | 120 | 80
|
||
```
|
||
|
||
#### **Onglets de tri (6 onglets)**
|
||
Chaque onglet contient les propositions triées selon un critère :
|
||
|
||
**Onglet "Impact total"**
|
||
```
|
||
Statistiques de vote - [Nom de la campagne] - Tri par Impact total (Somme totale investie)
|
||
|
||
Proposition | Votes reçus | Montant total | Montant moyen | Montant min | Montant max | Taux participation | Répartition votes | Score consensus
|
||
-----------|-------------|---------------|---------------|-------------|-------------|-------------------|-------------------|------------------
|
||
Prop A | 5 | 250 | 50 | 30 | 70 | 100 | 5 | 15.8
|
||
Prop B | 3 | 120 | 40 | 20 | 60 | 60 | 3 | 16.3
|
||
```
|
||
|
||
**Onglets disponibles :**
|
||
- **Impact total** : Tri par montant total investi
|
||
- **Popularité** : Tri par montant moyen puis nombre de votants
|
||
- **Consensus** : Tri par score de consensus (écart-type)
|
||
- **Engagement** : Tri par taux de participation
|
||
- **Répartition** : Tri par nombre de votes différents
|
||
- **Alphabétique** : Tri par ordre alphabétique
|
||
|
||
**Format des en-têtes :** "Statistiques de vote - [Nom Campagne] - Tri par [Critère] ([Description])"
|
||
|
||
**Descriptions des critères :**
|
||
- **Impact total** : "Somme totale investie"
|
||
- **Popularité** : "Moyenne puis nombre de votants"
|
||
- **Consensus** : "Plus petit écart-type"
|
||
- **Engagement** : "Taux de participation"
|
||
- **Répartition** : "Nombre de votes différents"
|
||
- **Alphabétique** : "Ordre alphabétique"
|
||
|
||
### 🎨 **Formatage**
|
||
- **En-tête** avec le titre de la campagne
|
||
- **Colonnes dimensionnées** automatiquement
|
||
- **Ligne des totaux** avec texte en gras et bordures épaisses
|
||
- **Colonnes des totaux** (Total voté, Budget restant) avec bordures épaisses
|
||
- **Nom de fichier** automatique avec date
|
||
|
||
## 🚀 Utilisation
|
||
|
||
### **Configuration de l'anonymisation**
|
||
|
||
1. **Accédez** à **Paramètres** > **Exports**
|
||
2. **Choisissez** le niveau d'anonymisation :
|
||
- **Anonymisation complète** : Noms remplacés par "XXXX" (recommandé)
|
||
- **Initiales uniquement** : Premières lettres des noms/prénoms
|
||
- **Aucune anonymisation** : Noms complets (attention RGPD)
|
||
3. **Sauvegardez** les paramètres
|
||
|
||
### **Dans l'interface d'administration**
|
||
|
||
1. **Accédez** à la page des statistiques d'une campagne
|
||
2. **Cliquez** sur le bouton "Exporter les votes (ODS)" en haut à droite
|
||
3. **Attendez** la génération du fichier
|
||
4. **Le fichier** se télécharge automatiquement avec le niveau d'anonymisation configuré
|
||
|
||
### **Format du nom de fichier**
|
||
```
|
||
statistiques_vote_[nom_campagne]_[date].ods
|
||
```
|
||
|
||
**Exemples :**
|
||
- `statistiques_vote_budget_participatif_2024_2025-08-27.ods`
|
||
- `statistiques_vote_campagne_ete_2025-08-27.ods`
|
||
|
||
## 🔧 Architecture technique
|
||
|
||
### **Fichiers impliqués**
|
||
|
||
#### `src/lib/export-utils.ts`
|
||
- **`generateVoteExportODS()`** : Génère le fichier ODS
|
||
- **`downloadODS()`** : Télécharge le fichier
|
||
- **`formatFilename()`** : Formate le nom de fichier
|
||
|
||
#### `src/components/ExportStatsButton.tsx`
|
||
- **Composant React** pour le bouton d'export
|
||
- **Gestion des états** (chargement, erreur)
|
||
- **Interface utilisateur** avec icône et texte
|
||
|
||
#### `src/app/admin/campaigns/[id]/stats/page.tsx`
|
||
- **Intégration** du bouton d'export
|
||
- **Passage des données** nécessaires
|
||
|
||
### **Dépendances**
|
||
```json
|
||
{
|
||
"xlsx": "^0.18.5"
|
||
}
|
||
```
|
||
|
||
## 📊 Structure des données
|
||
|
||
### **Interface ExportData**
|
||
```typescript
|
||
interface ExportData {
|
||
campaignTitle: string;
|
||
propositions: Proposition[];
|
||
participants: Participant[];
|
||
votes: Vote[];
|
||
budgetPerUser: number;
|
||
}
|
||
```
|
||
|
||
### **Calculs effectués**
|
||
|
||
#### **Totaux par participant**
|
||
```typescript
|
||
const totalVoted = votes
|
||
.filter(v => v.participant_id === participant.id)
|
||
.reduce((sum, vote) => sum + vote.amount, 0);
|
||
```
|
||
|
||
#### **Totaux par proposition**
|
||
```typescript
|
||
const propositionTotal = votes
|
||
.filter(v => v.proposition_id === proposition.id)
|
||
.reduce((sum, vote) => sum + vote.amount, 0);
|
||
```
|
||
|
||
#### **Budget restant**
|
||
```typescript
|
||
const budgetRemaining = budgetPerUser - totalVoted;
|
||
```
|
||
|
||
## 🧪 Tests
|
||
|
||
### **Tests unitaires**
|
||
- **Génération ODS** : Vérification de la structure
|
||
- **Formatage des noms** : Gestion des caractères spéciaux
|
||
- **Cas limites** : Participants sans votes, propositions vides
|
||
|
||
### **Fichier de test**
|
||
`src/__tests__/lib/export-utils.test.ts`
|
||
|
||
### **Exécution des tests**
|
||
```bash
|
||
npm test -- src/__tests__/lib/export-utils.test.ts
|
||
```
|
||
|
||
## 🔒 Sécurité et RGPD
|
||
|
||
### **Anonymisation des données**
|
||
- **3 niveaux de protection** configurables dans les paramètres
|
||
- **Anonymisation complète** : Noms remplacés par "XXXX" (recommandé)
|
||
- **Initiales uniquement** : Premières lettres des noms/prénoms
|
||
- **Aucune anonymisation** : Noms complets (avec avertissement RGPD)
|
||
|
||
### **Données exportées**
|
||
- **Aucune donnée sensible** (mots de passe, clés API)
|
||
- **Données publiques** uniquement (votes, participants, propositions)
|
||
- **Conformité RGPD** : Respect du niveau d'anonymisation configuré
|
||
- **Avertissement** : Alerte RGPD pour l'export sans anonymisation
|
||
|
||
### **Validation**
|
||
- **Vérification des types** TypeScript
|
||
- **Validation des données** avant export
|
||
- **Gestion d'erreurs** robuste
|
||
|
||
## 🎨 Interface utilisateur
|
||
|
||
### **Bouton d'export**
|
||
- **Icône** : FileSpreadsheet (Lucide React)
|
||
- **Texte** : "Exporter les votes (ODS)"
|
||
- **État de chargement** : Spinner + "Export en cours..."
|
||
- **Position** : En haut à droite de la page statistiques
|
||
- **Anonymisation** : Respecte le paramètre configuré dans les paramètres
|
||
|
||
### **États visuels**
|
||
- **Normal** : Bouton cliquable
|
||
- **Chargement** : Spinner + texte modifié
|
||
- **Désactivé** : Quand les données ne sont pas chargées
|
||
|
||
## 🔄 Workflow
|
||
|
||
### **1. Clic sur le bouton**
|
||
```typescript
|
||
const handleExport = async () => {
|
||
setIsExporting(true);
|
||
// Génération et téléchargement
|
||
setIsExporting(false);
|
||
};
|
||
```
|
||
|
||
### **2. Génération des données**
|
||
```typescript
|
||
const exportData: ExportData = {
|
||
campaignTitle,
|
||
propositions,
|
||
participants,
|
||
votes,
|
||
budgetPerUser
|
||
};
|
||
```
|
||
|
||
### **3. Création du fichier ODS**
|
||
```typescript
|
||
const odsData = generateVoteExportODS(exportData);
|
||
```
|
||
|
||
### **4. Téléchargement**
|
||
```typescript
|
||
const filename = formatFilename(campaignTitle);
|
||
downloadODS(odsData, filename);
|
||
```
|
||
|
||
## 🐛 Dépannage
|
||
|
||
### **Problèmes courants**
|
||
|
||
#### **Fichier ne se télécharge pas**
|
||
- Vérifiez les permissions du navigateur
|
||
- Désactivez les bloqueurs de popup
|
||
- Vérifiez l'espace disque disponible
|
||
|
||
#### **Erreur de génération**
|
||
- Vérifiez que toutes les données sont chargées
|
||
- Consultez la console du navigateur
|
||
- Relancez l'export
|
||
|
||
#### **Fichier corrompu**
|
||
- Vérifiez la taille du fichier
|
||
- Essayez d'ouvrir avec un autre logiciel
|
||
- Régénérez l'export
|
||
|
||
### **Logs de débogage**
|
||
```typescript
|
||
console.error('Erreur lors de l\'export:', error);
|
||
```
|
||
|
||
## 🚀 Améliorations futures
|
||
|
||
### **Fonctionnalités envisagées**
|
||
- **Export PDF** : Version imprimable
|
||
- **Filtres** : Export partiel (participants spécifiques)
|
||
- **Templates** : Formats personnalisables
|
||
- **Export automatique** : Programmation d'exports
|
||
|
||
### **Optimisations**
|
||
- **Compression** : Réduction de la taille des fichiers
|
||
- **Cache** : Mise en cache des exports récents
|
||
- **Asynchrone** : Export en arrière-plan pour les gros volumes
|
||
|
||
---
|
||
|
||
**Cette fonctionnalité facilite l'analyse et le partage des résultats de vote ! 📊✨**
|