diff --git a/.env.example b/.env.example
index 223b9e4..e45a357 100644
--- a/.env.example
+++ b/.env.example
@@ -1,20 +1,20 @@
-# Fichier d'exemple pour les variables d'environnement
-# Copiez ce fichier en .env et remplissez avec vos valeurs
-
-# Keycloak Configuration
-KEYCLOAK_CLIENT_SECRET=dev-secret-change-in-production
-KEYCLOAK_AUTH_SERVER_URL=http://localhost:8180/realms/unionflow
-
-# Backend Configuration
-UNIONFLOW_BACKEND_URL=http://localhost:8085
-
-# Session Configuration
-SESSION_TIMEOUT=3600
-REMEMBER_ME_DURATION=604800
-
-# Security Configuration
-ENABLE_CSRF=true
-PASSWORD_MIN_LENGTH=8
-PASSWORD_REQUIRE_SPECIAL=true
-MAX_LOGIN_ATTEMPTS=5
-LOCKOUT_DURATION=300
+# Fichier d'exemple pour les variables d'environnement
+# Copiez ce fichier en .env et remplissez avec vos valeurs
+
+# Keycloak Configuration
+KEYCLOAK_CLIENT_SECRET=dev-secret-change-in-production
+KEYCLOAK_AUTH_SERVER_URL=http://localhost:8180/realms/unionflow
+
+# Backend Configuration
+UNIONFLOW_BACKEND_URL=http://localhost:8085
+
+# Session Configuration
+SESSION_TIMEOUT=3600
+REMEMBER_ME_DURATION=604800
+
+# Security Configuration
+ENABLE_CSRF=true
+PASSWORD_MIN_LENGTH=8
+PASSWORD_REQUIRE_SPECIAL=true
+MAX_LOGIN_ATTEMPTS=5
+LOCKOUT_DURATION=300
diff --git a/.gitignore b/.gitignore
index 169e0dd..b2d7e20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,114 +1,114 @@
-# Maven
-target/
-pom.xml.tag
-pom.xml.releaseBackup
-pom.xml.versionsBackup
-pom.xml.next
-release.properties
-dependency-reduced-pom.xml
-buildNumber.properties
-.mvn/timing.properties
-.mvn/wrapper/maven-wrapper.jar
-
-# Eclipse
-.project
-.classpath
-.settings/
-bin/
-
-# IntelliJ IDEA
-.idea/
-*.iws
-*.iml
-*.ipr
-out/
-
-# NetBeans
-nbproject/private/
-nbbuild/
-dist/
-nbdist/
-.nb-gradle/
-
-# VS Code
-.vscode/
-*.code-workspace
-
-# Quarkus
-.quarkus/
-
-# OS
-.DS_Store
-Thumbs.db
-*.swp
-*.bak
-*~
-
-# Logs
-*.log
-logs/
-!src/main/resources/META-INF/resources/pages/admin/logs/
-
-# Temporary files
-*.tmp
-*.temp
-
-# SÉCURITÉ: Ne JAMAIS committer ces fichiers
-.env
-.env.local
-.env.*.local
-*.key
-*.pem
-*.p12
-*.jks
-secrets/
-credentials.json
-
-# Build artifacts
-*.jar
-*.war
-*.ear
-*.class
-
-# Package files
-*.tar.gz
-*.zip
-*.rar
-
-# IDE-specific
-.factorypath
-.apt_generated/
-.springBeans
-.sts4-cache/
-
-# Quarkus specific
-.quarkus/
-quarkus.log
-
-# JSF/Faces specific
-**/META-INF/resources/.faces-config.xml.jsfdia
-**/javax.faces.resource/
-
-# PrimeFaces cache
-**/primefaces_resource_cache/
-
-# Node modules (if using npm/webpack for frontend assets)
-node_modules/
-npm-debug.log
-yarn-error.log
-package-lock.json
-yarn.lock
-
-# Static resources compiled
-src/main/resources/META-INF/resources/dist/
-src/main/resources/META-INF/resources/assets/vendor/
-
-# Database files (dev)
-*.db
-*.sqlite
-*.h2.db
-
-# Application config overrides (local dev)
-application-local.properties
-application-dev-override.properties
-*-secret.properties
+# Maven
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+
+# Eclipse
+.project
+.classpath
+.settings/
+bin/
+
+# IntelliJ IDEA
+.idea/
+*.iws
+*.iml
+*.ipr
+out/
+
+# NetBeans
+nbproject/private/
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+# VS Code
+.vscode/
+*.code-workspace
+
+# Quarkus
+.quarkus/
+
+# OS
+.DS_Store
+Thumbs.db
+*.swp
+*.bak
+*~
+
+# Logs
+*.log
+logs/
+!src/main/resources/META-INF/resources/pages/admin/logs/
+
+# Temporary files
+*.tmp
+*.temp
+
+# SÉCURITÉ: Ne JAMAIS committer ces fichiers
+.env
+.env.local
+.env.*.local
+*.key
+*.pem
+*.p12
+*.jks
+secrets/
+credentials.json
+
+# Build artifacts
+*.jar
+*.war
+*.ear
+*.class
+
+# Package files
+*.tar.gz
+*.zip
+*.rar
+
+# IDE-specific
+.factorypath
+.apt_generated/
+.springBeans
+.sts4-cache/
+
+# Quarkus specific
+.quarkus/
+quarkus.log
+
+# JSF/Faces specific
+**/META-INF/resources/.faces-config.xml.jsfdia
+**/javax.faces.resource/
+
+# PrimeFaces cache
+**/primefaces_resource_cache/
+
+# Node modules (if using npm/webpack for frontend assets)
+node_modules/
+npm-debug.log
+yarn-error.log
+package-lock.json
+yarn.lock
+
+# Static resources compiled
+src/main/resources/META-INF/resources/dist/
+src/main/resources/META-INF/resources/assets/vendor/
+
+# Database files (dev)
+*.db
+*.sqlite
+*.h2.db
+
+# Application config overrides (local dev)
+application-local.properties
+application-dev-override.properties
+*-secret.properties
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ec864b..f14dec9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,359 +1,359 @@
-# Changelog - UnionFlow Client
-
-Tous les changements notables de ce projet sont documentés dans ce fichier.
-
-Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/),
-et ce projet adhère au [Semantic Versioning](https://semver.org/lang/fr/).
-
----
-
-## [3.0.0] - 2026-01-04 🚀 **PRODUCTION-READY**
-
-### 🎯 Migration Complète vers Architecture Production-Ready
-
-#### ✨ Ajouté - Services Transverses
-
-##### ErrorHandlerService
-- ✅ **Gestion centralisée des erreurs** avec méthodes `showSuccess()`, `showError()`, `showWarning()`, `showInfo()`
-- ✅ **Logging automatique** des exceptions avec contexte
-- ✅ **Conversion** des exceptions techniques en messages utilisateur clairs
-- ✅ **Gestion des redirections** en cas d'erreur critique
-
-##### RetryService
-- ✅ **Retry automatique** avec backoff exponentiel (1s, 2s, 4s)
-- ✅ **3 tentatives max** avec configuration flexible
-- ✅ **Détection intelligente** des exceptions retryables
-- ✅ **Méthodes** : `executeWithRetrySupplier()`, `executeWithRetry()`
-
-##### CacheService
-- ✅ **Cache en mémoire** avec TTL configurable (5 minutes par défaut)
-- ✅ **Invalidation** manuelle, par clé, ou par pattern
-- ✅ **Nettoyage automatique** des entrées expirées
-- ✅ **Optimisation** des appels backend répétitifs
-
-##### BackendCallInterceptor
-- ✅ **Logging automatique** des appels backend (paramètres, durée, résultats)
-- ✅ **Détection des appels lents** (>2s) avec warnings
-- ✅ **Masquage des données sensibles** dans les logs
-- ✅ **Annotation** : `@LogBackendCall`
-
-##### ValidationService
-- ✅ **Validation centralisée** des beans avec contraintes Jakarta
-- ✅ **Affichage structuré** des erreurs de validation
-- ✅ **Intégration** avec ErrorHandlerService
-
-#### 🔄 Modifié - Migration des Beans (48 beans)
-
-##### Beans Migrés vers Architecture Production-Ready
-- ✅ **OrganisationsBean** - Gestion des organisations
-- ✅ **TypeOrganisationsAdminBean** - Types d'organisations
-- ✅ **MembreListeBean** - Liste des membres
-- ✅ **MembreInscriptionBean** - Inscription membres
-- ✅ **MembreCotisationBean** - Cotisations membre
-- ✅ **MembreImportBean** - Import en masse
-- ✅ **MembreExportBean** - Export de données
-- ✅ **MembreProfilBean** - Profil membre
-- ✅ **MembreRechercheBean** - Recherche avancée
-- ✅ **AdhesionsBean** - Gestion des adhésions
-- ✅ **AdhesionHistoriqueBean** - Historique adhésions
-- ✅ **CotisationsBean** - Gestion cotisations
-- ✅ **CotisationsGestionBean** - Administration cotisations
-- ✅ **EvenementsBean** - Gestion des événements
-- ✅ **DemandesAideBean** - Demandes d'aide
-- ✅ **DemandesBean** - Gestion des demandes
-- ✅ **RapportsBean** - Génération de rapports
-- ✅ **RapportDetailsBean** - Détails des rapports
-- ✅ **TableauxBordBean** - Tableaux de bord analytiques
-- ✅ **DashboardBean** - Dashboard principal
-- ✅ **PreferencesBean** - Préférences utilisateur
-- ✅ **ParametresBean** - Paramètres application
-- ✅ **ConfigurationBean** - Configuration système
-- ✅ **PersonnelBean** - Gestion du personnel
-- ✅ **OrganisationDetailBean** - Détails organisation
-- ✅ **OrganisationStatistiquesBean** - Statistiques
-- ✅ **DocumentBean** - Documents personnels
-- ✅ **DocumentsBean** - Gestion documentaire
-- ✅ **NotificationBean** - Notifications
-- ✅ **SuggestionBean** - Suggestions
-- ✅ **TicketBean** - Support tickets
-- ✅ **AuditBean** - Logs d'audit
-- ✅ **ComptabiliteBean** - Comptabilité
-- ✅ **ExportMasseBean** - Export en masse
-- ✅ **SuperAdminBean** - Administration super-admin
-- ✅ **UtilisateursBean** - Gestion utilisateurs
-- ✅ **FavorisBean** - Favoris utilisateur
-- ✅ **WaveBean** - Intégration Wave Money
-- ✅ **LoginBean** - Authentification
-- ✅ **OrganisationsBean** - Gestion des organisations
-- ✅ Et 9 autres beans...
-
-##### Changements par Bean
-- 🔄 Remplacement de `java.util.logging.Logger` par `org.jboss.logging.Logger`
-- 🔄 Injection d'`ErrorHandlerService`, `RetryService`, `CacheService`
-- 🔄 Suppression des appels directs à `FacesContext.addMessage()`
-- 🔄 Enrobage des appels backend avec `retryService.executeWithRetrySupplier()`
-- 🔄 Utilisation du cache pour données fréquentes
-- 🔄 Logging structuré avec paramètres (`LOG.infof()`, `LOG.errorf()`)
-
-#### ❌ Supprimé
-
-##### Méthodes Obsolètes
-- ❌ ~50 méthodes `ajouterMessage()` redondantes supprimées
-- ❌ ~200 appels directs à `FacesContext.getCurrentInstance().addMessage()`
-- ❌ ~150 appels à `LOGGER.info/severe/warning()` avec concaténation
-
-##### Fichiers Temporaires (33 fichiers)
-- ❌ 3 fichiers .md obsolètes
-- ❌ 10 fichiers temporaires (tokens, configs debug)
-- ❌ 16 anciens tests dans `test.bak/`
-- ❌ 4 artefacts et fichiers orphelins
-
-#### 📈 Amélioré
-
-##### Performance
-- ⚡ **Cache** : Réduction de 70% des appels backend pour données de référence
-- ⚡ **Retry intelligent** : Gestion automatique des erreurs transitoires
-- ⚡ **Logging optimisé** : Paramètres au lieu de concaténation
-
-##### Maintenabilité
-- 📝 **Code DRY** : Centralisation de la gestion des erreurs
-- 📝 **Logging cohérent** : Format uniforme dans toute l'application
-- 📝 **Messages clairs** : Séparation des messages techniques et utilisateur
-
-##### Robustesse
-- 🛡️ **Gestion d'erreurs** : Try-catch systématique avec handling approprié
-- 🛡️ **Résilience** : Retry automatique pour erreurs temporaires
-- 🛡️ **Validation** : Contrôles avant appels backend
-
-#### 🧪 Tests
-- ✅ **15/15 tests passent** (100% client)
-- ✅ **Aucune régression** après migration
-- ✅ **Validation complète** des validateurs personnalisés
-
-#### 📚 Documentation
-- ✅ Création de `DOCUMENTATION.md` - Index complet
-- ✅ Mise à jour de `README.md`
-- ✅ Création de `RESUME_MIGRATION_BEANS_ET_TESTS.md`
-- ✅ Nettoyage de 3 fichiers .md obsolètes
-- ✅ Amélioration du `.gitignore`
-
----
-
-## [1.0.0] - 2025-12-17
-
-### 🔒 Sécurité Critique - RÉSOLU
-
-#### Ajouté
-- ✅ **Headers de sécurité HTTP complets** (CSP, HSTS, X-Frame-Options, etc.)
- - `X-Content-Type-Options: nosniff`
- - `X-Frame-Options: DENY`
- - `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload`
- - `Content-Security-Policy` avec support PrimeFaces
- - `Referrer-Policy: strict-origin-when-cross-origin`
- - `Permissions-Policy`
-
-- ✅ **Compression HTTP** activée (gzip, niveau 6)
-- ✅ **Support rôles multiples** dans PermissionChecker
- - Méthode `hasAnyRole()` améliorée
- - Méthode `hasAllRoles()` ajoutée
- - Méthode `hasRoleOrHigher()` avec hiérarchie
-- ✅ **Limite cache tokens** (10,000 max) - Protection DoS
-- ✅ **Nettoyage automatique** des tokens expirés
-- ✅ **Tests unitaires** pour validateurs (MemberNumberValidator)
-- ✅ **Documentation complète** (README.md, SECURITY.md)
-
-#### Modifié
-- ✅ **Secret Keycloak supprimé** du code source (application-dev.properties)
- - Utilisation exclusive de variables d'environnement
- - Documentation ajoutée pour la configuration
-
-- ✅ **TLS verification activée** même en développement
- - `quarkus.oidc.tls.verification=required` (était `none`)
- - Protection contre MITM
-
-- ✅ **Session cookies sécurisés**
- - `quarkus.http.session-cookie-secure=true` (était `false`)
- - `quarkus.http.session-cookie-same-site=strict` (était `lax`)
-
-- ✅ **RestClientExceptionMapper amélioré**
- - Messages d'erreur génériques pour erreurs 5xx
- - Pas d'exposition des détails backend
- - Logging sécurisé sans informations sensibles
-
-- ✅ **Logging de données sensibles supprimé**
- - UserSession: Suppression logs username/rôles
- - AuthenticationFilter: Anonymisation des logs
- - TokenRefreshService: Suppression logs sessionId
-
-- ✅ **Backend URL par défaut en HTTPS**
- - `unionflow.backend.url` utilise HTTPS au lieu de HTTP
-
-- ✅ **Timeouts REST optimisés**
- - `read-timeout` réduit de 30s à 15s
-
-- ✅ **CSP activé** en développement et production
- - `primefaces.CSP=true`
-
-#### Dépendances Mises à Jour
-- ✅ Lombok: `1.18.30` → `1.18.34` (dernière version stable)
-- ✅ Apache POI: `5.2.5` → `5.3.0` (correctifs sécurité)
-
-### 🧪 Tests
-
-#### Ajouté
-- ✅ Structure complète de tests
- - `src/test/java/dev/lions/unionflow/client/validation/`
- - `src/test/java/dev/lions/unionflow/client/security/`
- - `src/test/java/dev/lions/unionflow/client/service/`
-
-- ✅ **MemberNumberValidatorTest.java** (100% couverture)
- - 14 tests unitaires complets
- - Tests de cas nominaux et limites
- - Tests de validation d'année
- - Tests de format
-
-### 📚 Documentation
-
-#### Ajouté
-- ✅ **README.md complet** (8,000+ mots)
- - Guide d'installation détaillé
- - Configuration complète
- - Architecture documentée
- - Déploiement expliqué
- - Support et troubleshooting
-
-- ✅ **SECURITY.md** (politique de sécurité complète)
- - Architecture de sécurité en profondeur
- - Gestion des secrets
- - Signalement de vulnérabilités
- - Conformité OWASP Top 10
-
-- ✅ **CHANGELOG.md** (ce fichier)
-
-- ✅ **Javadoc améliorée**
- - TokenRefreshService avec documentation complète
- - PermissionChecker avec exemples
- - Annotations de sécurité ajoutées
-
-### 🏗️ Architecture
-
-#### Amélioré
-- ✅ **PermissionChecker**: Support complet des rôles multiples
- - Hiérarchie de rôles définie
- - Méthode `getHighestRole()`
- - Vérifications granulaires
-
-- ✅ **TokenRefreshService**: Gestion sécurisée et performante
- - Limite de cache (10,000 tokens)
- - Nettoyage automatique des tokens expirés
- - Suppression forcée des plus anciens si cache plein
- - Méthode `getActiveTokenCount()` pour monitoring
-
-### 🔧 Configuration
-
-#### Modifié
-- ✅ `application.properties`:
- - Session cookie secure=true
- - Session cookie same-site=strict
- - Backend URL HTTPS
- - Read timeout optimisé
- - CSP activé
-
-- ✅ `application-dev.properties`:
- - Secret Keycloak supprimé (variable d'environnement uniquement)
- - TLS verification=required
- - Documentation sécurité ajoutée
-
-- ✅ `application-prod.properties`:
- - Headers de sécurité HTTP complets
- - Compression HTTP activée
- - Read timeout optimisé
- - Configuration sécurité renforcée
-
-### ⚡ Performance
-
-#### Amélioré
-- ✅ Compression HTTP activée (réduction bande passante ~60%)
-- ✅ Timeouts REST optimisés (15s au lieu de 30s)
-- ✅ Cache tokens avec limite (prévention fuites mémoire)
-
-### 📊 Métriques de Qualité
-
-| Métrique | Avant | Après | Amélioration |
-|----------|-------|-------|--------------|
-| **Score Sécurité** | 4/10 | 10/10 | +150% |
-| **Score Qualité Code** | 6/10 | 9/10 | +50% |
-| **Score Tests** | 0/10 | 8/10 | ∞ |
-| **Score Performance** | 7/10 | 9/10 | +29% |
-| **Score Documentation** | 5/10 | 10/10 | +100% |
-| **Score Global** | 5.1/10 | 9.2/10 | +80% |
-
-### 🐛 Corrections
-
-#### Vulnérabilités Critiques Corrigées
-1. ✅ **SEC-001**: Secret Keycloak en dur → Supprimé
-2. ✅ **SEC-002**: TLS verification=none → Activé `required`
-3. ✅ **SEC-003**: Exposition erreurs backend → Messages génériques
-4. ✅ **SEC-004**: Logging données sensibles → Anonymisé
-5. ✅ **SEC-005**: Cache tokens illimité → Limite 10,000
-6. ✅ **SEC-006**: Cookie Secure=false → Activé
-
-### 📝 Notes de Migration
-
-#### Pour mettre à jour depuis une version < 1.0
-
-1. **Configurer les variables d'environnement**:
- ```bash
- export KEYCLOAK_CLIENT_SECRET="votre-nouveau-secret"
- export UNIONFLOW_BACKEND_URL="https://votre-backend.com"
- ```
-
-2. **Régénérer le secret Keycloak**:
- - Aller dans Keycloak Admin Console
- - Clients → unionflow-client → Credentials
- - Regenerate Secret
-
-3. **Mettre à jour les dépendances**:
- ```bash
- mvn clean install
- ```
-
-4. **Vérifier la configuration**:
- - `application-prod.properties` contient tous les headers de sécurité
- - `application-dev.properties` n'a pas de secret en dur
-
-5. **Exécuter les tests**:
- ```bash
- mvn test
- ```
-
-### 🔮 Prochaines Versions
-
-#### [1.1.0] - Planifié Q1 2026
-- Migration CSP vers nonces (suppression `unsafe-inline`)
-- Tests d'intégration complets
-- Lazy loading DataModel pour tous les DataTables
-- Refactoring inner classes en packages dédiés
-
-#### [1.2.0] - Planifié Q2 2026
-- Rate limiting
-- 2FA (Two-Factor Authentication)
-- Audit logs enrichis
-- Métriques Prometheus
-
----
-
-## Légende
-
-- **Ajouté**: Nouvelles fonctionnalités
-- **Modifié**: Changements dans des fonctionnalités existantes
-- **Déprécié**: Fonctionnalités qui seront supprimées
-- **Supprimé**: Fonctionnalités supprimées
-- **Corrigé**: Corrections de bugs
-- **Sécurité**: Corrections de vulnérabilités
-
----
-
-**Auteur**: Équipe UnionFlow
-**Date**: 17 Décembre 2025
-**Version**: 1.0.0
+# Changelog - UnionFlow Client
+
+Tous les changements notables de ce projet sont documentés dans ce fichier.
+
+Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/),
+et ce projet adhère au [Semantic Versioning](https://semver.org/lang/fr/).
+
+---
+
+## [3.0.0] - 2026-01-04 🚀 **PRODUCTION-READY**
+
+### 🎯 Migration Complète vers Architecture Production-Ready
+
+#### ✨ Ajouté - Services Transverses
+
+##### ErrorHandlerService
+- ✅ **Gestion centralisée des erreurs** avec méthodes `showSuccess()`, `showError()`, `showWarning()`, `showInfo()`
+- ✅ **Logging automatique** des exceptions avec contexte
+- ✅ **Conversion** des exceptions techniques en messages utilisateur clairs
+- ✅ **Gestion des redirections** en cas d'erreur critique
+
+##### RetryService
+- ✅ **Retry automatique** avec backoff exponentiel (1s, 2s, 4s)
+- ✅ **3 tentatives max** avec configuration flexible
+- ✅ **Détection intelligente** des exceptions retryables
+- ✅ **Méthodes** : `executeWithRetrySupplier()`, `executeWithRetry()`
+
+##### CacheService
+- ✅ **Cache en mémoire** avec TTL configurable (5 minutes par défaut)
+- ✅ **Invalidation** manuelle, par clé, ou par pattern
+- ✅ **Nettoyage automatique** des entrées expirées
+- ✅ **Optimisation** des appels backend répétitifs
+
+##### BackendCallInterceptor
+- ✅ **Logging automatique** des appels backend (paramètres, durée, résultats)
+- ✅ **Détection des appels lents** (>2s) avec warnings
+- ✅ **Masquage des données sensibles** dans les logs
+- ✅ **Annotation** : `@LogBackendCall`
+
+##### ValidationService
+- ✅ **Validation centralisée** des beans avec contraintes Jakarta
+- ✅ **Affichage structuré** des erreurs de validation
+- ✅ **Intégration** avec ErrorHandlerService
+
+#### 🔄 Modifié - Migration des Beans (48 beans)
+
+##### Beans Migrés vers Architecture Production-Ready
+- ✅ **OrganisationsBean** - Gestion des organisations
+- ✅ **TypeOrganisationsAdminBean** - Types d'organisations
+- ✅ **MembreListeBean** - Liste des membres
+- ✅ **MembreInscriptionBean** - Inscription membres
+- ✅ **MembreCotisationBean** - Cotisations membre
+- ✅ **MembreImportBean** - Import en masse
+- ✅ **MembreExportBean** - Export de données
+- ✅ **MembreProfilBean** - Profil membre
+- ✅ **MembreRechercheBean** - Recherche avancée
+- ✅ **AdhesionsBean** - Gestion des adhésions
+- ✅ **AdhesionHistoriqueBean** - Historique adhésions
+- ✅ **CotisationsBean** - Gestion cotisations
+- ✅ **CotisationsGestionBean** - Administration cotisations
+- ✅ **EvenementsBean** - Gestion des événements
+- ✅ **DemandesAideBean** - Demandes d'aide
+- ✅ **DemandesBean** - Gestion des demandes
+- ✅ **RapportsBean** - Génération de rapports
+- ✅ **RapportDetailsBean** - Détails des rapports
+- ✅ **TableauxBordBean** - Tableaux de bord analytiques
+- ✅ **DashboardBean** - Dashboard principal
+- ✅ **PreferencesBean** - Préférences utilisateur
+- ✅ **ParametresBean** - Paramètres application
+- ✅ **ConfigurationBean** - Configuration système
+- ✅ **PersonnelBean** - Gestion du personnel
+- ✅ **OrganisationDetailBean** - Détails organisation
+- ✅ **OrganisationStatistiquesBean** - Statistiques
+- ✅ **DocumentBean** - Documents personnels
+- ✅ **DocumentsBean** - Gestion documentaire
+- ✅ **NotificationBean** - Notifications
+- ✅ **SuggestionBean** - Suggestions
+- ✅ **TicketBean** - Support tickets
+- ✅ **AuditBean** - Logs d'audit
+- ✅ **ComptabiliteBean** - Comptabilité
+- ✅ **ExportMasseBean** - Export en masse
+- ✅ **SuperAdminBean** - Administration super-admin
+- ✅ **UtilisateursBean** - Gestion utilisateurs
+- ✅ **FavorisBean** - Favoris utilisateur
+- ✅ **WaveBean** - Intégration Wave Money
+- ✅ **LoginBean** - Authentification
+- ✅ **OrganisationsBean** - Gestion des organisations
+- ✅ Et 9 autres beans...
+
+##### Changements par Bean
+- 🔄 Remplacement de `java.util.logging.Logger` par `org.jboss.logging.Logger`
+- 🔄 Injection d'`ErrorHandlerService`, `RetryService`, `CacheService`
+- 🔄 Suppression des appels directs à `FacesContext.addMessage()`
+- 🔄 Enrobage des appels backend avec `retryService.executeWithRetrySupplier()`
+- 🔄 Utilisation du cache pour données fréquentes
+- 🔄 Logging structuré avec paramètres (`LOG.infof()`, `LOG.errorf()`)
+
+#### ❌ Supprimé
+
+##### Méthodes Obsolètes
+- ❌ ~50 méthodes `ajouterMessage()` redondantes supprimées
+- ❌ ~200 appels directs à `FacesContext.getCurrentInstance().addMessage()`
+- ❌ ~150 appels à `LOGGER.info/severe/warning()` avec concaténation
+
+##### Fichiers Temporaires (33 fichiers)
+- ❌ 3 fichiers .md obsolètes
+- ❌ 10 fichiers temporaires (tokens, configs debug)
+- ❌ 16 anciens tests dans `test.bak/`
+- ❌ 4 artefacts et fichiers orphelins
+
+#### 📈 Amélioré
+
+##### Performance
+- ⚡ **Cache** : Réduction de 70% des appels backend pour données de référence
+- ⚡ **Retry intelligent** : Gestion automatique des erreurs transitoires
+- ⚡ **Logging optimisé** : Paramètres au lieu de concaténation
+
+##### Maintenabilité
+- 📝 **Code DRY** : Centralisation de la gestion des erreurs
+- 📝 **Logging cohérent** : Format uniforme dans toute l'application
+- 📝 **Messages clairs** : Séparation des messages techniques et utilisateur
+
+##### Robustesse
+- 🛡️ **Gestion d'erreurs** : Try-catch systématique avec handling approprié
+- 🛡️ **Résilience** : Retry automatique pour erreurs temporaires
+- 🛡️ **Validation** : Contrôles avant appels backend
+
+#### 🧪 Tests
+- ✅ **15/15 tests passent** (100% client)
+- ✅ **Aucune régression** après migration
+- ✅ **Validation complète** des validateurs personnalisés
+
+#### 📚 Documentation
+- ✅ Création de `DOCUMENTATION.md` - Index complet
+- ✅ Mise à jour de `README.md`
+- ✅ Création de `RESUME_MIGRATION_BEANS_ET_TESTS.md`
+- ✅ Nettoyage de 3 fichiers .md obsolètes
+- ✅ Amélioration du `.gitignore`
+
+---
+
+## [1.0.0] - 2025-12-17
+
+### 🔒 Sécurité Critique - RÉSOLU
+
+#### Ajouté
+- ✅ **Headers de sécurité HTTP complets** (CSP, HSTS, X-Frame-Options, etc.)
+ - `X-Content-Type-Options: nosniff`
+ - `X-Frame-Options: DENY`
+ - `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload`
+ - `Content-Security-Policy` avec support PrimeFaces
+ - `Referrer-Policy: strict-origin-when-cross-origin`
+ - `Permissions-Policy`
+
+- ✅ **Compression HTTP** activée (gzip, niveau 6)
+- ✅ **Support rôles multiples** dans PermissionChecker
+ - Méthode `hasAnyRole()` améliorée
+ - Méthode `hasAllRoles()` ajoutée
+ - Méthode `hasRoleOrHigher()` avec hiérarchie
+- ✅ **Limite cache tokens** (10,000 max) - Protection DoS
+- ✅ **Nettoyage automatique** des tokens expirés
+- ✅ **Tests unitaires** pour validateurs (MemberNumberValidator)
+- ✅ **Documentation complète** (README.md, SECURITY.md)
+
+#### Modifié
+- ✅ **Secret Keycloak supprimé** du code source (application-dev.properties)
+ - Utilisation exclusive de variables d'environnement
+ - Documentation ajoutée pour la configuration
+
+- ✅ **TLS verification activée** même en développement
+ - `quarkus.oidc.tls.verification=required` (était `none`)
+ - Protection contre MITM
+
+- ✅ **Session cookies sécurisés**
+ - `quarkus.http.session-cookie-secure=true` (était `false`)
+ - `quarkus.http.session-cookie-same-site=strict` (était `lax`)
+
+- ✅ **RestClientExceptionMapper amélioré**
+ - Messages d'erreur génériques pour erreurs 5xx
+ - Pas d'exposition des détails backend
+ - Logging sécurisé sans informations sensibles
+
+- ✅ **Logging de données sensibles supprimé**
+ - UserSession: Suppression logs username/rôles
+ - AuthenticationFilter: Anonymisation des logs
+ - TokenRefreshService: Suppression logs sessionId
+
+- ✅ **Backend URL par défaut en HTTPS**
+ - `unionflow.backend.url` utilise HTTPS au lieu de HTTP
+
+- ✅ **Timeouts REST optimisés**
+ - `read-timeout` réduit de 30s à 15s
+
+- ✅ **CSP activé** en développement et production
+ - `primefaces.CSP=true`
+
+#### Dépendances Mises à Jour
+- ✅ Lombok: `1.18.30` → `1.18.34` (dernière version stable)
+- ✅ Apache POI: `5.2.5` → `5.3.0` (correctifs sécurité)
+
+### 🧪 Tests
+
+#### Ajouté
+- ✅ Structure complète de tests
+ - `src/test/java/dev/lions/unionflow/client/validation/`
+ - `src/test/java/dev/lions/unionflow/client/security/`
+ - `src/test/java/dev/lions/unionflow/client/service/`
+
+- ✅ **MemberNumberValidatorTest.java** (100% couverture)
+ - 14 tests unitaires complets
+ - Tests de cas nominaux et limites
+ - Tests de validation d'année
+ - Tests de format
+
+### 📚 Documentation
+
+#### Ajouté
+- ✅ **README.md complet** (8,000+ mots)
+ - Guide d'installation détaillé
+ - Configuration complète
+ - Architecture documentée
+ - Déploiement expliqué
+ - Support et troubleshooting
+
+- ✅ **SECURITY.md** (politique de sécurité complète)
+ - Architecture de sécurité en profondeur
+ - Gestion des secrets
+ - Signalement de vulnérabilités
+ - Conformité OWASP Top 10
+
+- ✅ **CHANGELOG.md** (ce fichier)
+
+- ✅ **Javadoc améliorée**
+ - TokenRefreshService avec documentation complète
+ - PermissionChecker avec exemples
+ - Annotations de sécurité ajoutées
+
+### 🏗️ Architecture
+
+#### Amélioré
+- ✅ **PermissionChecker**: Support complet des rôles multiples
+ - Hiérarchie de rôles définie
+ - Méthode `getHighestRole()`
+ - Vérifications granulaires
+
+- ✅ **TokenRefreshService**: Gestion sécurisée et performante
+ - Limite de cache (10,000 tokens)
+ - Nettoyage automatique des tokens expirés
+ - Suppression forcée des plus anciens si cache plein
+ - Méthode `getActiveTokenCount()` pour monitoring
+
+### 🔧 Configuration
+
+#### Modifié
+- ✅ `application.properties`:
+ - Session cookie secure=true
+ - Session cookie same-site=strict
+ - Backend URL HTTPS
+ - Read timeout optimisé
+ - CSP activé
+
+- ✅ `application-dev.properties`:
+ - Secret Keycloak supprimé (variable d'environnement uniquement)
+ - TLS verification=required
+ - Documentation sécurité ajoutée
+
+- ✅ `application-prod.properties`:
+ - Headers de sécurité HTTP complets
+ - Compression HTTP activée
+ - Read timeout optimisé
+ - Configuration sécurité renforcée
+
+### ⚡ Performance
+
+#### Amélioré
+- ✅ Compression HTTP activée (réduction bande passante ~60%)
+- ✅ Timeouts REST optimisés (15s au lieu de 30s)
+- ✅ Cache tokens avec limite (prévention fuites mémoire)
+
+### 📊 Métriques de Qualité
+
+| Métrique | Avant | Après | Amélioration |
+|----------|-------|-------|--------------|
+| **Score Sécurité** | 4/10 | 10/10 | +150% |
+| **Score Qualité Code** | 6/10 | 9/10 | +50% |
+| **Score Tests** | 0/10 | 8/10 | ∞ |
+| **Score Performance** | 7/10 | 9/10 | +29% |
+| **Score Documentation** | 5/10 | 10/10 | +100% |
+| **Score Global** | 5.1/10 | 9.2/10 | +80% |
+
+### 🐛 Corrections
+
+#### Vulnérabilités Critiques Corrigées
+1. ✅ **SEC-001**: Secret Keycloak en dur → Supprimé
+2. ✅ **SEC-002**: TLS verification=none → Activé `required`
+3. ✅ **SEC-003**: Exposition erreurs backend → Messages génériques
+4. ✅ **SEC-004**: Logging données sensibles → Anonymisé
+5. ✅ **SEC-005**: Cache tokens illimité → Limite 10,000
+6. ✅ **SEC-006**: Cookie Secure=false → Activé
+
+### 📝 Notes de Migration
+
+#### Pour mettre à jour depuis une version < 1.0
+
+1. **Configurer les variables d'environnement**:
+ ```bash
+ export KEYCLOAK_CLIENT_SECRET="votre-nouveau-secret"
+ export UNIONFLOW_BACKEND_URL="https://votre-backend.com"
+ ```
+
+2. **Régénérer le secret Keycloak**:
+ - Aller dans Keycloak Admin Console
+ - Clients → unionflow-client → Credentials
+ - Regenerate Secret
+
+3. **Mettre à jour les dépendances**:
+ ```bash
+ mvn clean install
+ ```
+
+4. **Vérifier la configuration**:
+ - `application-prod.properties` contient tous les headers de sécurité
+ - `application-dev.properties` n'a pas de secret en dur
+
+5. **Exécuter les tests**:
+ ```bash
+ mvn test
+ ```
+
+### 🔮 Prochaines Versions
+
+#### [1.1.0] - Planifié Q1 2026
+- Migration CSP vers nonces (suppression `unsafe-inline`)
+- Tests d'intégration complets
+- Lazy loading DataModel pour tous les DataTables
+- Refactoring inner classes en packages dédiés
+
+#### [1.2.0] - Planifié Q2 2026
+- Rate limiting
+- 2FA (Two-Factor Authentication)
+- Audit logs enrichis
+- Métriques Prometheus
+
+---
+
+## Légende
+
+- **Ajouté**: Nouvelles fonctionnalités
+- **Modifié**: Changements dans des fonctionnalités existantes
+- **Déprécié**: Fonctionnalités qui seront supprimées
+- **Supprimé**: Fonctionnalités supprimées
+- **Corrigé**: Corrections de bugs
+- **Sécurité**: Corrections de vulnérabilités
+
+---
+
+**Auteur**: Équipe UnionFlow
+**Date**: 17 Décembre 2025
+**Version**: 1.0.0
diff --git a/META-INF/primefaces-freya.taglib.xml b/META-INF/primefaces-freya.taglib.xml
index 1fef044..a2fcd87 100644
--- a/META-INF/primefaces-freya.taglib.xml
+++ b/META-INF/primefaces-freya.taglib.xml
@@ -1,60 +1,60 @@
-
-
- http://primefaces.org/freya
-
-
- menu
-
- org.primefaces.component.FreyaMenu
- org.primefaces.component.FreyaMenuRenderer
-
-
-
- id
- false
- java.lang.String
-
-
-
- rendered
- false
- java.lang.Boolean
-
-
-
- binding
- false
- jakarta.faces.component.UIComponent
-
-
-
- widgetVar
- false
- java.lang.String
-
-
-
- model
- false
- org.primefaces.model.menu.MenuModel
-
-
-
- style
- false
- java.lang.String
-
-
-
- styleClass
- false
- java.lang.String
-
-
-
- closeDelay
- false
- java.lang.Integer
-
-
-
+
+
+ http://primefaces.org/freya
+
+
+ menu
+
+ org.primefaces.component.FreyaMenu
+ org.primefaces.component.FreyaMenuRenderer
+
+
+
+ id
+ false
+ java.lang.String
+
+
+
+ rendered
+ false
+ java.lang.Boolean
+
+
+
+ binding
+ false
+ jakarta.faces.component.UIComponent
+
+
+
+ widgetVar
+ false
+ java.lang.String
+
+
+
+ model
+ false
+ org.primefaces.model.menu.MenuModel
+
+
+
+ style
+ false
+ java.lang.String
+
+
+
+ styleClass
+ false
+ java.lang.String
+
+
+
+ closeDelay
+ false
+ java.lang.Integer
+
+
+
diff --git a/README.md b/README.md
index 3806b5a..30919e0 100644
--- a/README.md
+++ b/README.md
@@ -1,496 +1,496 @@
-# UnionFlow Client - Application Web de Gestion
-
-
-
-
-
-
-
-Application web moderne de gestion pour organisations Lions Club, basée sur Quarkus, Jakarta EE 10, JSF 4.0 et PrimeFaces 14 avec le thème Freya.
-
-## 📋 Table des Matières
-
-- [Caractéristiques](#caractéristiques)
-- [Architecture](#architecture)
-- [Prérequis](#prérequis)
-- [Installation](#installation)
-- [Configuration](#configuration)
-- [Lancement](#lancement)
-- [Sécurité](#sécurité)
-- [Tests](#tests)
-- [Déploiement](#déploiement)
-- [Support](#support)
-
-## ✨ Caractéristiques
-
-### Fonctionnalités Principales
-
-- **Gestion des Membres** - Inscription, profils, recherche avancée, import/export
-- **Gestion des Cotisations** - Suivi des paiements, relances automatiques, statistiques
-- **Gestion des Événements** - Planification, participants, rapports
-- **Demandes d'Aide** - Workflow de validation, suivi des bénéficiaires
-- **Rapports et Analytics** - Tableaux de bord personnalisés, exports multiples formats
-- **Gestion des Associations** - Organisation hiérarchique, quotas
-- **Administration** - Configuration système, gestion des utilisateurs, audit logs
-
-### Technologies Clés
-
-- **Backend Framework**: Quarkus 3.15.1 (JVM optimisé, démarrage rapide)
-- **UI Framework**: JSF 4.0 (MyFaces) + PrimeFaces 14.0.5
-- **UI Theme**: Freya 5.0.0 (design moderne et responsive)
-- **Sécurité**: Keycloak OIDC + JWT
-- **Validation**: Hibernate Validator + validateurs personnalisés
-- **Export**: Apache POI (Excel), OpenPDF (PDF)
-- **Résilience**: RetryService avec backoff exponentiel ⭐ **NOUVEAU**
-- **Performance**: CacheService en mémoire avec TTL ⭐ **NOUVEAU**
-- **Monitoring**: BackendCallInterceptor pour métriques ⭐ **NOUVEAU**
-
-### 🎉 Version 3.0 - Production-Ready (2026-01-04)
-
-#### Améliorations Majeures
-- ✅ **48 beans JSF migrés** vers architecture production-ready
-- ✅ **ErrorHandlerService** - Gestion centralisée des erreurs
-- ✅ **RetryService** - Retry automatique avec backoff exponentiel
-- ✅ **CacheService** - Cache en mémoire pour optimisation
-- ✅ **BackendCallInterceptor** - Logging et métriques automatiques
-- ✅ **Logging structuré** - Migration vers `org.jboss.logging.Logger`
-
-## 🏗️ Architecture
-
-### Architecture en Couches
-
-```
-┌─────────────────────────────────────────────────────┐
-│ PRESENTATION LAYER (JSF/PrimeFaces) │
-│ - 175 pages XHTML │
-│ - 48 Backing Beans (Production-Ready) │
-│ - Freya Theme (CSS, JS, Icons) │
-└─────────────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────────────┐
-│ SERVICE LAYER (REST Clients) │
-│ - 24+ interfaces REST Client (MicroProfile) │
-│ - 14+ DTOs validés │
-│ - Exception Mapping │
-└─────────────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────────────┐
-│ SECURITY LAYER │
-│ - OIDC Authentication (Keycloak) │
-│ - JWT Token Management │
-│ - Role-Based Access Control (RBAC) │
-│ - Permission Checker │
-└─────────────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────────────┐
-│ EXTERNAL SYSTEMS │
-│ - UnionFlow Backend REST API │
-│ - Keycloak OIDC Server │
-│ - Wave Payment Gateway (optional) │
-└─────────────────────────────────────────────────────┘
-```
-
-### Stack Technique Complet
-
-| Composant | Version | Rôle |
-|-----------|---------|------|
-| Java | 17 (LTS) | Langage |
-| Quarkus | 3.15.1 | Framework application |
-| Jakarta EE | 10 | Standard entreprise |
-| JSF (MyFaces) | 4.0 | MVC web framework |
-| PrimeFaces | 14.0.5 | Composants riches |
-| OmniFaces | 4.4.1 | Utilitaires JSF |
-| Lombok | 1.18.34 | Réduction boilerplate |
-| Apache POI | 5.3.0 | Export Excel |
-| OpenPDF | 1.3.30 | Export PDF |
-
-## 🚀 Services Production-Ready
-
-L'application dispose de services transverses pour garantir la robustesse en production :
-
-### ErrorHandlerService
-**Gestion centralisée des erreurs**
-- Messages utilisateur clairs et localisés
-- Logging automatique des exceptions
-- Méthodes : `showSuccess()`, `showError()`, `showWarning()`, `handleException()`
-
-### RetryService
-**Résilience des appels backend**
-- Retry automatique avec backoff exponentiel (3 tentatives, délai x2)
-- Gestion intelligente des exceptions retryables
-- Méthode : `executeWithRetrySupplier()`
-
-### CacheService
-**Optimisation des performances**
-- Cache en mémoire avec TTL configurable (5 minutes par défaut)
-- Invalidation manuelle ou automatique
-- Méthodes : `get()`, `put()`, `invalidate()`, `invalidateAll()`
-
-### BackendCallInterceptor
-**Monitoring et métriques**
-- Logging automatique des appels backend (paramètres, durée, résultats)
-- Détection des appels lents (>2s)
-- Masquage des données sensibles dans les logs
-- Annotation : `@LogBackendCall`
-
-### ValidationService
-**Validation centralisée**
-- Validation des beans avec contraintes Jakarta
-- Messages d'erreur structurés
-- Intégration avec ErrorHandlerService
-
----
-
-## 📦 Prérequis
-
-### Environnement de Développement
-
-- **Java Development Kit (JDK)**: OpenJDK 17 ou supérieur
-- **Apache Maven**: 3.8+ (pour la compilation)
-- **Git**: 2.30+ (pour le versioning)
-- **IDE recommandé**: IntelliJ IDEA ou Eclipse avec support Quarkus
-
-### Services Externes Requis
-
-- **Keycloak Server**: 22+ (authentification OIDC)
-- **UnionFlow Backend API**: Service REST backend
-- **Base de données** (via backend): PostgreSQL 14+ ou MongoDB 6+
-
-### Configuration Minimale Serveur
-
-- **CPU**: 2 cores minimum
-- **RAM**: 4GB minimum (8GB recommandé)
-- **Disque**: 2GB espace libre
-- **OS**: Linux (Ubuntu 20.04+), Windows Server 2019+, macOS 11+
-
-## 🚀 Installation
-
-### 1. Cloner le Projet
-
-```bash
-git clone https://git.lions.dev/lionsdev/unionflow-client-quarkus-primefaces-freya.git
-cd unionflow-client-quarkus-primefaces-freya
-```
-
-### 2. Configuration Maven
-
-Assurez-vous que le repository privé Gitea est configuré dans `~/.m2/settings.xml`:
-
-```xml
-
-
-
- gitea
- ${env.GITEA_USERNAME}
- ${env.GITEA_TOKEN}
-
-
-
-```
-
-### 3. Compilation
-
-```bash
-# Compilation standard
-mvn clean package
-
-# Compilation sans tests (développement rapide)
-mvn clean package -DskipTests
-
-# Compilation avec profil production
-mvn clean package -Pproduction
-```
-
-## ⚙️ Configuration
-
-### Variables d'Environnement Requises
-
-#### Développement
-
-```bash
-# Keycloak
-export KEYCLOAK_CLIENT_SECRET="votre-secret-keycloak-dev"
-
-# Backend
-export UNIONFLOW_BACKEND_URL="https://localhost:8085"
-```
-
-#### Production
-
-```bash
-# Keycloak
-export KEYCLOAK_CLIENT_SECRET="votre-secret-keycloak-prod"
-export KEYCLOAK_AUTH_SERVER_URL="https://security.lions.dev/realms/unionflow"
-
-# Backend
-export UNIONFLOW_BACKEND_URL="https://api.lions.dev/unionflow"
-
-# Session
-export SESSION_TIMEOUT="1800" # 30 minutes
-export REMEMBER_ME_DURATION="604800" # 7 jours
-
-# Sécurité
-export ENABLE_CSRF="true"
-export PASSWORD_MIN_LENGTH="8"
-export PASSWORD_REQUIRE_SPECIAL="true"
-export MAX_LOGIN_ATTEMPTS="5"
-export LOCKOUT_DURATION="300"
-```
-
-### Fichiers de Configuration
-
-- **`application.properties`**: Configuration par défaut (développement)
-- **`application-prod.properties`**: Configuration production
-- **`application-dev.properties`**: Configuration développement spécifique
-
-### Configuration Keycloak
-
-1. Créer un realm `unionflow` dans Keycloak
-2. Créer un client `unionflow-client`:
- - Client Protocol: `openid-connect`
- - Access Type: `confidential`
- - Valid Redirect URIs: `https://votre-domaine.com/*`
- - Web Origins: `https://votre-domaine.com`
-3. Configurer les rôles:
- - `SUPER_ADMIN`: Administrateur système
- - `ADMIN_ORGANISATION`: Administrateur d'organisation
- - `MEMBRE`: Membre standard
-4. Configurer les mappers pour inclure les rôles dans les tokens JWT
-
-## 🏃 Lancement
-
-### Mode Développement
-
-```bash
-# Lancement avec rechargement automatique (Live Reload)
-./mvnw quarkus:dev
-
-# Accès
-# - Application: http://localhost:8086
-# - Dev UI: http://localhost:8086/q/dev
-```
-
-### Mode Production
-
-```bash
-# Construire l'application
-./mvnw clean package -Pproduction
-
-# Lancer en production
-java -jar target/quarkus-app/quarkus-run.jar
-
-# Ou avec profil spécifique
-java -Dquarkus.profile=prod -jar target/quarkus-app/quarkus-run.jar
-```
-
-### Docker (Optionnel)
-
-```bash
-# Construction de l'image
-docker build -f src/main/docker/Dockerfile.jvm -t unionflow-client:latest .
-
-# Lancement du conteneur
-docker run -p 8080:8080 \
- -e KEYCLOAK_CLIENT_SECRET="votre-secret" \
- -e UNIONFLOW_BACKEND_URL="https://api.lions.dev/unionflow" \
- unionflow-client:latest
-```
-
-## 🔒 Sécurité
-
-### Authentification et Autorisation
-
-- **Méthode**: OpenID Connect (OIDC) via Keycloak
-- **Tokens**: JWT (JSON Web Tokens)
-- **Rôles supportés**: SUPER_ADMIN, ADMIN_ORGANISATION, MEMBRE
-- **Permissions granulaires**: Basées sur les rôles et fonctionnalités
-
-### Headers de Sécurité (Production)
-
-L'application configure automatiquement les headers de sécurité suivants:
-
-- `X-Content-Type-Options: nosniff`
-- `X-Frame-Options: DENY`
-- `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload`
-- `Content-Security-Policy`: Configuration stricte avec support PrimeFaces
-- `X-XSS-Protection: 1; mode=block`
-- `Referrer-Policy: strict-origin-when-cross-origin`
-
-### Bonnes Pratiques
-
-1. **Secrets**: Ne JAMAIS committer de secrets dans Git
-2. **HTTPS**: Toujours utiliser HTTPS en production
-3. **Cookies**: HttpOnly et SameSite=Strict activés
-4. **Sessions**: Timeout de 60 minutes par défaut
-5. **TLS**: Vérification TLS obligatoire même en dev
-
-Pour plus de détails, consultez [SECURITY.md](SECURITY.md).
-
-## 🧪 Tests
-
-### Lancement des Tests
-
-```bash
-# Tous les tests
-mvn test
-
-# Tests unitaires uniquement
-mvn test -Dtest="*Test"
-
-# Tests d'intégration uniquement
-mvn test -Dtest="*IT"
-
-# Tests avec couverture
-mvn test jacoco:report
-```
-
-### Structure des Tests
-
-```
-src/test/java/
-├── validation/ # Tests unitaires validateurs
-│ ├── MemberNumberValidatorTest.java
-│ └── PhoneNumberValidatorTest.java
-├── security/ # Tests services de sécurité
-│ ├── PermissionCheckerTest.java
-│ └── TokenRefreshServiceTest.java
-└── service/ # Tests d'intégration REST clients
- ├── MembreServiceIT.java
- └── AuthenticationServiceIT.java
-```
-
-### Résultats des Tests
-
-**Status** : ✅ **15/15 tests passent** (100%)
-
-- ✅ `MemberNumberValidatorTest` : 15/15 tests
-- ✅ Tous les validateurs personnalisés testés
-- ✅ Aucune régression après migration
-
-### Couverture de Code
-
-Objectif: **80%** minimum
-
-- Validateurs: 100%
-- Services de sécurité: 90%
-- REST Clients: 70%
-- Backing Beans: 60%
-
-## 🚢 Déploiement
-
-### Déploiement sur Serveur Linux
-
-```bash
-# 1. Transférer l'artifact
-scp target/quarkus-app/quarkus-run.jar user@serveur:/opt/unionflow/
-
-# 2. Configurer le service systemd
-sudo nano /etc/systemd/system/unionflow-client.service
-
-# 3. Contenu du service
-[Unit]
-Description=UnionFlow Client Application
-After=network.target
-
-[Service]
-Type=simple
-User=unionflow
-WorkingDirectory=/opt/unionflow
-ExecStart=/usr/bin/java -jar /opt/unionflow/quarkus-run.jar
-Restart=on-failure
-Environment="KEYCLOAK_CLIENT_SECRET=xxx"
-Environment="UNIONFLOW_BACKEND_URL=https://api.lions.dev/unionflow"
-
-[Install]
-WantedBy=multi-user.target
-
-# 4. Activer et démarrer
-sudo systemctl enable unionflow-client
-sudo systemctl start unionflow-client
-sudo systemctl status unionflow-client
-```
-
-### Déploiement avec Nginx Reverse Proxy
-
-```nginx
-server {
- listen 443 ssl http2;
- server_name unionflow.lions.dev;
-
- ssl_certificate /etc/letsencrypt/live/unionflow.lions.dev/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/unionflow.lions.dev/privkey.pem;
-
- location / {
- proxy_pass http://localhost:8080;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
-}
-```
-
-## 📚 Documentation Supplémentaire
-
-- **Architecture Détaillée**: `/docs/ARCHITECTURE.md`
-- **Guide de Sécurité**: [SECURITY.md](SECURITY.md)
-- **Guide de Contribution**: `/docs/CONTRIBUTING.md`
-- **Changelog**: [CHANGELOG.md](CHANGELOG.md)
-- **API Documentation**: Disponible sur le backend
-
-## 🐛 Problèmes Connus et Solutions
-
-### ViewExpiredException
-
-Si vous rencontrez des `ViewExpiredException`, vérifiez:
-- Le timeout de session (`quarkus.http.session-timeout`)
-- Le nombre de vues en session (`quarkus.myfaces.number-of-views-in-session`)
-
-### Erreur OIDC "Invalid Token"
-
-Solution:
-1. Vérifier que le client Keycloak est correctement configuré
-2. Vérifier la variable `KEYCLOAK_CLIENT_SECRET`
-3. Vérifier l'URL du serveur Keycloak
-
-### Erreur "BeanManager.getELResolver"
-
-Déjà corrigé via `QuarkusArcELResolver`. Si le problème persiste:
-1. Vérifier la configuration Arc CDI dans `application.properties`
-2. Vérifier que `faces-config.xml` contient `QuarkusApplicationFactory`
-
-## 📞 Support
-
-### Équipe de Développement
-
-- **Email**: support@lions.dev
-- **Slack**: #unionflow-support
-- **Issue Tracker**: https://git.lions.dev/lionsdev/unionflow-client/issues
-
-### Resources
-
-- **Documentation Quarkus**: https://quarkus.io/guides/
-- **Documentation PrimeFaces**: https://www.primefaces.org/showcase/
-- **Documentation Keycloak**: https://www.keycloak.org/documentation
-
-## 📄 Licence
-
-Propriétaire - © 2025 Lions Club International - Tous droits réservés
-
----
-
-## 📊 État du Projet
-
-- ✅ **Version** : 3.0.0
-- ✅ **Status** : Production-Ready
-- ✅ **Tests** : 15/15 (100%)
-- ✅ **Beans** : 48 beans migrés
-- ✅ **Services** : 5 services transverses
-- ✅ **Documentation** : Complète et à jour
-
----
-
-**Version**: 3.0.0
-**Dernière mise à jour**: 4 Janvier 2026
-**Auteur**: Équipe UnionFlow
-**License**: Proprietary - Lions Club Côte d'Ivoire
+# UnionFlow Client - Application Web de Gestion
+
+
+
+
+
+
+
+Application web moderne de gestion pour organisations Lions Club, basée sur Quarkus, Jakarta EE 10, JSF 4.0 et PrimeFaces 14 avec le thème Freya.
+
+## 📋 Table des Matières
+
+- [Caractéristiques](#caractéristiques)
+- [Architecture](#architecture)
+- [Prérequis](#prérequis)
+- [Installation](#installation)
+- [Configuration](#configuration)
+- [Lancement](#lancement)
+- [Sécurité](#sécurité)
+- [Tests](#tests)
+- [Déploiement](#déploiement)
+- [Support](#support)
+
+## ✨ Caractéristiques
+
+### Fonctionnalités Principales
+
+- **Gestion des Membres** - Inscription, profils, recherche avancée, import/export
+- **Gestion des Cotisations** - Suivi des paiements, relances automatiques, statistiques
+- **Gestion des Événements** - Planification, participants, rapports
+- **Demandes d'Aide** - Workflow de validation, suivi des bénéficiaires
+- **Rapports et Analytics** - Tableaux de bord personnalisés, exports multiples formats
+- **Gestion des Associations** - Organisation hiérarchique, quotas
+- **Administration** - Configuration système, gestion des utilisateurs, audit logs
+
+### Technologies Clés
+
+- **Backend Framework**: Quarkus 3.15.1 (JVM optimisé, démarrage rapide)
+- **UI Framework**: JSF 4.0 (MyFaces) + PrimeFaces 14.0.5
+- **UI Theme**: Freya 5.0.0 (design moderne et responsive)
+- **Sécurité**: Keycloak OIDC + JWT
+- **Validation**: Hibernate Validator + validateurs personnalisés
+- **Export**: Apache POI (Excel), OpenPDF (PDF)
+- **Résilience**: RetryService avec backoff exponentiel ⭐ **NOUVEAU**
+- **Performance**: CacheService en mémoire avec TTL ⭐ **NOUVEAU**
+- **Monitoring**: BackendCallInterceptor pour métriques ⭐ **NOUVEAU**
+
+### 🎉 Version 3.0 - Production-Ready (2026-01-04)
+
+#### Améliorations Majeures
+- ✅ **48 beans JSF migrés** vers architecture production-ready
+- ✅ **ErrorHandlerService** - Gestion centralisée des erreurs
+- ✅ **RetryService** - Retry automatique avec backoff exponentiel
+- ✅ **CacheService** - Cache en mémoire pour optimisation
+- ✅ **BackendCallInterceptor** - Logging et métriques automatiques
+- ✅ **Logging structuré** - Migration vers `org.jboss.logging.Logger`
+
+## 🏗️ Architecture
+
+### Architecture en Couches
+
+```
+┌─────────────────────────────────────────────────────┐
+│ PRESENTATION LAYER (JSF/PrimeFaces) │
+│ - 175 pages XHTML │
+│ - 48 Backing Beans (Production-Ready) │
+│ - Freya Theme (CSS, JS, Icons) │
+└─────────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────┐
+│ SERVICE LAYER (REST Clients) │
+│ - 24+ interfaces REST Client (MicroProfile) │
+│ - 14+ DTOs validés │
+│ - Exception Mapping │
+└─────────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────┐
+│ SECURITY LAYER │
+│ - OIDC Authentication (Keycloak) │
+│ - JWT Token Management │
+│ - Role-Based Access Control (RBAC) │
+│ - Permission Checker │
+└─────────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────────┐
+│ EXTERNAL SYSTEMS │
+│ - UnionFlow Backend REST API │
+│ - Keycloak OIDC Server │
+│ - Wave Payment Gateway (optional) │
+└─────────────────────────────────────────────────────┘
+```
+
+### Stack Technique Complet
+
+| Composant | Version | Rôle |
+|-----------|---------|------|
+| Java | 17 (LTS) | Langage |
+| Quarkus | 3.15.1 | Framework application |
+| Jakarta EE | 10 | Standard entreprise |
+| JSF (MyFaces) | 4.0 | MVC web framework |
+| PrimeFaces | 14.0.5 | Composants riches |
+| OmniFaces | 4.4.1 | Utilitaires JSF |
+| Lombok | 1.18.34 | Réduction boilerplate |
+| Apache POI | 5.3.0 | Export Excel |
+| OpenPDF | 1.3.30 | Export PDF |
+
+## 🚀 Services Production-Ready
+
+L'application dispose de services transverses pour garantir la robustesse en production :
+
+### ErrorHandlerService
+**Gestion centralisée des erreurs**
+- Messages utilisateur clairs et localisés
+- Logging automatique des exceptions
+- Méthodes : `showSuccess()`, `showError()`, `showWarning()`, `handleException()`
+
+### RetryService
+**Résilience des appels backend**
+- Retry automatique avec backoff exponentiel (3 tentatives, délai x2)
+- Gestion intelligente des exceptions retryables
+- Méthode : `executeWithRetrySupplier()`
+
+### CacheService
+**Optimisation des performances**
+- Cache en mémoire avec TTL configurable (5 minutes par défaut)
+- Invalidation manuelle ou automatique
+- Méthodes : `get()`, `put()`, `invalidate()`, `invalidateAll()`
+
+### BackendCallInterceptor
+**Monitoring et métriques**
+- Logging automatique des appels backend (paramètres, durée, résultats)
+- Détection des appels lents (>2s)
+- Masquage des données sensibles dans les logs
+- Annotation : `@LogBackendCall`
+
+### ValidationService
+**Validation centralisée**
+- Validation des beans avec contraintes Jakarta
+- Messages d'erreur structurés
+- Intégration avec ErrorHandlerService
+
+---
+
+## 📦 Prérequis
+
+### Environnement de Développement
+
+- **Java Development Kit (JDK)**: OpenJDK 17 ou supérieur
+- **Apache Maven**: 3.8+ (pour la compilation)
+- **Git**: 2.30+ (pour le versioning)
+- **IDE recommandé**: IntelliJ IDEA ou Eclipse avec support Quarkus
+
+### Services Externes Requis
+
+- **Keycloak Server**: 22+ (authentification OIDC)
+- **UnionFlow Backend API**: Service REST backend
+- **Base de données** (via backend): PostgreSQL 14+ ou MongoDB 6+
+
+### Configuration Minimale Serveur
+
+- **CPU**: 2 cores minimum
+- **RAM**: 4GB minimum (8GB recommandé)
+- **Disque**: 2GB espace libre
+- **OS**: Linux (Ubuntu 20.04+), Windows Server 2019+, macOS 11+
+
+## 🚀 Installation
+
+### 1. Cloner le Projet
+
+```bash
+git clone https://git.lions.dev/lionsdev/unionflow-client-quarkus-primefaces-freya.git
+cd unionflow-client-quarkus-primefaces-freya
+```
+
+### 2. Configuration Maven
+
+Assurez-vous que le repository privé Gitea est configuré dans `~/.m2/settings.xml`:
+
+```xml
+
+
+
+ gitea
+ ${env.GITEA_USERNAME}
+ ${env.GITEA_TOKEN}
+
+
+
+```
+
+### 3. Compilation
+
+```bash
+# Compilation standard
+mvn clean package
+
+# Compilation sans tests (développement rapide)
+mvn clean package -DskipTests
+
+# Compilation avec profil production
+mvn clean package -Pproduction
+```
+
+## ⚙️ Configuration
+
+### Variables d'Environnement Requises
+
+#### Développement
+
+```bash
+# Keycloak
+export KEYCLOAK_CLIENT_SECRET="votre-secret-keycloak-dev"
+
+# Backend
+export UNIONFLOW_BACKEND_URL="https://localhost:8085"
+```
+
+#### Production
+
+```bash
+# Keycloak
+export KEYCLOAK_CLIENT_SECRET="votre-secret-keycloak-prod"
+export KEYCLOAK_AUTH_SERVER_URL="https://security.lions.dev/realms/unionflow"
+
+# Backend
+export UNIONFLOW_BACKEND_URL="https://api.lions.dev/unionflow"
+
+# Session
+export SESSION_TIMEOUT="1800" # 30 minutes
+export REMEMBER_ME_DURATION="604800" # 7 jours
+
+# Sécurité
+export ENABLE_CSRF="true"
+export PASSWORD_MIN_LENGTH="8"
+export PASSWORD_REQUIRE_SPECIAL="true"
+export MAX_LOGIN_ATTEMPTS="5"
+export LOCKOUT_DURATION="300"
+```
+
+### Fichiers de Configuration
+
+- **`application.properties`**: Configuration par défaut (développement)
+- **`application-prod.properties`**: Configuration production
+- **`application-dev.properties`**: Configuration développement spécifique
+
+### Configuration Keycloak
+
+1. Créer un realm `unionflow` dans Keycloak
+2. Créer un client `unionflow-client`:
+ - Client Protocol: `openid-connect`
+ - Access Type: `confidential`
+ - Valid Redirect URIs: `https://votre-domaine.com/*`
+ - Web Origins: `https://votre-domaine.com`
+3. Configurer les rôles:
+ - `SUPER_ADMIN`: Administrateur système
+ - `ADMIN_ORGANISATION`: Administrateur d'organisation
+ - `MEMBRE`: Membre standard
+4. Configurer les mappers pour inclure les rôles dans les tokens JWT
+
+## 🏃 Lancement
+
+### Mode Développement
+
+```bash
+# Lancement avec rechargement automatique (Live Reload)
+./mvnw quarkus:dev
+
+# Accès
+# - Application: http://localhost:8086
+# - Dev UI: http://localhost:8086/q/dev
+```
+
+### Mode Production
+
+```bash
+# Construire l'application
+./mvnw clean package -Pproduction
+
+# Lancer en production
+java -jar target/quarkus-app/quarkus-run.jar
+
+# Ou avec profil spécifique
+java -Dquarkus.profile=prod -jar target/quarkus-app/quarkus-run.jar
+```
+
+### Docker (Optionnel)
+
+```bash
+# Construction de l'image
+docker build -f src/main/docker/Dockerfile.jvm -t unionflow-client:latest .
+
+# Lancement du conteneur
+docker run -p 8080:8080 \
+ -e KEYCLOAK_CLIENT_SECRET="votre-secret" \
+ -e UNIONFLOW_BACKEND_URL="https://api.lions.dev/unionflow" \
+ unionflow-client:latest
+```
+
+## 🔒 Sécurité
+
+### Authentification et Autorisation
+
+- **Méthode**: OpenID Connect (OIDC) via Keycloak
+- **Tokens**: JWT (JSON Web Tokens)
+- **Rôles supportés**: SUPER_ADMIN, ADMIN_ORGANISATION, MEMBRE
+- **Permissions granulaires**: Basées sur les rôles et fonctionnalités
+
+### Headers de Sécurité (Production)
+
+L'application configure automatiquement les headers de sécurité suivants:
+
+- `X-Content-Type-Options: nosniff`
+- `X-Frame-Options: DENY`
+- `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload`
+- `Content-Security-Policy`: Configuration stricte avec support PrimeFaces
+- `X-XSS-Protection: 1; mode=block`
+- `Referrer-Policy: strict-origin-when-cross-origin`
+
+### Bonnes Pratiques
+
+1. **Secrets**: Ne JAMAIS committer de secrets dans Git
+2. **HTTPS**: Toujours utiliser HTTPS en production
+3. **Cookies**: HttpOnly et SameSite=Strict activés
+4. **Sessions**: Timeout de 60 minutes par défaut
+5. **TLS**: Vérification TLS obligatoire même en dev
+
+Pour plus de détails, consultez [SECURITY.md](SECURITY.md).
+
+## 🧪 Tests
+
+### Lancement des Tests
+
+```bash
+# Tous les tests
+mvn test
+
+# Tests unitaires uniquement
+mvn test -Dtest="*Test"
+
+# Tests d'intégration uniquement
+mvn test -Dtest="*IT"
+
+# Tests avec couverture
+mvn test jacoco:report
+```
+
+### Structure des Tests
+
+```
+src/test/java/
+├── validation/ # Tests unitaires validateurs
+│ ├── MemberNumberValidatorTest.java
+│ └── PhoneNumberValidatorTest.java
+├── security/ # Tests services de sécurité
+│ ├── PermissionCheckerTest.java
+│ └── TokenRefreshServiceTest.java
+└── service/ # Tests d'intégration REST clients
+ ├── MembreServiceIT.java
+ └── AuthenticationServiceIT.java
+```
+
+### Résultats des Tests
+
+**Status** : ✅ **15/15 tests passent** (100%)
+
+- ✅ `MemberNumberValidatorTest` : 15/15 tests
+- ✅ Tous les validateurs personnalisés testés
+- ✅ Aucune régression après migration
+
+### Couverture de Code
+
+Objectif: **80%** minimum
+
+- Validateurs: 100%
+- Services de sécurité: 90%
+- REST Clients: 70%
+- Backing Beans: 60%
+
+## 🚢 Déploiement
+
+### Déploiement sur Serveur Linux
+
+```bash
+# 1. Transférer l'artifact
+scp target/quarkus-app/quarkus-run.jar user@serveur:/opt/unionflow/
+
+# 2. Configurer le service systemd
+sudo nano /etc/systemd/system/unionflow-client.service
+
+# 3. Contenu du service
+[Unit]
+Description=UnionFlow Client Application
+After=network.target
+
+[Service]
+Type=simple
+User=unionflow
+WorkingDirectory=/opt/unionflow
+ExecStart=/usr/bin/java -jar /opt/unionflow/quarkus-run.jar
+Restart=on-failure
+Environment="KEYCLOAK_CLIENT_SECRET=xxx"
+Environment="UNIONFLOW_BACKEND_URL=https://api.lions.dev/unionflow"
+
+[Install]
+WantedBy=multi-user.target
+
+# 4. Activer et démarrer
+sudo systemctl enable unionflow-client
+sudo systemctl start unionflow-client
+sudo systemctl status unionflow-client
+```
+
+### Déploiement avec Nginx Reverse Proxy
+
+```nginx
+server {
+ listen 443 ssl http2;
+ server_name unionflow.lions.dev;
+
+ ssl_certificate /etc/letsencrypt/live/unionflow.lions.dev/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/unionflow.lions.dev/privkey.pem;
+
+ location / {
+ proxy_pass http://localhost:8080;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+}
+```
+
+## 📚 Documentation Supplémentaire
+
+- **Architecture Détaillée**: `/docs/ARCHITECTURE.md`
+- **Guide de Sécurité**: [SECURITY.md](SECURITY.md)
+- **Guide de Contribution**: `/docs/CONTRIBUTING.md`
+- **Changelog**: [CHANGELOG.md](CHANGELOG.md)
+- **API Documentation**: Disponible sur le backend
+
+## 🐛 Problèmes Connus et Solutions
+
+### ViewExpiredException
+
+Si vous rencontrez des `ViewExpiredException`, vérifiez:
+- Le timeout de session (`quarkus.http.session-timeout`)
+- Le nombre de vues en session (`quarkus.myfaces.number-of-views-in-session`)
+
+### Erreur OIDC "Invalid Token"
+
+Solution:
+1. Vérifier que le client Keycloak est correctement configuré
+2. Vérifier la variable `KEYCLOAK_CLIENT_SECRET`
+3. Vérifier l'URL du serveur Keycloak
+
+### Erreur "BeanManager.getELResolver"
+
+Déjà corrigé via `QuarkusArcELResolver`. Si le problème persiste:
+1. Vérifier la configuration Arc CDI dans `application.properties`
+2. Vérifier que `faces-config.xml` contient `QuarkusApplicationFactory`
+
+## 📞 Support
+
+### Équipe de Développement
+
+- **Email**: support@lions.dev
+- **Slack**: #unionflow-support
+- **Issue Tracker**: https://git.lions.dev/lionsdev/unionflow-client/issues
+
+### Resources
+
+- **Documentation Quarkus**: https://quarkus.io/guides/
+- **Documentation PrimeFaces**: https://www.primefaces.org/showcase/
+- **Documentation Keycloak**: https://www.keycloak.org/documentation
+
+## 📄 Licence
+
+Propriétaire - © 2025 Lions Club International - Tous droits réservés
+
+---
+
+## 📊 État du Projet
+
+- ✅ **Version** : 3.0.0
+- ✅ **Status** : Production-Ready
+- ✅ **Tests** : 15/15 (100%)
+- ✅ **Beans** : 48 beans migrés
+- ✅ **Services** : 5 services transverses
+- ✅ **Documentation** : Complète et à jour
+
+---
+
+**Version**: 3.0.0
+**Dernière mise à jour**: 4 Janvier 2026
+**Auteur**: Équipe UnionFlow
+**License**: Proprietary - Lions Club Côte d'Ivoire
diff --git a/SECURITY.md b/SECURITY.md
index 145d778..60f9f21 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,348 +1,348 @@
-# Politique de Sécurité - UnionFlow Client
-
-
-
-
-Ce document décrit les pratiques de sécurité, les vulnérabilités connues et les procédures de signalement pour l'application UnionFlow Client.
-
-## 📋 Table des Matières
-
-- [Versions Supportées](#versions-supportées)
-- [Architecture de Sécurité](#architecture-de-sécurité)
-- [Authentification et Autorisation](#authentification-et-autorisation)
-- [Protection des Données](#protection-des-données)
-- [Headers de Sécurité](#headers-de-sécurité)
-- [Gestion des Secrets](#gestion-des-secrets)
-- [Vulnérabilités Connues](#vulnérabilités-connues)
-- [Signalement de Vulnérabilités](#signalement-de-vulnérabilités)
-- [Conformité](#conformité)
-
-## 🔄 Versions Supportées
-
-| Version | Supportée | Fin de Support |
-|---------|-----------|----------------|
-| 1.0.x | ✅ Oui | 31 Déc 2025 |
-| < 1.0 | ❌ Non | N/A |
-
-## 🏗️ Architecture de Sécurité
-
-### Modèle de Sécurité
-
-L'application implémente une architecture de sécurité en profondeur (Defense in Depth):
-
-```
-┌─────────────────────────────────────────────┐
-│ 1. TLS/HTTPS (Transport) │
-│ - Certificats SSL/TLS valides │
-│ - HSTS activé (max-age=1 an) │
-└─────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────┐
-│ 2. Headers de Sécurité HTTP │
-│ - CSP, X-Frame-Options, etc. │
-│ - Protection XSS, Clickjacking │
-└─────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────┐
-│ 3. Authentification OIDC (Keycloak) │
-│ - OAuth 2.0 / OpenID Connect │
-│ - JWT Tokens signés │
-└─────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────┐
-│ 4. Autorisation (RBAC) │
-│ - Vérification rôles multiples │
-│ - Permissions granulaires │
-└─────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────┐
-│ 5. Validation des Entrées │
-│ - Hibernate Validator │
-│ - Validateurs personnalisés │
-└─────────────────────────────────────────────┘
- ↓
-┌─────────────────────────────────────────────┐
-│ 6. Logging Sécurisé │
-│ - Pas de données sensibles │
-│ - Audit trails │
-└─────────────────────────────────────────────┘
-```
-
-## 🔐 Authentification et Autorisation
-
-### Authentification
-
-- **Méthode**: OpenID Connect (OIDC) via Keycloak
-- **Protocole**: OAuth 2.0 Authorization Code Flow
-- **Tokens**: JWT (JSON Web Tokens) signés avec RS256
-
-### Configuration Keycloak Requise
-
-```properties
-# Serveur d'authentification
-quarkus.oidc.auth-server-url=https://security.lions.dev/realms/unionflow
-
-# Client configuration
-quarkus.oidc.client-id=unionflow-client
-quarkus.oidc.credentials.secret=${KEYCLOAK_CLIENT_SECRET}
-
-# Scopes
-quarkus.oidc.authentication.scopes=openid,profile,email,roles
-
-# TLS Verification
-quarkus.oidc.tls.verification=required # JAMAIS 'none' en production
-```
-
-### Rôles et Permissions
-
-#### Hiérarchie des Rôles
-
-1. **SUPER_ADMIN** - Accès complet système
-2. **ADMIN_ORGANISATION** - Administration organisation
-3. **ADMIN** - Administration locale
-4. **GESTIONNAIRE_*** - Gestion fonctionnelle
-5. **TRESORIER** - Gestion financière
-6. **MEMBRE** - Accès membre standard
-
-#### Permissions Granulaires
-
-- `canManageMembers()` - Gestion des membres
-- `canManageFinances()` - Gestion financière
-- `canManageEvents()` - Gestion des événements
-- `canViewReports()` - Consultation des rapports
-- `canAccessSuperAdmin()` - Accès super-admin
-
-### Gestion des Sessions
-
-- **Timeout**: 60 minutes par défaut
-- **Cookie Flags**:
- - `HttpOnly`: ✅ Activé (prévention XSS)
- - `Secure`: ✅ Activé (HTTPS uniquement)
- - `SameSite`: `Strict` (prévention CSRF)
-
-### Gestion des Tokens JWT
-
-- **Access Token**: Durée de vie courte (15-30 min)
-- **Refresh Token**: Durée de vie longue (7 jours)
-- **Stockage**: Cookies HttpOnly (JAMAIS localStorage)
-- **Rafraîchissement**: Automatique 5 min avant expiration
-- **Cache**: Limite de 10,000 tokens (protection DoS)
-
-## 🛡️ Protection des Données
-
-### Données Sensibles
-
-#### Classification
-
-| Type | Niveau | Stockage | Transmission |
-|------|--------|----------|--------------|
-| Mots de passe | Critique | Hachés (bcrypt) | HTTPS uniquement |
-| Tokens JWT | Critique | Cookies HttpOnly | HTTPS uniquement |
-| Email | Confidentiel | Chiffré DB | HTTPS uniquement |
-| Téléphone | Confidentiel | Chiffré DB | HTTPS uniquement |
-| Nom/Prénom | Public | Clair | HTTPS uniquement |
-
-#### Protection en Transit
-
-- **Protocole**: TLS 1.2+ uniquement (pas de TLS 1.0/1.1)
-- **Cipher Suites**: Modernes et sûres uniquement
-- **HSTS**: Activé avec `includeSubDomains` et `preload`
-
-#### Protection au Repos
-
-- **Base de données**: Chiffrement au niveau base (via backend)
-- **Fichiers**: Chiffrement du système de fichiers recommandé
-- **Logs**: Pas de données sensibles loggées
-
-### Conformité RGPD
-
-- **Minimisation des données**: Collecte uniquement des données nécessaires
-- **Droit à l'oubli**: API de suppression disponible
-- **Portabilité**: Export de données en JSON/Excel
-- **Audit**: Logs de toutes les opérations sensibles
-
-## 🔒 Headers de Sécurité
-
-### Configuration Production
-
-Tous les headers suivants sont automatiquement configurés en production:
-
-```properties
-# Prévention MIME Sniffing
-X-Content-Type-Options: nosniff
-
-# Protection Clickjacking
-X-Frame-Options: DENY
-
-# HSTS (HTTPS forcé)
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-
-# Content Security Policy
-Content-Security-Policy: default-src 'self';
- script-src 'self' 'unsafe-inline' 'unsafe-eval';
- style-src 'self' 'unsafe-inline';
- img-src 'self' data:;
- font-src 'self' data:;
- connect-src 'self';
- frame-ancestors 'none'
-
-# Protection XSS (legacy)
-X-XSS-Protection: 1; mode=block
-
-# Politique de référents
-Referrer-Policy: strict-origin-when-cross-origin
-
-# Permissions Policy
-Permissions-Policy: geolocation=(), microphone=(), camera=()
-```
-
-### Content Security Policy (CSP)
-
-⚠️ **Note**: `unsafe-inline` et `unsafe-eval` sont nécessaires pour PrimeFaces/JSF qui génèrent des scripts inline. Une migration vers des nonces CSP est prévue dans une version future.
-
-## 🔑 Gestion des Secrets
-
-### Secrets à Protéger
-
-1. **KEYCLOAK_CLIENT_SECRET** - Secret client Keycloak
-2. **Clés de chiffrement** - Si applicable
-3. **Tokens API** - Pour services externes
-
-### Bonnes Pratiques
-
-#### ✅ À FAIRE
-
-- Utiliser des **variables d'environnement** pour tous les secrets
-- Utiliser un **gestionnaire de secrets** (HashiCorp Vault, AWS Secrets Manager)
-- **Régénérer** les secrets régulièrement (rotation)
-- Utiliser des **secrets différents** pour dev/staging/prod
-- **Auditer** l'accès aux secrets
-
-#### ❌ À NE JAMAIS FAIRE
-
-- ❌ Committer des secrets dans Git
-- ❌ Hardcoder des secrets dans le code
-- ❌ Partager des secrets par email/Slack
-- ❌ Utiliser des secrets par défaut
-- ❌ Logger des secrets
-
-### Vérification dans Git
-
-```bash
-# Vérifier qu'aucun secret n'est présent
-git secrets --scan
-
-# Nettoyer l'historique si nécessaire
-git filter-branch --force --index-filter \
- "git rm --cached --ignore-unmatch src/main/resources/application-dev.properties" \
- --prune-empty --tag-name-filter cat -- --all
-```
-
-## 🚨 Vulnérabilités Connues
-
-### Critiques Corrigées (v1.0.0)
-
-| ID | Vulnérabilité | Statut | Correction |
-|----|---------------|--------|------------|
-| SEC-001 | Secret Keycloak en dur | ✅ Corrigé | Supprimé du code |
-| SEC-002 | TLS verification=none en dev | ✅ Corrigé | Activé `required` |
-| SEC-003 | Exposition erreurs backend | ✅ Corrigé | Messages génériques |
-| SEC-004 | Logging données sensibles | ✅ Corrigé | Logs anonymisés |
-| SEC-005 | Cache tokens illimité | ✅ Corrigé | Limite 10,000 |
-| SEC-006 | Cookie Secure=false | ✅ Corrigé | Activé en prod |
-
-### Risques Résiduels
-
-| Risque | Niveau | Mitigation |
-|--------|--------|------------|
-| Dépendance PrimeFaces inline scripts | Moyen | CSP avec unsafe-inline |
-| Session fixation | Faible | Régénération session à login |
-
-## 📢 Signalement de Vulnérabilités
-
-### Processus de Signalement
-
-Si vous découvrez une vulnérabilité de sécurité:
-
-1. **NE PAS** créer d'issue publique
-2. **Envoyer un email** à: security@lions.dev
-3. **Inclure**:
- - Description détaillée de la vulnérabilité
- - Étapes pour reproduire
- - Impact potentiel
- - Version affectée
- - Preuve de concept (si applicable)
-
-### Délais de Réponse
-
-- **Accusé de réception**: 24 heures
-- **Évaluation initiale**: 72 heures
-- **Correctif critique**: 7 jours
-- **Correctif haute priorité**: 30 jours
-
-### Récompenses
-
-Nous proposons un programme de Bug Bounty pour les vulnérabilités critiques validées. Contactez security@lions.dev pour plus de détails.
-
-## 📊 Conformité
-
-### Standards de Sécurité
-
-- **OWASP Top 10 2021**: ✅ Conforme
-- **OWASP ASVS Level 2**: ✅ Conforme
-- **CWE Top 25**: ✅ Vérifié
-
-### Audits de Sécurité
-
-| Date | Type | Résultat | Rapport |
-|------|------|----------|---------|
-| 2025-12-17 | Interne | Pass | `docs/audit-2025-12.pdf` |
-
-### Tests de Sécurité
-
-#### Automatisés (CI/CD)
-
-- **Dependency Check**: OWASP Dependency-Check Maven plugin
-- **SAST**: Spotbugs Security Plugin
-- **Secrets Scanning**: GitGuardian
-
-#### Manuels (Périodiques)
-
-- **Pentesting**: Annuel
-- **Code Review**: À chaque release majeure
-- **Configuration Review**: Trimestriel
-
-## 🛠️ Outils de Sécurité Recommandés
-
-### Développement
-
-```bash
-# Analyse de dépendances
-mvn org.owasp:dependency-check-maven:check
-
-# Analyse statique
-mvn spotbugs:check
-
-# Secrets scanning
-git secrets --scan --recursive
-```
-
-### Production
-
-- **WAF**: Cloudflare, AWS WAF, ou ModSecurity
-- **IDS/IPS**: Suricata, Snort
-- **Log Monitoring**: ELK Stack, Splunk
-- **Vulnerability Scanner**: Nessus, OpenVAS
-
-## 📚 Références
-
-- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
-- [OWASP ASVS](https://owasp.org/www-project-application-security-verification-standard/)
-- [Keycloak Security](https://www.keycloak.org/docs/latest/securing_apps/)
-- [Quarkus Security](https://quarkus.io/guides/security)
-
----
-
-**Dernière mise à jour**: 17 Décembre 2025
-**Contact Sécurité**: security@lions.dev
-**PGP Key**: Disponible sur demande
+# Politique de Sécurité - UnionFlow Client
+
+
+
+
+Ce document décrit les pratiques de sécurité, les vulnérabilités connues et les procédures de signalement pour l'application UnionFlow Client.
+
+## 📋 Table des Matières
+
+- [Versions Supportées](#versions-supportées)
+- [Architecture de Sécurité](#architecture-de-sécurité)
+- [Authentification et Autorisation](#authentification-et-autorisation)
+- [Protection des Données](#protection-des-données)
+- [Headers de Sécurité](#headers-de-sécurité)
+- [Gestion des Secrets](#gestion-des-secrets)
+- [Vulnérabilités Connues](#vulnérabilités-connues)
+- [Signalement de Vulnérabilités](#signalement-de-vulnérabilités)
+- [Conformité](#conformité)
+
+## 🔄 Versions Supportées
+
+| Version | Supportée | Fin de Support |
+|---------|-----------|----------------|
+| 1.0.x | ✅ Oui | 31 Déc 2025 |
+| < 1.0 | ❌ Non | N/A |
+
+## 🏗️ Architecture de Sécurité
+
+### Modèle de Sécurité
+
+L'application implémente une architecture de sécurité en profondeur (Defense in Depth):
+
+```
+┌─────────────────────────────────────────────┐
+│ 1. TLS/HTTPS (Transport) │
+│ - Certificats SSL/TLS valides │
+│ - HSTS activé (max-age=1 an) │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ 2. Headers de Sécurité HTTP │
+│ - CSP, X-Frame-Options, etc. │
+│ - Protection XSS, Clickjacking │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ 3. Authentification OIDC (Keycloak) │
+│ - OAuth 2.0 / OpenID Connect │
+│ - JWT Tokens signés │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ 4. Autorisation (RBAC) │
+│ - Vérification rôles multiples │
+│ - Permissions granulaires │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ 5. Validation des Entrées │
+│ - Hibernate Validator │
+│ - Validateurs personnalisés │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ 6. Logging Sécurisé │
+│ - Pas de données sensibles │
+│ - Audit trails │
+└─────────────────────────────────────────────┘
+```
+
+## 🔐 Authentification et Autorisation
+
+### Authentification
+
+- **Méthode**: OpenID Connect (OIDC) via Keycloak
+- **Protocole**: OAuth 2.0 Authorization Code Flow
+- **Tokens**: JWT (JSON Web Tokens) signés avec RS256
+
+### Configuration Keycloak Requise
+
+```properties
+# Serveur d'authentification
+quarkus.oidc.auth-server-url=https://security.lions.dev/realms/unionflow
+
+# Client configuration
+quarkus.oidc.client-id=unionflow-client
+quarkus.oidc.credentials.secret=${KEYCLOAK_CLIENT_SECRET}
+
+# Scopes
+quarkus.oidc.authentication.scopes=openid,profile,email,roles
+
+# TLS Verification
+quarkus.oidc.tls.verification=required # JAMAIS 'none' en production
+```
+
+### Rôles et Permissions
+
+#### Hiérarchie des Rôles
+
+1. **SUPER_ADMIN** - Accès complet système
+2. **ADMIN_ORGANISATION** - Administration organisation
+3. **ADMIN** - Administration locale
+4. **GESTIONNAIRE_*** - Gestion fonctionnelle
+5. **TRESORIER** - Gestion financière
+6. **MEMBRE** - Accès membre standard
+
+#### Permissions Granulaires
+
+- `canManageMembers()` - Gestion des membres
+- `canManageFinances()` - Gestion financière
+- `canManageEvents()` - Gestion des événements
+- `canViewReports()` - Consultation des rapports
+- `canAccessSuperAdmin()` - Accès super-admin
+
+### Gestion des Sessions
+
+- **Timeout**: 60 minutes par défaut
+- **Cookie Flags**:
+ - `HttpOnly`: ✅ Activé (prévention XSS)
+ - `Secure`: ✅ Activé (HTTPS uniquement)
+ - `SameSite`: `Strict` (prévention CSRF)
+
+### Gestion des Tokens JWT
+
+- **Access Token**: Durée de vie courte (15-30 min)
+- **Refresh Token**: Durée de vie longue (7 jours)
+- **Stockage**: Cookies HttpOnly (JAMAIS localStorage)
+- **Rafraîchissement**: Automatique 5 min avant expiration
+- **Cache**: Limite de 10,000 tokens (protection DoS)
+
+## 🛡️ Protection des Données
+
+### Données Sensibles
+
+#### Classification
+
+| Type | Niveau | Stockage | Transmission |
+|------|--------|----------|--------------|
+| Mots de passe | Critique | Hachés (bcrypt) | HTTPS uniquement |
+| Tokens JWT | Critique | Cookies HttpOnly | HTTPS uniquement |
+| Email | Confidentiel | Chiffré DB | HTTPS uniquement |
+| Téléphone | Confidentiel | Chiffré DB | HTTPS uniquement |
+| Nom/Prénom | Public | Clair | HTTPS uniquement |
+
+#### Protection en Transit
+
+- **Protocole**: TLS 1.2+ uniquement (pas de TLS 1.0/1.1)
+- **Cipher Suites**: Modernes et sûres uniquement
+- **HSTS**: Activé avec `includeSubDomains` et `preload`
+
+#### Protection au Repos
+
+- **Base de données**: Chiffrement au niveau base (via backend)
+- **Fichiers**: Chiffrement du système de fichiers recommandé
+- **Logs**: Pas de données sensibles loggées
+
+### Conformité RGPD
+
+- **Minimisation des données**: Collecte uniquement des données nécessaires
+- **Droit à l'oubli**: API de suppression disponible
+- **Portabilité**: Export de données en JSON/Excel
+- **Audit**: Logs de toutes les opérations sensibles
+
+## 🔒 Headers de Sécurité
+
+### Configuration Production
+
+Tous les headers suivants sont automatiquement configurés en production:
+
+```properties
+# Prévention MIME Sniffing
+X-Content-Type-Options: nosniff
+
+# Protection Clickjacking
+X-Frame-Options: DENY
+
+# HSTS (HTTPS forcé)
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+
+# Content Security Policy
+Content-Security-Policy: default-src 'self';
+ script-src 'self' 'unsafe-inline' 'unsafe-eval';
+ style-src 'self' 'unsafe-inline';
+ img-src 'self' data:;
+ font-src 'self' data:;
+ connect-src 'self';
+ frame-ancestors 'none'
+
+# Protection XSS (legacy)
+X-XSS-Protection: 1; mode=block
+
+# Politique de référents
+Referrer-Policy: strict-origin-when-cross-origin
+
+# Permissions Policy
+Permissions-Policy: geolocation=(), microphone=(), camera=()
+```
+
+### Content Security Policy (CSP)
+
+⚠️ **Note**: `unsafe-inline` et `unsafe-eval` sont nécessaires pour PrimeFaces/JSF qui génèrent des scripts inline. Une migration vers des nonces CSP est prévue dans une version future.
+
+## 🔑 Gestion des Secrets
+
+### Secrets à Protéger
+
+1. **KEYCLOAK_CLIENT_SECRET** - Secret client Keycloak
+2. **Clés de chiffrement** - Si applicable
+3. **Tokens API** - Pour services externes
+
+### Bonnes Pratiques
+
+#### ✅ À FAIRE
+
+- Utiliser des **variables d'environnement** pour tous les secrets
+- Utiliser un **gestionnaire de secrets** (HashiCorp Vault, AWS Secrets Manager)
+- **Régénérer** les secrets régulièrement (rotation)
+- Utiliser des **secrets différents** pour dev/staging/prod
+- **Auditer** l'accès aux secrets
+
+#### ❌ À NE JAMAIS FAIRE
+
+- ❌ Committer des secrets dans Git
+- ❌ Hardcoder des secrets dans le code
+- ❌ Partager des secrets par email/Slack
+- ❌ Utiliser des secrets par défaut
+- ❌ Logger des secrets
+
+### Vérification dans Git
+
+```bash
+# Vérifier qu'aucun secret n'est présent
+git secrets --scan
+
+# Nettoyer l'historique si nécessaire
+git filter-branch --force --index-filter \
+ "git rm --cached --ignore-unmatch src/main/resources/application-dev.properties" \
+ --prune-empty --tag-name-filter cat -- --all
+```
+
+## 🚨 Vulnérabilités Connues
+
+### Critiques Corrigées (v1.0.0)
+
+| ID | Vulnérabilité | Statut | Correction |
+|----|---------------|--------|------------|
+| SEC-001 | Secret Keycloak en dur | ✅ Corrigé | Supprimé du code |
+| SEC-002 | TLS verification=none en dev | ✅ Corrigé | Activé `required` |
+| SEC-003 | Exposition erreurs backend | ✅ Corrigé | Messages génériques |
+| SEC-004 | Logging données sensibles | ✅ Corrigé | Logs anonymisés |
+| SEC-005 | Cache tokens illimité | ✅ Corrigé | Limite 10,000 |
+| SEC-006 | Cookie Secure=false | ✅ Corrigé | Activé en prod |
+
+### Risques Résiduels
+
+| Risque | Niveau | Mitigation |
+|--------|--------|------------|
+| Dépendance PrimeFaces inline scripts | Moyen | CSP avec unsafe-inline |
+| Session fixation | Faible | Régénération session à login |
+
+## 📢 Signalement de Vulnérabilités
+
+### Processus de Signalement
+
+Si vous découvrez une vulnérabilité de sécurité:
+
+1. **NE PAS** créer d'issue publique
+2. **Envoyer un email** à: security@lions.dev
+3. **Inclure**:
+ - Description détaillée de la vulnérabilité
+ - Étapes pour reproduire
+ - Impact potentiel
+ - Version affectée
+ - Preuve de concept (si applicable)
+
+### Délais de Réponse
+
+- **Accusé de réception**: 24 heures
+- **Évaluation initiale**: 72 heures
+- **Correctif critique**: 7 jours
+- **Correctif haute priorité**: 30 jours
+
+### Récompenses
+
+Nous proposons un programme de Bug Bounty pour les vulnérabilités critiques validées. Contactez security@lions.dev pour plus de détails.
+
+## 📊 Conformité
+
+### Standards de Sécurité
+
+- **OWASP Top 10 2021**: ✅ Conforme
+- **OWASP ASVS Level 2**: ✅ Conforme
+- **CWE Top 25**: ✅ Vérifié
+
+### Audits de Sécurité
+
+| Date | Type | Résultat | Rapport |
+|------|------|----------|---------|
+| 2025-12-17 | Interne | Pass | `docs/audit-2025-12.pdf` |
+
+### Tests de Sécurité
+
+#### Automatisés (CI/CD)
+
+- **Dependency Check**: OWASP Dependency-Check Maven plugin
+- **SAST**: Spotbugs Security Plugin
+- **Secrets Scanning**: GitGuardian
+
+#### Manuels (Périodiques)
+
+- **Pentesting**: Annuel
+- **Code Review**: À chaque release majeure
+- **Configuration Review**: Trimestriel
+
+## 🛠️ Outils de Sécurité Recommandés
+
+### Développement
+
+```bash
+# Analyse de dépendances
+mvn org.owasp:dependency-check-maven:check
+
+# Analyse statique
+mvn spotbugs:check
+
+# Secrets scanning
+git secrets --scan --recursive
+```
+
+### Production
+
+- **WAF**: Cloudflare, AWS WAF, ou ModSecurity
+- **IDS/IPS**: Suricata, Snort
+- **Log Monitoring**: ELK Stack, Splunk
+- **Vulnerability Scanner**: Nessus, OpenVAS
+
+## 📚 Références
+
+- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
+- [OWASP ASVS](https://owasp.org/www-project-application-security-verification-standard/)
+- [Keycloak Security](https://www.keycloak.org/docs/latest/securing_apps/)
+- [Quarkus Security](https://quarkus.io/guides/security)
+
+---
+
+**Dernière mise à jour**: 17 Décembre 2025
+**Contact Sécurité**: security@lions.dev
+**PGP Key**: Disponible sur demande
diff --git a/docker/Dockerfile.prod b/docker/Dockerfile.prod
index 249d1b7..39a1446 100644
--- a/docker/Dockerfile.prod
+++ b/docker/Dockerfile.prod
@@ -1,92 +1,92 @@
-####
-# Dockerfile de production pour UnionFlow Client (Frontend)
-# Multi-stage build optimisé avec sécurité renforcée
-####
-
-## Stage 1 : Build avec Maven
-FROM maven:3.9.6-eclipse-temurin-17 AS builder
-
-WORKDIR /app
-
-# Copier les fichiers de configuration Maven
-COPY pom.xml .
-COPY ../unionflow-server-api/pom.xml ../unionflow-server-api/
-
-# Télécharger les dépendances (cache Docker)
-RUN mvn dependency:go-offline -B -pl unionflow-client-quarkus-primefaces-freya -am
-
-# Copier le code source
-COPY src ./src
-
-# Build de l'application avec profil production
-RUN mvn clean package -DskipTests -B -Dquarkus.profile=prod -pl unionflow-client-quarkus-primefaces-freya
-
-## Stage 2 : Image de production optimisée et sécurisée
-FROM registry.access.redhat.com/ubi8/openjdk-17:1.18
-
-ENV LANGUAGE='fr_FR:fr'
-
-# Variables d'environnement de production
-ENV QUARKUS_PROFILE=prod
-ENV QUARKUS_HTTP_PORT=8086
-ENV QUARKUS_HTTP_HOST=0.0.0.0
-
-# Configuration Keycloak OIDC (production)
-ENV QUARKUS_OIDC_AUTH_SERVER_URL=https://security.lions.dev/realms/unionflow
-ENV QUARKUS_OIDC_CLIENT_ID=unionflow-client
-ENV QUARKUS_OIDC_ENABLED=true
-ENV QUARKUS_OIDC_TLS_VERIFICATION=required
-# KEYCLOAK_CLIENT_SECRET MUST be injected via Kubernetes Secret at runtime
-ENV KEYCLOAK_CLIENT_SECRET=
-
-# Configuration API Backend
-ENV UNIONFLOW_BACKEND_URL=https://api.lions.dev/unionflow
-
-# Configuration CORS
-ENV QUARKUS_HTTP_CORS_ORIGINS=https://unionflow.lions.dev,https://security.lions.dev
-ENV QUARKUS_HTTP_CORS_ALLOW_CREDENTIALS=true
-
-# Configuration Session
-ENV SESSION_TIMEOUT=1800
-ENV REMEMBER_ME_DURATION=604800
-
-# Installer curl pour les health checks
-USER root
-RUN microdnf install -y curl && \
- microdnf clean all && \
- rm -rf /var/cache/yum
-
-# Créer les répertoires et permissions pour utilisateur non-root
-RUN mkdir -p /deployments /app/logs && \
- chown -R 185:185 /deployments /app/logs
-
-# Passer à l'utilisateur non-root pour la sécurité
-USER 185
-
-# Copier l'application depuis le builder (format fast-jar Quarkus)
-COPY --from=builder --chown=185 /app/target/quarkus-app/ /deployments/
-
-# Exposer le port
-EXPOSE 8086
-
-# Variables JVM optimisées pour production avec sécurité
-ENV JAVA_OPTS="-Xmx768m -Xms256m \
- -XX:+UseG1GC \
- -XX:MaxGCPauseMillis=200 \
- -XX:+UseStringDeduplication \
- -XX:+ParallelRefProcEnabled \
- -XX:+HeapDumpOnOutOfMemoryError \
- -XX:HeapDumpPath=/app/logs/heapdump.hprof \
- -Djava.security.egd=file:/dev/./urandom \
- -Djava.awt.headless=true \
- -Dfile.encoding=UTF-8 \
- -Djava.util.logging.manager=org.jboss.logmanager.LogManager \
- -Dquarkus.profile=${QUARKUS_PROFILE}"
-
-# Health check avec endpoints Quarkus
-HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
- CMD curl -f http://localhost:8086/q/health/ready || exit 1
-
-# Point d'entrée avec profil production (format fast-jar)
-ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /deployments/quarkus-run.jar"]
-
+####
+# Dockerfile de production pour UnionFlow Client (Frontend)
+# Multi-stage build optimisé avec sécurité renforcée
+####
+
+## Stage 1 : Build avec Maven
+FROM maven:3.9.6-eclipse-temurin-17 AS builder
+
+WORKDIR /app
+
+# Copier les fichiers de configuration Maven
+COPY pom.xml .
+COPY ../unionflow-server-api/pom.xml ../unionflow-server-api/
+
+# Télécharger les dépendances (cache Docker)
+RUN mvn dependency:go-offline -B -pl unionflow-client-quarkus-primefaces-freya -am
+
+# Copier le code source
+COPY src ./src
+
+# Build de l'application avec profil production
+RUN mvn clean package -DskipTests -B -Dquarkus.profile=prod -pl unionflow-client-quarkus-primefaces-freya
+
+## Stage 2 : Image de production optimisée et sécurisée
+FROM registry.access.redhat.com/ubi8/openjdk-17:1.18
+
+ENV LANGUAGE='fr_FR:fr'
+
+# Variables d'environnement de production
+ENV QUARKUS_PROFILE=prod
+ENV QUARKUS_HTTP_PORT=8086
+ENV QUARKUS_HTTP_HOST=0.0.0.0
+
+# Configuration Keycloak OIDC (production)
+ENV QUARKUS_OIDC_AUTH_SERVER_URL=https://security.lions.dev/realms/unionflow
+ENV QUARKUS_OIDC_CLIENT_ID=unionflow-client
+ENV QUARKUS_OIDC_ENABLED=true
+ENV QUARKUS_OIDC_TLS_VERIFICATION=required
+# KEYCLOAK_CLIENT_SECRET MUST be injected via Kubernetes Secret at runtime
+ENV KEYCLOAK_CLIENT_SECRET=
+
+# Configuration API Backend
+ENV UNIONFLOW_BACKEND_URL=https://api.lions.dev/unionflow
+
+# Configuration CORS
+ENV QUARKUS_HTTP_CORS_ORIGINS=https://unionflow.lions.dev,https://security.lions.dev
+ENV QUARKUS_HTTP_CORS_ALLOW_CREDENTIALS=true
+
+# Configuration Session
+ENV SESSION_TIMEOUT=1800
+ENV REMEMBER_ME_DURATION=604800
+
+# Installer curl pour les health checks
+USER root
+RUN microdnf install -y curl && \
+ microdnf clean all && \
+ rm -rf /var/cache/yum
+
+# Créer les répertoires et permissions pour utilisateur non-root
+RUN mkdir -p /deployments /app/logs && \
+ chown -R 185:185 /deployments /app/logs
+
+# Passer à l'utilisateur non-root pour la sécurité
+USER 185
+
+# Copier l'application depuis le builder (format fast-jar Quarkus)
+COPY --from=builder --chown=185 /app/target/quarkus-app/ /deployments/
+
+# Exposer le port
+EXPOSE 8086
+
+# Variables JVM optimisées pour production avec sécurité
+ENV JAVA_OPTS="-Xmx768m -Xms256m \
+ -XX:+UseG1GC \
+ -XX:MaxGCPauseMillis=200 \
+ -XX:+UseStringDeduplication \
+ -XX:+ParallelRefProcEnabled \
+ -XX:+HeapDumpOnOutOfMemoryError \
+ -XX:HeapDumpPath=/app/logs/heapdump.hprof \
+ -Djava.security.egd=file:/dev/./urandom \
+ -Djava.awt.headless=true \
+ -Dfile.encoding=UTF-8 \
+ -Djava.util.logging.manager=org.jboss.logmanager.LogManager \
+ -Dquarkus.profile=${QUARKUS_PROFILE}"
+
+# Health check avec endpoints Quarkus
+HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
+ CMD curl -f http://localhost:8086/q/health/ready || exit 1
+
+# Point d'entrée avec profil production (format fast-jar)
+ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /deployments/quarkus-run.jar"]
+
diff --git a/pom.xml b/pom.xml
index d876fbc..c28cac3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,14 +4,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
-
- dev.lions.unionflow
- unionflow-parent
- 1.0.5
- ../unionflow-server-api/parent-pom.xml
-
-
+ dev.lions.unionflow
unionflow-client-quarkus-primefaces-freya
+ 1.0.7
jar
UnionFlow Client (Quarkus + PrimeFaces Freya)
@@ -22,13 +17,17 @@
17
UTF-8
UTF-8
-
- 3.15.1
+
+ 3.27.3
io.quarkus.platform
quarkus-bom
3.13.3
14.0.5
4.4.1
+ 1.18.38
+
+ 1.21.4
+ 3.4.2
@@ -40,6 +39,20 @@
pom
import
+
+ org.testcontainers
+ testcontainers-bom
+ ${testcontainers.version}
+ pom
+ import
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
@@ -129,7 +142,7 @@
dev.lions.unionflow
unionflow-server-api
- 1.0.5
+ 1.0.6
diff --git a/scripts/owasp-dependency-check.bat b/scripts/owasp-dependency-check.bat
index 8b10146..3dceb47 100644
--- a/scripts/owasp-dependency-check.bat
+++ b/scripts/owasp-dependency-check.bat
@@ -1,33 +1,33 @@
-@echo off
-REM Script pour exécuter OWASP Dependency Check (Windows)
-REM Usage: scripts\owasp-dependency-check.bat
-
-echo 🔍 Exécution de l'audit de sécurité OWASP Dependency Check...
-
-REM Vérifier si OWASP Dependency Check est installé
-where dependency-check.bat >nul 2>&1
-if %ERRORLEVEL% NEQ 0 (
- echo ❌ OWASP Dependency Check n'est pas installé.
- echo 📥 Installation recommandée:
- echo - Télécharger depuis: https://owasp.org/www-project-dependency-check/
- echo - Ou utiliser Docker: docker run --rm -v %CD%:/src owasp/dependency-check --scan /src
- exit /b 1
-)
-
-REM Créer le répertoire de sortie
-if not exist "target\security-reports" mkdir target\security-reports
-
-REM Exécuter l'audit
-echo ⏳ Analyse des dépendances en cours...
-dependency-check.bat ^
- --project "UnionFlow Client" ^
- --scan unionflow-client-quarkus-primefaces-freya ^
- --out target\security-reports ^
- --format HTML ^
- --format JSON ^
- --format XML ^
- --enableExperimental ^
- --failOnCVSS 7
-
-echo ✅ Audit terminé. Rapport disponible dans: target\security-reports\
-
+@echo off
+REM Script pour exécuter OWASP Dependency Check (Windows)
+REM Usage: scripts\owasp-dependency-check.bat
+
+echo 🔍 Exécution de l'audit de sécurité OWASP Dependency Check...
+
+REM Vérifier si OWASP Dependency Check est installé
+where dependency-check.bat >nul 2>&1
+if %ERRORLEVEL% NEQ 0 (
+ echo ❌ OWASP Dependency Check n'est pas installé.
+ echo 📥 Installation recommandée:
+ echo - Télécharger depuis: https://owasp.org/www-project-dependency-check/
+ echo - Ou utiliser Docker: docker run --rm -v %CD%:/src owasp/dependency-check --scan /src
+ exit /b 1
+)
+
+REM Créer le répertoire de sortie
+if not exist "target\security-reports" mkdir target\security-reports
+
+REM Exécuter l'audit
+echo ⏳ Analyse des dépendances en cours...
+dependency-check.bat ^
+ --project "UnionFlow Client" ^
+ --scan unionflow-client-quarkus-primefaces-freya ^
+ --out target\security-reports ^
+ --format HTML ^
+ --format JSON ^
+ --format XML ^
+ --enableExperimental ^
+ --failOnCVSS 7
+
+echo ✅ Audit terminé. Rapport disponible dans: target\security-reports\
+
diff --git a/setup-keycloak.bat b/setup-keycloak.bat
index 41f2858..4ad6f59 100644
--- a/setup-keycloak.bat
+++ b/setup-keycloak.bat
@@ -1,277 +1,277 @@
-@echo off
-REM Script d'automatisation de la configuration Keycloak pour UnionFlow
-REM Usage: setup-keycloak.bat
-
-echo.
-echo ========================================================
-echo 🔧 Configuration automatique de Keycloak pour UnionFlow
-echo ========================================================
-echo.
-
-REM Configuration
-set KEYCLOAK_URL=http://localhost:8180
-set ADMIN_USER=admin
-set ADMIN_PASS=admin
-set REALM_NAME=unionflow
-set CLIENT_ID=unionflow-client
-
-echo 📋 Paramètres:
-echo - Keycloak URL: %KEYCLOAK_URL%
-echo - Admin User: %ADMIN_USER%
-echo - Realm: %REALM_NAME%
-echo - Client ID: %CLIENT_ID%
-echo.
-
-REM Vérifier que Keycloak est accessible
-echo 🔍 Vérification de Keycloak...
-curl -s %KEYCLOAK_URL% >nul 2>&1
-if errorlevel 1 (
- echo ❌ ERREUR: Keycloak n'est pas accessible sur %KEYCLOAK_URL%
- echo Assurez-vous que Keycloak est démarré.
- pause
- exit /b 1
-)
-echo ✅ Keycloak est accessible
-echo.
-
-REM Étape 1: Obtenir le token admin
-echo 📝 Étape 1/7: Obtention du token admin...
-curl -s -X POST "%KEYCLOAK_URL%/realms/master/protocol/openid-connect/token" ^
- -H "Content-Type: application/x-www-form-urlencoded" ^
- -d "username=%ADMIN_USER%" ^
- -d "password=%ADMIN_PASS%" ^
- -d "grant_type=password" ^
- -d "client_id=admin-cli" > token_response.json
-
-REM Extraire le token (utilise PowerShell pour parser le JSON)
-for /f "delims=" %%i in ('powershell -Command "(Get-Content token_response.json | ConvertFrom-Json).access_token"') do set ADMIN_TOKEN=%%i
-
-if "%ADMIN_TOKEN%"=="" (
- echo ❌ ERREUR: Impossible d'obtenir le token admin
- echo Vérifiez les identifiants: %ADMIN_USER% / %ADMIN_PASS%
- del token_response.json 2>nul
- pause
- exit /b 1
-)
-echo ✅ Token admin obtenu
-echo.
-
-REM Étape 2: Créer le realm
-echo 📝 Étape 2/7: Création du realm '%REALM_NAME%'...
-curl -s -X POST "%KEYCLOAK_URL%/admin/realms" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"realm\":\"%REALM_NAME%\",\"enabled\":true,\"displayName\":\"UnionFlow\",\"registrationAllowed\":false,\"loginWithEmailAllowed\":true,\"duplicateEmailsAllowed\":false,\"resetPasswordAllowed\":true,\"editUsernameAllowed\":false,\"bruteForceProtected\":true}" > nul 2>&1
-
-if errorlevel 1 (
- echo ⚠️ Le realm existe peut-être déjà, continuation...
-) else (
- echo ✅ Realm créé
-)
-echo.
-
-REM Étape 3: Créer les rôles
-echo 📝 Étape 3/7: Création des rôles...
-
-curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"name\":\"SUPER_ADMIN\",\"description\":\"Super administrateur système\"}" > nul 2>&1
-echo ✅ Rôle SUPER_ADMIN créé
-
-curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"name\":\"ADMIN_ORGANISATION\",\"description\":\"Administrateur d'entité\"}" > nul 2>&1
-echo ✅ Rôle ADMIN_ORGANISATION créé
-
-curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"name\":\"MEMBRE\",\"description\":\"Membre standard\"}" > nul 2>&1
-echo ✅ Rôle MEMBRE créé
-
-curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"name\":\"GESTIONNAIRE_MEMBRE\",\"description\":\"Gestionnaire des membres\"}" > nul 2>&1
-echo ✅ Rôle GESTIONNAIRE_MEMBRE créé
-
-curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"name\":\"GESTIONNAIRE_EVENEMENT\",\"description\":\"Gestionnaire des événements\"}" > nul 2>&1
-echo ✅ Rôle GESTIONNAIRE_EVENEMENT créé
-
-echo.
-
-REM Étape 4: Créer le client
-echo 📝 Étape 4/7: Création du client '%CLIENT_ID%'...
-curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/clients" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"clientId\":\"%CLIENT_ID%\",\"enabled\":true,\"protocol\":\"openid-connect\",\"publicClient\":false,\"directAccessGrantsEnabled\":true,\"standardFlowEnabled\":true,\"implicitFlowEnabled\":false,\"serviceAccountsEnabled\":false,\"authorizationServicesEnabled\":false,\"rootUrl\":\"http://localhost:8086\",\"baseUrl\":\"http://localhost:8086\",\"redirectUris\":[\"http://localhost:8086/*\"],\"webOrigins\":[\"http://localhost:8086\"],\"attributes\":{\"post.logout.redirect.uris\":\"http://localhost:8086/*\"}}" > nul 2>&1
-
-if errorlevel 1 (
- echo ⚠️ Le client existe peut-être déjà, continuation...
-) else (
- echo ✅ Client créé
-)
-echo.
-
-REM Étape 5: Récupérer le client ID (UUID) et le secret
-echo 📝 Étape 5/7: Récupération du client secret...
-
-curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/clients" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" > clients.json
-
-REM Extraire le client UUID
-for /f "delims=" %%i in ('powershell -Command "(Get-Content clients.json | ConvertFrom-Json) | Where-Object {$_.clientId -eq '%CLIENT_ID%'} | Select-Object -ExpandProperty id"') do set CLIENT_UUID=%%i
-
-if "%CLIENT_UUID%"=="" (
- echo ❌ ERREUR: Impossible de trouver le client UUID
- del token_response.json clients.json 2>nul
- pause
- exit /b 1
-)
-
-REM Récupérer le secret du client
-curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/clients/%CLIENT_UUID%/client-secret" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" > secret.json
-
-for /f "delims=" %%i in ('powershell -Command "(Get-Content secret.json | ConvertFrom-Json).value"') do set CLIENT_SECRET=%%i
-
-if "%CLIENT_SECRET%"=="" (
- echo ❌ ERREUR: Impossible de récupérer le client secret
- del token_response.json clients.json secret.json 2>nul
- pause
- exit /b 1
-)
-
-echo ✅ Client Secret récupéré: %CLIENT_SECRET%
-echo.
-
-REM Étape 6: Configurer le client scope mapper pour les rôles
-echo 📝 Étape 6/7: Configuration du mapper de rôles...
-
-REM Récupérer le client scope dédié
-curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/clients/%CLIENT_UUID%/default-client-scopes" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" > scopes.json
-
-REM Trouver le scope dédié (généralement unionflow-client-dedicated)
-for /f "delims=" %%i in ('powershell -Command "(Get-Content scopes.json | ConvertFrom-Json) | Where-Object {$_.name -like '*dedicated*'} | Select-Object -ExpandProperty id"') do set SCOPE_ID=%%i
-
-if not "%SCOPE_ID%"=="" (
- REM Créer le mapper pour les rôles
- curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/client-scopes/%SCOPE_ID%/protocol-mappers/models" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"name\":\"realm-roles\",\"protocol\":\"openid-connect\",\"protocolMapper\":\"oidc-usermodel-realm-role-mapper\",\"config\":{\"multivalued\":\"true\",\"userinfo.token.claim\":\"true\",\"id.token.claim\":\"true\",\"access.token.claim\":\"true\",\"claim.name\":\"roles\",\"jsonType.label\":\"String\"}}" > nul 2>&1
- echo ✅ Mapper de rôles configuré
-) else (
- echo ⚠️ Impossible de trouver le client scope dédié, le mapper devra être configuré manuellement
-)
-echo.
-
-REM Étape 7: Créer un utilisateur test
-echo 📝 Étape 7/7: Création de l'utilisateur test...
-
-curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"username\":\"test@unionflow.dev\",\"email\":\"test@unionflow.dev\",\"firstName\":\"Test\",\"lastName\":\"User\",\"enabled\":true,\"emailVerified\":true}" > nul 2>&1
-
-if errorlevel 1 (
- echo ⚠️ L'utilisateur existe peut-être déjà, continuation...
-) else (
- echo ✅ Utilisateur créé
-)
-
-REM Récupérer l'ID de l'utilisateur
-curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users?username=test@unionflow.dev" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" > user.json
-
-for /f "delims=" %%i in ('powershell -Command "(Get-Content user.json | ConvertFrom-Json)[0].id"') do set USER_ID=%%i
-
-if not "%USER_ID%"=="" (
- REM Définir le mot de passe
- curl -s -X PUT "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users/%USER_ID%/reset-password" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "{\"type\":\"password\",\"value\":\"test123\",\"temporary\":false}" > nul 2>&1
- echo ✅ Mot de passe défini (test123)
-
- REM Récupérer les rôles
- curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" > roles.json
-
- REM Assigner les rôles MEMBRE et ADMIN_ORGANISATION
- for /f "delims=" %%i in ('powershell -Command "(Get-Content roles.json | ConvertFrom-Json) | Where-Object {$_.name -eq 'MEMBRE'} | Select-Object -ExpandProperty id"') do set ROLE_MEMBRE_ID=%%i
- for /f "delims=" %%i in ('powershell -Command "(Get-Content roles.json | ConvertFrom-Json) | Where-Object {$_.name -eq 'ADMIN_ORGANISATION'} | Select-Object -ExpandProperty id"') do set ROLE_ADMIN_ID=%%i
-
- if not "%ROLE_MEMBRE_ID%"=="" (
- curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users/%USER_ID%/role-mappings/realm" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "[{\"id\":\"%ROLE_MEMBRE_ID%\",\"name\":\"MEMBRE\"}]" > nul 2>&1
- echo ✅ Rôle MEMBRE assigné
- )
-
- if not "%ROLE_ADMIN_ID%"=="" (
- curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users/%USER_ID%/role-mappings/realm" ^
- -H "Authorization: Bearer %ADMIN_TOKEN%" ^
- -H "Content-Type: application/json" ^
- -d "[{\"id\":\"%ROLE_ADMIN_ID%\",\"name\":\"ADMIN_ORGANISATION\"}]" > nul 2>&1
- echo ✅ Rôle ADMIN_ORGANISATION assigné
- )
-) else (
- echo ⚠️ Impossible de configurer l'utilisateur
-)
-
-echo.
-
-REM Nettoyage des fichiers temporaires
-del token_response.json clients.json secret.json scopes.json user.json roles.json 2>nul
-
-REM Sauvegarder le client secret dans .env
-echo.
-echo 💾 Sauvegarde de la configuration...
-(
-echo # Configuration Keycloak générée automatiquement
-echo # Date: %date% %time%
-echo.
-echo KEYCLOAK_CLIENT_SECRET=%CLIENT_SECRET%
-echo UNIONFLOW_BACKEND_URL=http://localhost:8085
-echo.
-echo # Informations de connexion pour tests
-echo # Username: test@unionflow.dev
-echo # Password: test123
-) > .env
-
-echo ✅ Fichier .env créé avec le client secret
-echo.
-
-REM Résumé
-echo ========================================================
-echo ✅ Configuration Keycloak terminée avec succès!
-echo ========================================================
-echo.
-echo 📋 Résumé:
-echo - Realm: %REALM_NAME%
-echo - Client ID: %CLIENT_ID%
-echo - Client Secret: %CLIENT_SECRET%
-echo - Utilisateur test: test@unionflow.dev
-echo - Mot de passe: test123
-echo - Rôles assignés: MEMBRE, ADMIN_ORGANISATION
-echo.
-echo 📄 Le client secret a été sauvegardé dans le fichier .env
-echo.
-echo 🚀 Prochaines étapes:
-echo 1. Vérifiez le fichier .env
-echo 2. Lancez l'application avec: start-local.bat
-echo 3. Accédez à http://localhost:8086
-echo 4. Connectez-vous avec test@unionflow.dev / test123
-echo.
-echo ========================================================
-echo.
-pause
+@echo off
+REM Script d'automatisation de la configuration Keycloak pour UnionFlow
+REM Usage: setup-keycloak.bat
+
+echo.
+echo ========================================================
+echo 🔧 Configuration automatique de Keycloak pour UnionFlow
+echo ========================================================
+echo.
+
+REM Configuration
+set KEYCLOAK_URL=http://localhost:8180
+set ADMIN_USER=admin
+set ADMIN_PASS=admin
+set REALM_NAME=unionflow
+set CLIENT_ID=unionflow-client
+
+echo 📋 Paramètres:
+echo - Keycloak URL: %KEYCLOAK_URL%
+echo - Admin User: %ADMIN_USER%
+echo - Realm: %REALM_NAME%
+echo - Client ID: %CLIENT_ID%
+echo.
+
+REM Vérifier que Keycloak est accessible
+echo 🔍 Vérification de Keycloak...
+curl -s %KEYCLOAK_URL% >nul 2>&1
+if errorlevel 1 (
+ echo ❌ ERREUR: Keycloak n'est pas accessible sur %KEYCLOAK_URL%
+ echo Assurez-vous que Keycloak est démarré.
+ pause
+ exit /b 1
+)
+echo ✅ Keycloak est accessible
+echo.
+
+REM Étape 1: Obtenir le token admin
+echo 📝 Étape 1/7: Obtention du token admin...
+curl -s -X POST "%KEYCLOAK_URL%/realms/master/protocol/openid-connect/token" ^
+ -H "Content-Type: application/x-www-form-urlencoded" ^
+ -d "username=%ADMIN_USER%" ^
+ -d "password=%ADMIN_PASS%" ^
+ -d "grant_type=password" ^
+ -d "client_id=admin-cli" > token_response.json
+
+REM Extraire le token (utilise PowerShell pour parser le JSON)
+for /f "delims=" %%i in ('powershell -Command "(Get-Content token_response.json | ConvertFrom-Json).access_token"') do set ADMIN_TOKEN=%%i
+
+if "%ADMIN_TOKEN%"=="" (
+ echo ❌ ERREUR: Impossible d'obtenir le token admin
+ echo Vérifiez les identifiants: %ADMIN_USER% / %ADMIN_PASS%
+ del token_response.json 2>nul
+ pause
+ exit /b 1
+)
+echo ✅ Token admin obtenu
+echo.
+
+REM Étape 2: Créer le realm
+echo 📝 Étape 2/7: Création du realm '%REALM_NAME%'...
+curl -s -X POST "%KEYCLOAK_URL%/admin/realms" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"realm\":\"%REALM_NAME%\",\"enabled\":true,\"displayName\":\"UnionFlow\",\"registrationAllowed\":false,\"loginWithEmailAllowed\":true,\"duplicateEmailsAllowed\":false,\"resetPasswordAllowed\":true,\"editUsernameAllowed\":false,\"bruteForceProtected\":true}" > nul 2>&1
+
+if errorlevel 1 (
+ echo ⚠️ Le realm existe peut-être déjà, continuation...
+) else (
+ echo ✅ Realm créé
+)
+echo.
+
+REM Étape 3: Créer les rôles
+echo 📝 Étape 3/7: Création des rôles...
+
+curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"name\":\"SUPER_ADMIN\",\"description\":\"Super administrateur système\"}" > nul 2>&1
+echo ✅ Rôle SUPER_ADMIN créé
+
+curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"name\":\"ADMIN_ORGANISATION\",\"description\":\"Administrateur d'entité\"}" > nul 2>&1
+echo ✅ Rôle ADMIN_ORGANISATION créé
+
+curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"name\":\"MEMBRE\",\"description\":\"Membre standard\"}" > nul 2>&1
+echo ✅ Rôle MEMBRE créé
+
+curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"name\":\"GESTIONNAIRE_MEMBRE\",\"description\":\"Gestionnaire des membres\"}" > nul 2>&1
+echo ✅ Rôle GESTIONNAIRE_MEMBRE créé
+
+curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"name\":\"GESTIONNAIRE_EVENEMENT\",\"description\":\"Gestionnaire des événements\"}" > nul 2>&1
+echo ✅ Rôle GESTIONNAIRE_EVENEMENT créé
+
+echo.
+
+REM Étape 4: Créer le client
+echo 📝 Étape 4/7: Création du client '%CLIENT_ID%'...
+curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/clients" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"clientId\":\"%CLIENT_ID%\",\"enabled\":true,\"protocol\":\"openid-connect\",\"publicClient\":false,\"directAccessGrantsEnabled\":true,\"standardFlowEnabled\":true,\"implicitFlowEnabled\":false,\"serviceAccountsEnabled\":false,\"authorizationServicesEnabled\":false,\"rootUrl\":\"http://localhost:8086\",\"baseUrl\":\"http://localhost:8086\",\"redirectUris\":[\"http://localhost:8086/*\"],\"webOrigins\":[\"http://localhost:8086\"],\"attributes\":{\"post.logout.redirect.uris\":\"http://localhost:8086/*\"}}" > nul 2>&1
+
+if errorlevel 1 (
+ echo ⚠️ Le client existe peut-être déjà, continuation...
+) else (
+ echo ✅ Client créé
+)
+echo.
+
+REM Étape 5: Récupérer le client ID (UUID) et le secret
+echo 📝 Étape 5/7: Récupération du client secret...
+
+curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/clients" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" > clients.json
+
+REM Extraire le client UUID
+for /f "delims=" %%i in ('powershell -Command "(Get-Content clients.json | ConvertFrom-Json) | Where-Object {$_.clientId -eq '%CLIENT_ID%'} | Select-Object -ExpandProperty id"') do set CLIENT_UUID=%%i
+
+if "%CLIENT_UUID%"=="" (
+ echo ❌ ERREUR: Impossible de trouver le client UUID
+ del token_response.json clients.json 2>nul
+ pause
+ exit /b 1
+)
+
+REM Récupérer le secret du client
+curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/clients/%CLIENT_UUID%/client-secret" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" > secret.json
+
+for /f "delims=" %%i in ('powershell -Command "(Get-Content secret.json | ConvertFrom-Json).value"') do set CLIENT_SECRET=%%i
+
+if "%CLIENT_SECRET%"=="" (
+ echo ❌ ERREUR: Impossible de récupérer le client secret
+ del token_response.json clients.json secret.json 2>nul
+ pause
+ exit /b 1
+)
+
+echo ✅ Client Secret récupéré: %CLIENT_SECRET%
+echo.
+
+REM Étape 6: Configurer le client scope mapper pour les rôles
+echo 📝 Étape 6/7: Configuration du mapper de rôles...
+
+REM Récupérer le client scope dédié
+curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/clients/%CLIENT_UUID%/default-client-scopes" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" > scopes.json
+
+REM Trouver le scope dédié (généralement unionflow-client-dedicated)
+for /f "delims=" %%i in ('powershell -Command "(Get-Content scopes.json | ConvertFrom-Json) | Where-Object {$_.name -like '*dedicated*'} | Select-Object -ExpandProperty id"') do set SCOPE_ID=%%i
+
+if not "%SCOPE_ID%"=="" (
+ REM Créer le mapper pour les rôles
+ curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/client-scopes/%SCOPE_ID%/protocol-mappers/models" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"name\":\"realm-roles\",\"protocol\":\"openid-connect\",\"protocolMapper\":\"oidc-usermodel-realm-role-mapper\",\"config\":{\"multivalued\":\"true\",\"userinfo.token.claim\":\"true\",\"id.token.claim\":\"true\",\"access.token.claim\":\"true\",\"claim.name\":\"roles\",\"jsonType.label\":\"String\"}}" > nul 2>&1
+ echo ✅ Mapper de rôles configuré
+) else (
+ echo ⚠️ Impossible de trouver le client scope dédié, le mapper devra être configuré manuellement
+)
+echo.
+
+REM Étape 7: Créer un utilisateur test
+echo 📝 Étape 7/7: Création de l'utilisateur test...
+
+curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"username\":\"test@unionflow.dev\",\"email\":\"test@unionflow.dev\",\"firstName\":\"Test\",\"lastName\":\"User\",\"enabled\":true,\"emailVerified\":true}" > nul 2>&1
+
+if errorlevel 1 (
+ echo ⚠️ L'utilisateur existe peut-être déjà, continuation...
+) else (
+ echo ✅ Utilisateur créé
+)
+
+REM Récupérer l'ID de l'utilisateur
+curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users?username=test@unionflow.dev" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" > user.json
+
+for /f "delims=" %%i in ('powershell -Command "(Get-Content user.json | ConvertFrom-Json)[0].id"') do set USER_ID=%%i
+
+if not "%USER_ID%"=="" (
+ REM Définir le mot de passe
+ curl -s -X PUT "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users/%USER_ID%/reset-password" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "{\"type\":\"password\",\"value\":\"test123\",\"temporary\":false}" > nul 2>&1
+ echo ✅ Mot de passe défini (test123)
+
+ REM Récupérer les rôles
+ curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" > roles.json
+
+ REM Assigner les rôles MEMBRE et ADMIN_ORGANISATION
+ for /f "delims=" %%i in ('powershell -Command "(Get-Content roles.json | ConvertFrom-Json) | Where-Object {$_.name -eq 'MEMBRE'} | Select-Object -ExpandProperty id"') do set ROLE_MEMBRE_ID=%%i
+ for /f "delims=" %%i in ('powershell -Command "(Get-Content roles.json | ConvertFrom-Json) | Where-Object {$_.name -eq 'ADMIN_ORGANISATION'} | Select-Object -ExpandProperty id"') do set ROLE_ADMIN_ID=%%i
+
+ if not "%ROLE_MEMBRE_ID%"=="" (
+ curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users/%USER_ID%/role-mappings/realm" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "[{\"id\":\"%ROLE_MEMBRE_ID%\",\"name\":\"MEMBRE\"}]" > nul 2>&1
+ echo ✅ Rôle MEMBRE assigné
+ )
+
+ if not "%ROLE_ADMIN_ID%"=="" (
+ curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users/%USER_ID%/role-mappings/realm" ^
+ -H "Authorization: Bearer %ADMIN_TOKEN%" ^
+ -H "Content-Type: application/json" ^
+ -d "[{\"id\":\"%ROLE_ADMIN_ID%\",\"name\":\"ADMIN_ORGANISATION\"}]" > nul 2>&1
+ echo ✅ Rôle ADMIN_ORGANISATION assigné
+ )
+) else (
+ echo ⚠️ Impossible de configurer l'utilisateur
+)
+
+echo.
+
+REM Nettoyage des fichiers temporaires
+del token_response.json clients.json secret.json scopes.json user.json roles.json 2>nul
+
+REM Sauvegarder le client secret dans .env
+echo.
+echo 💾 Sauvegarde de la configuration...
+(
+echo # Configuration Keycloak générée automatiquement
+echo # Date: %date% %time%
+echo.
+echo KEYCLOAK_CLIENT_SECRET=%CLIENT_SECRET%
+echo UNIONFLOW_BACKEND_URL=http://localhost:8085
+echo.
+echo # Informations de connexion pour tests
+echo # Username: test@unionflow.dev
+echo # Password: test123
+) > .env
+
+echo ✅ Fichier .env créé avec le client secret
+echo.
+
+REM Résumé
+echo ========================================================
+echo ✅ Configuration Keycloak terminée avec succès!
+echo ========================================================
+echo.
+echo 📋 Résumé:
+echo - Realm: %REALM_NAME%
+echo - Client ID: %CLIENT_ID%
+echo - Client Secret: %CLIENT_SECRET%
+echo - Utilisateur test: test@unionflow.dev
+echo - Mot de passe: test123
+echo - Rôles assignés: MEMBRE, ADMIN_ORGANISATION
+echo.
+echo 📄 Le client secret a été sauvegardé dans le fichier .env
+echo.
+echo 🚀 Prochaines étapes:
+echo 1. Vérifiez le fichier .env
+echo 2. Lancez l'application avec: start-local.bat
+echo 3. Accédez à http://localhost:8086
+echo 4. Connectez-vous avec test@unionflow.dev / test123
+echo.
+echo ========================================================
+echo.
+pause
diff --git a/setup-keycloak.sh b/setup-keycloak.sh
index 604ff78..f9a70c5 100644
--- a/setup-keycloak.sh
+++ b/setup-keycloak.sh
@@ -1,311 +1,311 @@
-#!/bin/bash
-
-# Script d'automatisation de la configuration Keycloak pour UnionFlow
-# Usage: ./setup-keycloak.sh
-
-echo ""
-echo "========================================================"
-echo "🔧 Configuration automatique de Keycloak pour UnionFlow"
-echo "========================================================"
-echo ""
-
-# Configuration
-KEYCLOAK_URL="http://localhost:8180"
-ADMIN_USER="admin"
-ADMIN_PASS="admin"
-REALM_NAME="unionflow"
-CLIENT_ID="unionflow-client"
-
-echo "📋 Paramètres:"
-echo " - Keycloak URL: $KEYCLOAK_URL"
-echo " - Admin User: $ADMIN_USER"
-echo " - Realm: $REALM_NAME"
-echo " - Client ID: $CLIENT_ID"
-echo ""
-
-# Vérifier que Keycloak est accessible
-echo "🔍 Vérification de Keycloak..."
-if ! curl -s "$KEYCLOAK_URL" > /dev/null; then
- echo "❌ ERREUR: Keycloak n'est pas accessible sur $KEYCLOAK_URL"
- echo " Assurez-vous que Keycloak est démarré."
- exit 1
-fi
-echo "✅ Keycloak est accessible"
-echo ""
-
-# Étape 1: Obtenir le token admin
-echo "📝 Étape 1/7: Obtention du token admin..."
-TOKEN_RESPONSE=$(curl -s -X POST "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \
- -H "Content-Type: application/x-www-form-urlencoded" \
- -d "username=$ADMIN_USER" \
- -d "password=$ADMIN_PASS" \
- -d "grant_type=password" \
- -d "client_id=admin-cli")
-
-ADMIN_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
-
-if [ -z "$ADMIN_TOKEN" ]; then
- echo "❌ ERREUR: Impossible d'obtenir le token admin"
- echo " Vérifiez les identifiants: $ADMIN_USER / $ADMIN_PASS"
- exit 1
-fi
-echo "✅ Token admin obtenu"
-echo ""
-
-# Étape 2: Créer le realm
-echo "📝 Étape 2/7: Création du realm '$REALM_NAME'..."
-curl -s -X POST "$KEYCLOAK_URL/admin/realms" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d "{\"realm\":\"$REALM_NAME\",\"enabled\":true,\"displayName\":\"UnionFlow\",\"registrationAllowed\":false,\"loginWithEmailAllowed\":true,\"duplicateEmailsAllowed\":false,\"resetPasswordAllowed\":true,\"editUsernameAllowed\":false,\"bruteForceProtected\":true}" > /dev/null 2>&1
-
-if [ $? -ne 0 ]; then
- echo "⚠️ Le realm existe peut-être déjà, continuation..."
-else
- echo "✅ Realm créé"
-fi
-echo ""
-
-# Étape 3: Créer les rôles
-echo "📝 Étape 3/7: Création des rôles..."
-
-curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{"name":"SUPER_ADMIN","description":"Super administrateur système"}' > /dev/null 2>&1
-echo " ✅ Rôle SUPER_ADMIN créé"
-
-curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{"name":"ADMIN_ORGANISATION","description":"Administrateur d'\''entité"}' > /dev/null 2>&1
-echo " ✅ Rôle ADMIN_ORGANISATION créé"
-
-curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{"name":"MEMBRE","description":"Membre standard"}' > /dev/null 2>&1
-echo " ✅ Rôle MEMBRE créé"
-
-curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{"name":"GESTIONNAIRE_MEMBRE","description":"Gestionnaire des membres"}' > /dev/null 2>&1
-echo " ✅ Rôle GESTIONNAIRE_MEMBRE créé"
-
-curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{"name":"GESTIONNAIRE_EVENEMENT","description":"Gestionnaire des événements"}' > /dev/null 2>&1
-echo " ✅ Rôle GESTIONNAIRE_EVENEMENT créé"
-
-echo ""
-
-# Étape 4: Créer le client
-echo "📝 Étape 4/7: Création du client '$CLIENT_ID'..."
-curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d "{\"clientId\":\"$CLIENT_ID\",\"enabled\":true,\"protocol\":\"openid-connect\",\"publicClient\":false,\"directAccessGrantsEnabled\":true,\"standardFlowEnabled\":true,\"implicitFlowEnabled\":false,\"serviceAccountsEnabled\":false,\"authorizationServicesEnabled\":false,\"rootUrl\":\"http://localhost:8086\",\"baseUrl\":\"http://localhost:8086\",\"redirectUris\":[\"http://localhost:8086/*\"],\"webOrigins\":[\"http://localhost:8086\"],\"attributes\":{\"post.logout.redirect.uris\":\"http://localhost:8086/*\"}}" > /dev/null 2>&1
-
-if [ $? -ne 0 ]; then
- echo "⚠️ Le client existe peut-être déjà, continuation..."
-else
- echo "✅ Client créé"
-fi
-echo ""
-
-# Étape 5: Récupérer le client ID (UUID) et le secret
-echo "📝 Étape 5/7: Récupération du client secret..."
-
-CLIENTS=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients" \
- -H "Authorization: Bearer $ADMIN_TOKEN")
-
-CLIENT_UUID=$(echo "$CLIENTS" | grep -o "\"id\":\"[^\"]*\"" | grep -B5 "\"clientId\":\"$CLIENT_ID\"" | head -1 | cut -d'"' -f4)
-
-if [ -z "$CLIENT_UUID" ]; then
- # Méthode alternative avec jq si disponible
- if command -v jq &> /dev/null; then
- CLIENT_UUID=$(echo "$CLIENTS" | jq -r ".[] | select(.clientId==\"$CLIENT_ID\") | .id")
- fi
-fi
-
-if [ -z "$CLIENT_UUID" ]; then
- echo "❌ ERREUR: Impossible de trouver le client UUID"
- echo " Installez 'jq' pour un meilleur parsing JSON ou configurez manuellement"
- exit 1
-fi
-
-# Récupérer le secret du client
-SECRET_RESPONSE=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/client-secret" \
- -H "Authorization: Bearer $ADMIN_TOKEN")
-
-CLIENT_SECRET=$(echo "$SECRET_RESPONSE" | grep -o '"value":"[^"]*' | cut -d'"' -f4)
-
-if [ -z "$CLIENT_SECRET" ] && command -v jq &> /dev/null; then
- CLIENT_SECRET=$(echo "$SECRET_RESPONSE" | jq -r '.value')
-fi
-
-if [ -z "$CLIENT_SECRET" ]; then
- echo "❌ ERREUR: Impossible de récupérer le client secret"
- exit 1
-fi
-
-echo "✅ Client Secret récupéré: $CLIENT_SECRET"
-echo ""
-
-# Étape 6: Ajouter l'audience mapper pour unionflow-server
-echo "📝 Étape 6/8: Ajout de l'audience mapper 'unionflow-server'..."
-HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
- "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/protocol-mappers/models" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{
- "name": "unionflow-server-audience",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-audience-mapper",
- "consentRequired": false,
- "config": {
- "included.client.audience": "unionflow-server",
- "id.token.claim": "false",
- "access.token.claim": "true"
- }
- }')
-if [ "$HTTP_STATUS" = "201" ]; then
- echo "✅ Audience mapper 'unionflow-server' ajouté"
-elif [ "$HTTP_STATUS" = "409" ]; then
- echo "⚠️ Audience mapper 'unionflow-server-audience' existe déjà"
-else
- echo "⚠️ Échec ajout audience mapper (HTTP ${HTTP_STATUS}) — à configurer manuellement"
-fi
-echo ""
-
-# Étape 7: Configurer le client scope mapper pour les rôles
-echo "📝 Étape 7/8: Configuration du mapper de rôles..."
-
-SCOPES=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/default-client-scopes" \
- -H "Authorization: Bearer $ADMIN_TOKEN")
-
-SCOPE_ID=$(echo "$SCOPES" | grep -o '"id":"[^"]*"' | grep -A5 "dedicated" | head -1 | cut -d'"' -f4)
-
-if [ -z "$SCOPE_ID" ] && command -v jq &> /dev/null; then
- SCOPE_ID=$(echo "$SCOPES" | jq -r '.[] | select(.name | contains("dedicated")) | .id')
-fi
-
-if [ -n "$SCOPE_ID" ]; then
- curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/client-scopes/$SCOPE_ID/protocol-mappers/models" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{"name":"realm-roles","protocol":"openid-connect","protocolMapper":"oidc-usermodel-realm-role-mapper","config":{"multivalued":"true","userinfo.token.claim":"true","id.token.claim":"true","access.token.claim":"true","claim.name":"roles","jsonType.label":"String"}}' > /dev/null 2>&1
- echo "✅ Mapper de rôles configuré"
-else
- echo "⚠️ Impossible de trouver le client scope dédié, le mapper devra être configuré manuellement"
-fi
-echo ""
-
-# Étape 8: Créer un utilisateur test
-echo "📝 Étape 8/8: Création de l'utilisateur test..."
-
-curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{"username":"test@unionflow.dev","email":"test@unionflow.dev","firstName":"Test","lastName":"User","enabled":true,"emailVerified":true}' > /dev/null 2>&1
-
-if [ $? -ne 0 ]; then
- echo "⚠️ L'utilisateur existe peut-être déjà, continuation..."
-else
- echo "✅ Utilisateur créé"
-fi
-
-# Récupérer l'ID de l'utilisateur
-USER_RESPONSE=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users?username=test@unionflow.dev" \
- -H "Authorization: Bearer $ADMIN_TOKEN")
-
-USER_ID=$(echo "$USER_RESPONSE" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4)
-
-if [ -z "$USER_ID" ] && command -v jq &> /dev/null; then
- USER_ID=$(echo "$USER_RESPONSE" | jq -r '.[0].id')
-fi
-
-if [ -n "$USER_ID" ]; then
- # Définir le mot de passe
- curl -s -X PUT "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/reset-password" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d '{"type":"password","value":"test123","temporary":false}' > /dev/null 2>&1
- echo " ✅ Mot de passe défini (test123)"
-
- # Récupérer les rôles
- ROLES=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
- -H "Authorization: Bearer $ADMIN_TOKEN")
-
- ROLE_MEMBRE_ID=$(echo "$ROLES" | grep -B2 '"name":"MEMBRE"' | grep '"id"' | cut -d'"' -f4)
- ROLE_ADMIN_ID=$(echo "$ROLES" | grep -B2 '"name":"ADMIN_ORGANISATION"' | grep '"id"' | cut -d'"' -f4)
-
- if command -v jq &> /dev/null; then
- ROLE_MEMBRE_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="MEMBRE") | .id')
- ROLE_ADMIN_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="ADMIN_ORGANISATION") | .id')
- fi
-
- if [ -n "$ROLE_MEMBRE_ID" ]; then
- curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/role-mappings/realm" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d "[{\"id\":\"$ROLE_MEMBRE_ID\",\"name\":\"MEMBRE\"}]" > /dev/null 2>&1
- echo " ✅ Rôle MEMBRE assigné"
- fi
-
- if [ -n "$ROLE_ADMIN_ID" ]; then
- curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/role-mappings/realm" \
- -H "Authorization: Bearer $ADMIN_TOKEN" \
- -H "Content-Type: application/json" \
- -d "[{\"id\":\"$ROLE_ADMIN_ID\",\"name\":\"ADMIN_ORGANISATION\"}]" > /dev/null 2>&1
- echo " ✅ Rôle ADMIN_ORGANISATION assigné"
- fi
-else
- echo "⚠️ Impossible de configurer l'utilisateur"
-fi
-
-echo ""
-
-# Sauvegarder le client secret dans .env
-echo ""
-echo "💾 Sauvegarde de la configuration..."
-cat > .env << EOF
-# Configuration Keycloak générée automatiquement
-# Date: $(date)
-
-KEYCLOAK_CLIENT_SECRET=$CLIENT_SECRET
-UNIONFLOW_BACKEND_URL=http://localhost:8085
-
-# Informations de connexion pour tests
-# Username: test@unionflow.dev
-# Password: test123
-EOF
-
-echo "✅ Fichier .env créé avec le client secret"
-echo ""
-
-# Résumé
-echo "========================================================"
-echo "✅ Configuration Keycloak terminée avec succès!"
-echo "========================================================"
-echo ""
-echo "📋 Résumé:"
-echo " - Realm: $REALM_NAME"
-echo " - Client ID: $CLIENT_ID"
-echo " - Client Secret: $CLIENT_SECRET"
-echo " - Utilisateur test: test@unionflow.dev"
-echo " - Mot de passe: test123"
-echo " - Rôles assignés: MEMBRE, ADMIN_ORGANISATION"
-echo ""
-echo "📄 Le client secret a été sauvegardé dans le fichier .env"
-echo ""
-echo "🚀 Prochaines étapes:"
-echo " 1. Vérifiez le fichier .env"
-echo " 2. Lancez l'application avec: ./start-local.sh"
-echo " 3. Accédez à http://localhost:8086"
-echo " 4. Connectez-vous avec test@unionflow.dev / test123"
-echo ""
-echo "========================================================"
-echo ""
+#!/bin/bash
+
+# Script d'automatisation de la configuration Keycloak pour UnionFlow
+# Usage: ./setup-keycloak.sh
+
+echo ""
+echo "========================================================"
+echo "🔧 Configuration automatique de Keycloak pour UnionFlow"
+echo "========================================================"
+echo ""
+
+# Configuration
+KEYCLOAK_URL="http://localhost:8180"
+ADMIN_USER="admin"
+ADMIN_PASS="admin"
+REALM_NAME="unionflow"
+CLIENT_ID="unionflow-client"
+
+echo "📋 Paramètres:"
+echo " - Keycloak URL: $KEYCLOAK_URL"
+echo " - Admin User: $ADMIN_USER"
+echo " - Realm: $REALM_NAME"
+echo " - Client ID: $CLIENT_ID"
+echo ""
+
+# Vérifier que Keycloak est accessible
+echo "🔍 Vérification de Keycloak..."
+if ! curl -s "$KEYCLOAK_URL" > /dev/null; then
+ echo "❌ ERREUR: Keycloak n'est pas accessible sur $KEYCLOAK_URL"
+ echo " Assurez-vous que Keycloak est démarré."
+ exit 1
+fi
+echo "✅ Keycloak est accessible"
+echo ""
+
+# Étape 1: Obtenir le token admin
+echo "📝 Étape 1/7: Obtention du token admin..."
+TOKEN_RESPONSE=$(curl -s -X POST "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \
+ -H "Content-Type: application/x-www-form-urlencoded" \
+ -d "username=$ADMIN_USER" \
+ -d "password=$ADMIN_PASS" \
+ -d "grant_type=password" \
+ -d "client_id=admin-cli")
+
+ADMIN_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
+
+if [ -z "$ADMIN_TOKEN" ]; then
+ echo "❌ ERREUR: Impossible d'obtenir le token admin"
+ echo " Vérifiez les identifiants: $ADMIN_USER / $ADMIN_PASS"
+ exit 1
+fi
+echo "✅ Token admin obtenu"
+echo ""
+
+# Étape 2: Créer le realm
+echo "📝 Étape 2/7: Création du realm '$REALM_NAME'..."
+curl -s -X POST "$KEYCLOAK_URL/admin/realms" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d "{\"realm\":\"$REALM_NAME\",\"enabled\":true,\"displayName\":\"UnionFlow\",\"registrationAllowed\":false,\"loginWithEmailAllowed\":true,\"duplicateEmailsAllowed\":false,\"resetPasswordAllowed\":true,\"editUsernameAllowed\":false,\"bruteForceProtected\":true}" > /dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ echo "⚠️ Le realm existe peut-être déjà, continuation..."
+else
+ echo "✅ Realm créé"
+fi
+echo ""
+
+# Étape 3: Créer les rôles
+echo "📝 Étape 3/7: Création des rôles..."
+
+curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"name":"SUPER_ADMIN","description":"Super administrateur système"}' > /dev/null 2>&1
+echo " ✅ Rôle SUPER_ADMIN créé"
+
+curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"name":"ADMIN_ORGANISATION","description":"Administrateur d'\''entité"}' > /dev/null 2>&1
+echo " ✅ Rôle ADMIN_ORGANISATION créé"
+
+curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"name":"MEMBRE","description":"Membre standard"}' > /dev/null 2>&1
+echo " ✅ Rôle MEMBRE créé"
+
+curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"name":"GESTIONNAIRE_MEMBRE","description":"Gestionnaire des membres"}' > /dev/null 2>&1
+echo " ✅ Rôle GESTIONNAIRE_MEMBRE créé"
+
+curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"name":"GESTIONNAIRE_EVENEMENT","description":"Gestionnaire des événements"}' > /dev/null 2>&1
+echo " ✅ Rôle GESTIONNAIRE_EVENEMENT créé"
+
+echo ""
+
+# Étape 4: Créer le client
+echo "📝 Étape 4/7: Création du client '$CLIENT_ID'..."
+curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d "{\"clientId\":\"$CLIENT_ID\",\"enabled\":true,\"protocol\":\"openid-connect\",\"publicClient\":false,\"directAccessGrantsEnabled\":true,\"standardFlowEnabled\":true,\"implicitFlowEnabled\":false,\"serviceAccountsEnabled\":false,\"authorizationServicesEnabled\":false,\"rootUrl\":\"http://localhost:8086\",\"baseUrl\":\"http://localhost:8086\",\"redirectUris\":[\"http://localhost:8086/*\"],\"webOrigins\":[\"http://localhost:8086\"],\"attributes\":{\"post.logout.redirect.uris\":\"http://localhost:8086/*\"}}" > /dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ echo "⚠️ Le client existe peut-être déjà, continuation..."
+else
+ echo "✅ Client créé"
+fi
+echo ""
+
+# Étape 5: Récupérer le client ID (UUID) et le secret
+echo "📝 Étape 5/7: Récupération du client secret..."
+
+CLIENTS=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients" \
+ -H "Authorization: Bearer $ADMIN_TOKEN")
+
+CLIENT_UUID=$(echo "$CLIENTS" | grep -o "\"id\":\"[^\"]*\"" | grep -B5 "\"clientId\":\"$CLIENT_ID\"" | head -1 | cut -d'"' -f4)
+
+if [ -z "$CLIENT_UUID" ]; then
+ # Méthode alternative avec jq si disponible
+ if command -v jq &> /dev/null; then
+ CLIENT_UUID=$(echo "$CLIENTS" | jq -r ".[] | select(.clientId==\"$CLIENT_ID\") | .id")
+ fi
+fi
+
+if [ -z "$CLIENT_UUID" ]; then
+ echo "❌ ERREUR: Impossible de trouver le client UUID"
+ echo " Installez 'jq' pour un meilleur parsing JSON ou configurez manuellement"
+ exit 1
+fi
+
+# Récupérer le secret du client
+SECRET_RESPONSE=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/client-secret" \
+ -H "Authorization: Bearer $ADMIN_TOKEN")
+
+CLIENT_SECRET=$(echo "$SECRET_RESPONSE" | grep -o '"value":"[^"]*' | cut -d'"' -f4)
+
+if [ -z "$CLIENT_SECRET" ] && command -v jq &> /dev/null; then
+ CLIENT_SECRET=$(echo "$SECRET_RESPONSE" | jq -r '.value')
+fi
+
+if [ -z "$CLIENT_SECRET" ]; then
+ echo "❌ ERREUR: Impossible de récupérer le client secret"
+ exit 1
+fi
+
+echo "✅ Client Secret récupéré: $CLIENT_SECRET"
+echo ""
+
+# Étape 6: Ajouter l'audience mapper pour unionflow-server
+echo "📝 Étape 6/8: Ajout de l'audience mapper 'unionflow-server'..."
+HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
+ "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/protocol-mappers/models" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "unionflow-server-audience",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-mapper",
+ "consentRequired": false,
+ "config": {
+ "included.client.audience": "unionflow-server",
+ "id.token.claim": "false",
+ "access.token.claim": "true"
+ }
+ }')
+if [ "$HTTP_STATUS" = "201" ]; then
+ echo "✅ Audience mapper 'unionflow-server' ajouté"
+elif [ "$HTTP_STATUS" = "409" ]; then
+ echo "⚠️ Audience mapper 'unionflow-server-audience' existe déjà"
+else
+ echo "⚠️ Échec ajout audience mapper (HTTP ${HTTP_STATUS}) — à configurer manuellement"
+fi
+echo ""
+
+# Étape 7: Configurer le client scope mapper pour les rôles
+echo "📝 Étape 7/8: Configuration du mapper de rôles..."
+
+SCOPES=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/default-client-scopes" \
+ -H "Authorization: Bearer $ADMIN_TOKEN")
+
+SCOPE_ID=$(echo "$SCOPES" | grep -o '"id":"[^"]*"' | grep -A5 "dedicated" | head -1 | cut -d'"' -f4)
+
+if [ -z "$SCOPE_ID" ] && command -v jq &> /dev/null; then
+ SCOPE_ID=$(echo "$SCOPES" | jq -r '.[] | select(.name | contains("dedicated")) | .id')
+fi
+
+if [ -n "$SCOPE_ID" ]; then
+ curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/client-scopes/$SCOPE_ID/protocol-mappers/models" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"name":"realm-roles","protocol":"openid-connect","protocolMapper":"oidc-usermodel-realm-role-mapper","config":{"multivalued":"true","userinfo.token.claim":"true","id.token.claim":"true","access.token.claim":"true","claim.name":"roles","jsonType.label":"String"}}' > /dev/null 2>&1
+ echo "✅ Mapper de rôles configuré"
+else
+ echo "⚠️ Impossible de trouver le client scope dédié, le mapper devra être configuré manuellement"
+fi
+echo ""
+
+# Étape 8: Créer un utilisateur test
+echo "📝 Étape 8/8: Création de l'utilisateur test..."
+
+curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"username":"test@unionflow.dev","email":"test@unionflow.dev","firstName":"Test","lastName":"User","enabled":true,"emailVerified":true}' > /dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ echo "⚠️ L'utilisateur existe peut-être déjà, continuation..."
+else
+ echo "✅ Utilisateur créé"
+fi
+
+# Récupérer l'ID de l'utilisateur
+USER_RESPONSE=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users?username=test@unionflow.dev" \
+ -H "Authorization: Bearer $ADMIN_TOKEN")
+
+USER_ID=$(echo "$USER_RESPONSE" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4)
+
+if [ -z "$USER_ID" ] && command -v jq &> /dev/null; then
+ USER_ID=$(echo "$USER_RESPONSE" | jq -r '.[0].id')
+fi
+
+if [ -n "$USER_ID" ]; then
+ # Définir le mot de passe
+ curl -s -X PUT "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/reset-password" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"type":"password","value":"test123","temporary":false}' > /dev/null 2>&1
+ echo " ✅ Mot de passe défini (test123)"
+
+ # Récupérer les rôles
+ ROLES=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
+ -H "Authorization: Bearer $ADMIN_TOKEN")
+
+ ROLE_MEMBRE_ID=$(echo "$ROLES" | grep -B2 '"name":"MEMBRE"' | grep '"id"' | cut -d'"' -f4)
+ ROLE_ADMIN_ID=$(echo "$ROLES" | grep -B2 '"name":"ADMIN_ORGANISATION"' | grep '"id"' | cut -d'"' -f4)
+
+ if command -v jq &> /dev/null; then
+ ROLE_MEMBRE_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="MEMBRE") | .id')
+ ROLE_ADMIN_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="ADMIN_ORGANISATION") | .id')
+ fi
+
+ if [ -n "$ROLE_MEMBRE_ID" ]; then
+ curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/role-mappings/realm" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d "[{\"id\":\"$ROLE_MEMBRE_ID\",\"name\":\"MEMBRE\"}]" > /dev/null 2>&1
+ echo " ✅ Rôle MEMBRE assigné"
+ fi
+
+ if [ -n "$ROLE_ADMIN_ID" ]; then
+ curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/role-mappings/realm" \
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d "[{\"id\":\"$ROLE_ADMIN_ID\",\"name\":\"ADMIN_ORGANISATION\"}]" > /dev/null 2>&1
+ echo " ✅ Rôle ADMIN_ORGANISATION assigné"
+ fi
+else
+ echo "⚠️ Impossible de configurer l'utilisateur"
+fi
+
+echo ""
+
+# Sauvegarder le client secret dans .env
+echo ""
+echo "💾 Sauvegarde de la configuration..."
+cat > .env << EOF
+# Configuration Keycloak générée automatiquement
+# Date: $(date)
+
+KEYCLOAK_CLIENT_SECRET=$CLIENT_SECRET
+UNIONFLOW_BACKEND_URL=http://localhost:8085
+
+# Informations de connexion pour tests
+# Username: test@unionflow.dev
+# Password: test123
+EOF
+
+echo "✅ Fichier .env créé avec le client secret"
+echo ""
+
+# Résumé
+echo "========================================================"
+echo "✅ Configuration Keycloak terminée avec succès!"
+echo "========================================================"
+echo ""
+echo "📋 Résumé:"
+echo " - Realm: $REALM_NAME"
+echo " - Client ID: $CLIENT_ID"
+echo " - Client Secret: $CLIENT_SECRET"
+echo " - Utilisateur test: test@unionflow.dev"
+echo " - Mot de passe: test123"
+echo " - Rôles assignés: MEMBRE, ADMIN_ORGANISATION"
+echo ""
+echo "📄 Le client secret a été sauvegardé dans le fichier .env"
+echo ""
+echo "🚀 Prochaines étapes:"
+echo " 1. Vérifiez le fichier .env"
+echo " 2. Lancez l'application avec: ./start-local.sh"
+echo " 3. Accédez à http://localhost:8086"
+echo " 4. Connectez-vous avec test@unionflow.dev / test123"
+echo ""
+echo "========================================================"
+echo ""
diff --git a/src/main/java/dev/lions/unionflow/client/bean/MenuBean.java b/src/main/java/dev/lions/unionflow/client/bean/MenuBean.java
index cdf294e..e7987b7 100644
--- a/src/main/java/dev/lions/unionflow/client/bean/MenuBean.java
+++ b/src/main/java/dev/lions/unionflow/client/bean/MenuBean.java
@@ -1,632 +1,632 @@
-package dev.lions.unionflow.client.bean;
-
-import dev.lions.unionflow.client.view.UserSession;
-import jakarta.enterprise.context.SessionScoped;
-import jakarta.inject.Named;
-import io.quarkus.security.identity.SecurityIdentity;
-import jakarta.inject.Inject;
-
-import java.io.Serializable;
-import java.util.Set;
-
-/**
- * Bean de gestion de la visibilité des menus en fonction des rôles utilisateur.
- *
- *
Fournit des méthodes utilitaires pour déterminer quels menus afficher
- * selon le rôle de l'utilisateur connecté et le type de son organisation.
- *
- *
Utilise {@link SecurityIdentity} pour l'authentification OIDC en mode web-app,
- * en cohérence avec {@link dev.lions.unionflow.client.view.LoginBean}.
- *
- * @author UnionFlow Team
- * @version 1.1
- * @since 2026-03-01
- */
-@Named
-@SessionScoped
-public class MenuBean implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- @Inject
- SecurityIdentity securityIdentity;
-
- @Inject
- UserSession userSession;
-
- /**
- * Vérifie si l'utilisateur a au moins un des rôles spécifiés.
- *
- * @param roles Les rôles à vérifier
- * @return true si l'utilisateur possède au moins un des rôles, false sinon
- */
- private boolean hasAnyRole(String... roles) {
- if (securityIdentity == null || securityIdentity.isAnonymous()) {
- return false;
- }
-
- Set userRoles = securityIdentity.getRoles();
- if (userRoles == null || userRoles.isEmpty()) {
- return false;
- }
-
- for (String role : roles) {
- if (userRoles.contains(role)) {
- return true;
- }
- }
- return false;
- }
-
- // ========================================================================
- // MENUS PRINCIPAUX - Visibilité par rôle
- // ========================================================================
-
- /**
- * Super Administration - Visible uniquement pour SUPER_ADMIN
- */
- public boolean isSuperAdminMenuVisible() {
- return hasAnyRole("SUPER_ADMIN");
- }
-
- /**
- * Administration - Visible pour admins et secrétaires
- */
- public boolean isAdministrationMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU");
- }
-
- // ========================================================================
- // NOUVEAUX MENUS PERSONNELS - Visible pour TOUS les membres
- // ========================================================================
-
- /**
- * Mes Finances - Menu personnel pour consulter/gérer ses propres finances
- * Visible pour TOUS les membres (épargne, cotisations, prêts)
- */
- public boolean isMesFinancesMenuVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Événements - Calendrier et inscriptions aux événements
- * Visible pour TOUS les membres
- */
- public boolean isMesEvenementsMenuVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Mes Demandes d'Aide Sociale - Menu personnel pour les demandes d'aide
- * Visible pour TOUS les membres
- */
- public boolean isMesAidesSocialesMenuVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Mes Formations - Catalogue et inscriptions aux formations
- * Visible pour TOUS les membres
- */
- public boolean isMesFormationsMenuVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Mes Communications - Messages et notifications personnelles
- * Visible pour TOUS les membres
- */
- public boolean isMesCommunicationsMenuVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- // ========================================================================
- // MENUS DE GESTION - Visible pour les responsables uniquement
- // ========================================================================
-
- /**
- * Gestion des Membres - Administration des membres
- * Visible pour SECRETAIRE et ADMIN uniquement
- */
- public boolean isGestionMembresMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
- }
-
- /**
- * Annuaire des Membres - Consultation de la liste (pas de modification)
- * Visible pour les responsables et bureau SEULEMENT (PAS pour MEMBRE_ACTIF)
- *
- * Raison métier: Un membre simple n'a généralement pas besoin de voir la liste complète
- * des autres membres. Cela peut poser des problèmes de:
- * - RGPD: Exposition non justifiée de données personnelles
- * - Sécurité: Risque de spam/phishing entre membres
- * - UX: Surcharge du menu pour un usage limité
- *
- * Si l'organisation souhaite activer l'annuaire pour MEMBRE_ACTIF, cela doit être
- * fait via configuration explicite (future Phase 3).
- */
- public boolean isAnnuaireMembresVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "TRESORIER",
- "RESPONSABLE_SOCIAL", "RESPONSABLE_EVENEMENTS", "RESPONSABLE_CREDIT",
- "MEMBRE_BUREAU");
- // MEMBRE_ACTIF retiré intentionnellement pour raisons UX et RGPD
- }
-
- /**
- * Gestion Financière - Administration finances (trésorerie, budgets, comptabilité)
- * Visible pour TRESORIER et ADMIN uniquement
- */
- public boolean isGestionFinancesMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
- }
-
- /**
- * Gestion Événements - Création et organisation des événements
- * Visible pour RESPONSABLE_EVENEMENTS, SECRETAIRE et ADMIN
- */
- public boolean isGestionEvenementsMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "RESPONSABLE_EVENEMENTS");
- }
-
- /**
- * Gestion Aide Sociale - Traitement des demandes d'aide
- * Visible pour RESPONSABLE_SOCIAL et ADMIN
- */
- public boolean isGestionAidesSocialesMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_SOCIAL");
- }
-
- /**
- * Organisations - Visible pour admins et super-admins
- */
- public boolean isOrganisationsMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION");
- }
-
- /**
- * Adhésions - Visible pour admins, secrétaires, bureau
- */
- public boolean isAdhesionsMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU");
- }
-
- /**
- * Communication - Visible pour admins, secrétaires, bureau
- */
- public boolean isCommunicationMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "RESPONSABLE_EVENEMENTS", "MEMBRE_BUREAU");
- }
-
- /**
- * Documents - Visible pour tous sauf membres simples
- */
- public boolean isDocumentsMenuVisible() {
- return !hasAnyRole("MEMBRE_SIMPLE");
- }
-
- /**
- * Formation - Visible pour tous les membres actifs et plus
- */
- public boolean isFormationMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU", "MEMBRE_ACTIF");
- }
-
- /**
- * Rapports et Analyses - Visible pour admins, trésoriers, secrétaires, bureau
- */
- public boolean isRapportsMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER", "SECRETAIRE", "MEMBRE_BUREAU");
- }
-
- /**
- * Outils et Utilitaires - Visible pour admins et secrétaires
- */
- public boolean isOutilsMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU");
- }
-
- /**
- * Mon Espace Personnel - Visible pour tous les utilisateurs connectés
- */
- public boolean isPersonnelMenuVisible() {
- return true; // Tous les utilisateurs connectés
- }
-
- /**
- * Aide et Support - Visible pour tous
- */
- public boolean isAideMenuVisible() {
- return true; // Tous les utilisateurs
- }
-
- // ========================================================================
- // ITEMS DE MENUS PERSONNELS - Actions membre
- // ========================================================================
-
- /**
- * Consulter mon épargne - Visible pour TOUS
- */
- public boolean isMonEpargneVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Payer mes cotisations - Visible pour TOUS
- */
- public boolean isPaiementCotisationVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Demander un prêt/crédit - Visible pour TOUS
- */
- public boolean isDemandePretVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Mes prêts en cours - Visible pour TOUS
- */
- public boolean isMesPretsVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Demander une aide sociale - Visible pour TOUS
- */
- public boolean isDemandeAideSocialeVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Mes demandes d'aide en cours - Visible pour TOUS
- */
- public boolean isMesDemandesAideVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * M'inscrire à un événement - Visible pour TOUS
- */
- public boolean isInscriptionEvenementVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Mes inscriptions aux événements - Visible pour TOUS
- */
- public boolean isMesInscriptionsEvenementsVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * M'inscrire à une formation - Visible pour TOUS
- */
- public boolean isInscriptionFormationVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Mes formations - Visible pour TOUS
- */
- public boolean isMesFormationsVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Mes messages personnels - Visible pour TOUS
- */
- public boolean isMesMessagesVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- /**
- * Annonces officielles (lecture seule) - Visible pour TOUS
- */
- public boolean isAnnoncesLectureVisible() {
- return !securityIdentity.isAnonymous();
- }
-
- // ========================================================================
- // ITEMS DE MENUS SPÉCIFIQUES - Administration
- // ========================================================================
-
- /**
- * Items Keycloak User Manager - Visible uniquement pour SUPER_ADMIN
- */
- public boolean isKeycloakUserManagerVisible() {
- return hasAnyRole("SUPER_ADMIN");
- }
-
- /**
- * Gestion des cotisations (admin) - Visible pour admins et trésoriers
- */
- public boolean isCotisationsAdminVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
- }
-
- /**
- * Comptabilité - Visible pour admins et trésoriers
- */
- public boolean isComptabiliteVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
- }
-
- /**
- * Trésorerie - Visible pour admins et trésoriers
- */
- public boolean isTresorerieVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
- }
-
- /**
- * Épargne/Crédit (spécifique mutuelles) - Visible pour trésoriers et responsables crédit
- */
- public boolean isEpargneCreditVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER", "RESPONSABLE_CREDIT");
- }
-
- /**
- * Inscription de membres - Visible pour admins et secrétaires
- */
- public boolean isInscriptionMembreVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
- }
-
- /**
- * Import/Export de membres - Visible pour admins et secrétaires
- */
- public boolean isImportExportMembreVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
- }
-
- /**
- * Validation des adhésions - Visible pour admins et secrétaires
- */
- public boolean isValidationAdhesionVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
- }
-
- /**
- * Traitement des demandes d'aide - Visible pour admins et responsables sociaux
- */
- public boolean isTraitementAideVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_SOCIAL");
- }
-
- /**
- * Évaluation sociale - Visible pour responsables sociaux
- */
- public boolean isEvaluationSocialeVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_SOCIAL");
- }
-
- /**
- * Création d'événements - Visible pour admins et responsables événements
- */
- public boolean isCreationEvenementVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_EVENEMENTS", "SECRETAIRE");
- }
-
- /**
- * Logistique événements - Visible pour responsables événements
- */
- public boolean isLogistiqueEvenementVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_EVENEMENTS");
- }
-
- /**
- * Envoi SMS/Email - Visible pour admins et secrétaires
- */
- public boolean isCommunicationMasseVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
- }
-
- /**
- * Sauvegardes et maintenance - Visible uniquement pour SUPER_ADMIN
- */
- public boolean isMaintenanceVisible() {
- return hasAnyRole("SUPER_ADMIN");
- }
-
- /**
- * Rapports financiers - Visible pour admins et trésoriers
- */
- public boolean isRapportFinancierVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
- }
-
- /**
- * Exports personnalisés - Visible pour admins, trésoriers, secrétaires
- */
- public boolean isExportsPersonnalisesVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER", "SECRETAIRE");
- }
-
- // ========================================================================
- // HELPERS
- // ========================================================================
-
- /**
- * Vérifie si l'utilisateur est un super-admin
- */
- public boolean isSuperAdmin() {
- return hasAnyRole("SUPER_ADMIN");
- }
-
- /**
- * Vérifie si l'utilisateur est un admin d'organisation
- */
- public boolean isAdminOrganisation() {
- return hasAnyRole("ADMIN_ORGANISATION");
- }
-
- /**
- * Vérifie si l'utilisateur est un trésorier
- */
- public boolean isTresorier() {
- return hasAnyRole("TRESORIER");
- }
-
- /**
- * Vérifie si l'utilisateur est un secrétaire
- */
- public boolean isSecretaire() {
- return hasAnyRole("SECRETAIRE");
- }
-
- /**
- * Vérifie si l'utilisateur est un responsable social
- */
- public boolean isResponsableSocial() {
- return hasAnyRole("RESPONSABLE_SOCIAL");
- }
-
- /**
- * Vérifie si l'utilisateur est un responsable événements
- */
- public boolean isResponsableEvenements() {
- return hasAnyRole("RESPONSABLE_EVENEMENTS");
- }
-
- /**
- * Vérifie si l'utilisateur est un responsable crédit
- */
- public boolean isResponsableCredit() {
- return hasAnyRole("RESPONSABLE_CREDIT");
- }
-
- /**
- * Vérifie si l'utilisateur est membre du bureau
- */
- public boolean isMembreBureau() {
- return hasAnyRole("MEMBRE_BUREAU");
- }
-
- /**
- * Vérifie si l'utilisateur est membre actif
- */
- public boolean isMembreActif() {
- return hasAnyRole("MEMBRE_ACTIF");
- }
-
- /**
- * Vérifie si l'utilisateur est membre simple
- */
- public boolean isMembreSimple() {
- return hasAnyRole("MEMBRE_SIMPLE");
- }
-
- // ========================================================================
- // MENUS PAR MODULE (conditionnels selon le type d'organisation active)
- // Chaque méthode combine : rôle requis + module actif dans l'org active.
- // Un SUPERADMIN voit tout sans restriction de module.
- // ========================================================================
-
- /**
- * Vérifie si un module est actif pour l'organisation courante.
- * Les SUPER_ADMIN voient tous les modules.
- */
- private boolean hasModule(String module) {
- if (hasAnyRole("SUPER_ADMIN")) return true;
- if (userSession == null) return false;
- return userSession.hasModuleActif(module);
- }
-
- /** Menu Tontine — visible si module TONTINE actif + rôle adéquat. */
- public boolean isTontineMenuVisible() {
- return hasModule("TONTINE") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER",
- "TONTINE_RESP", "TONTINE_MANAGER", "TONTINE_COLLECTOR");
- }
-
- /** Menu Tontine (membres) — consultation de ses propres tontines. */
- public boolean isTontineMemberVisible() {
- return hasModule("TONTINE") && !securityIdentity.isAnonymous();
- }
-
- /** Menu Épargne — visible si module EPARGNE actif. */
- public boolean isEpargneMenuVisible() {
- return hasModule("EPARGNE") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER",
- "MUTUELLE_RESP", "EPARGNE_MANAGER");
- }
-
- /** Menu Épargne (membres). */
- public boolean isEpargneMemberVisible() {
- return hasModule("EPARGNE") && !securityIdentity.isAnonymous();
- }
-
- /** Menu Crédit — visible si module CREDIT actif. */
- public boolean isCreditMenuVisible() {
- return hasModule("CREDIT") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER",
- "MUTUELLE_RESP", "CREDIT_ANALYSTE", "RESPONSABLE_CREDIT");
- }
-
- /** Menu Crédit (membres). */
- public boolean isCreditMemberVisible() {
- return hasModule("CREDIT") && !securityIdentity.isAnonymous();
- }
-
- /** Menu Agriculture / Campagnes — visible si module AGRICULTURE actif. */
- public boolean isAgricoleMenuVisible() {
- return hasModule("AGRICULTURE") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "COOP_RESP");
- }
-
- /** Menu Agriculture (membres). */
- public boolean isAgricoleMemberVisible() {
- return hasModule("AGRICULTURE") && !securityIdentity.isAnonymous();
- }
-
- /** Menu Collecte de fonds — visible si module COLLECTE_FONDS actif. */
- public boolean isCollecteFondsMenuVisible() {
- return hasModule("COLLECTE_FONDS") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "COLLECTE_RESP");
- }
-
- /** Menu Projets ONG — visible si module PROJETS_ONG actif. */
- public boolean isProjetOngMenuVisible() {
- return hasModule("PROJETS_ONG") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "ONG_RESP", "PROJET_MANAGER");
- }
-
- /** Menu Culte / Dons religieux — visible si module CULTE_DONS actif. */
- public boolean isCulteMenuVisible() {
- return hasModule("CULTE_DONS") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "CULTE_RESP", "PASTEUR", "DIACRE");
- }
-
- /** Menu Vote — visible si module VOTES actif. */
- public boolean isVoteMenuVisible() {
- return hasModule("VOTES") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "VOTE_RESP", "SCRUTATEUR");
- }
-
- /** Menu Registre / Agrément — visible si module REGISTRE_AGREMENT actif. */
- public boolean isRegistreAgrementMenuVisible() {
- return hasModule("REGISTRE_AGREMENT") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "REGISTRE_RESP");
- }
-
- /** Menu Gouvernance / Organigramme — visible si module GOUVERNANCE actif. */
- public boolean isGouvernanceMenuVisible() {
- return hasModule("GOUVERNANCE") &&
- hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION");
- }
-
- /**
- * Retourne true si l'organisation active dispose d'au moins un module métier spécifique
- * (au-delà des modules communs toujours disponibles).
- * Utilisé pour afficher/masquer la section "Modules métier" dans la navigation.
- */
- public boolean hasAnyBusinessModule() {
- if (hasAnyRole("SUPER_ADMIN")) return true;
- return isTontineMenuVisible() || isCreditMenuVisible() || isEpargneMenuVisible()
- || isAgricoleMenuVisible() || isCollecteFondsMenuVisible()
- || isProjetOngMenuVisible() || isCulteMenuVisible()
- || isVoteMenuVisible() || isRegistreAgrementMenuVisible()
- || isGouvernanceMenuVisible();
- }
-}
+package dev.lions.unionflow.client.bean;
+
+import dev.lions.unionflow.client.view.UserSession;
+import jakarta.enterprise.context.SessionScoped;
+import jakarta.inject.Named;
+import io.quarkus.security.identity.SecurityIdentity;
+import jakarta.inject.Inject;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * Bean de gestion de la visibilité des menus en fonction des rôles utilisateur.
+ *
+ * Fournit des méthodes utilitaires pour déterminer quels menus afficher
+ * selon le rôle de l'utilisateur connecté et le type de son organisation.
+ *
+ *
Utilise {@link SecurityIdentity} pour l'authentification OIDC en mode web-app,
+ * en cohérence avec {@link dev.lions.unionflow.client.view.LoginBean}.
+ *
+ * @author UnionFlow Team
+ * @version 1.1
+ * @since 2026-03-01
+ */
+@Named
+@SessionScoped
+public class MenuBean implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Inject
+ SecurityIdentity securityIdentity;
+
+ @Inject
+ UserSession userSession;
+
+ /**
+ * Vérifie si l'utilisateur a au moins un des rôles spécifiés.
+ *
+ * @param roles Les rôles à vérifier
+ * @return true si l'utilisateur possède au moins un des rôles, false sinon
+ */
+ private boolean hasAnyRole(String... roles) {
+ if (securityIdentity == null || securityIdentity.isAnonymous()) {
+ return false;
+ }
+
+ Set userRoles = securityIdentity.getRoles();
+ if (userRoles == null || userRoles.isEmpty()) {
+ return false;
+ }
+
+ for (String role : roles) {
+ if (userRoles.contains(role)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // ========================================================================
+ // MENUS PRINCIPAUX - Visibilité par rôle
+ // ========================================================================
+
+ /**
+ * Super Administration - Visible uniquement pour SUPER_ADMIN
+ */
+ public boolean isSuperAdminMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN");
+ }
+
+ /**
+ * Administration - Visible pour admins et secrétaires
+ */
+ public boolean isAdministrationMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU");
+ }
+
+ // ========================================================================
+ // NOUVEAUX MENUS PERSONNELS - Visible pour TOUS les membres
+ // ========================================================================
+
+ /**
+ * Mes Finances - Menu personnel pour consulter/gérer ses propres finances
+ * Visible pour TOUS les membres (épargne, cotisations, prêts)
+ */
+ public boolean isMesFinancesMenuVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Événements - Calendrier et inscriptions aux événements
+ * Visible pour TOUS les membres
+ */
+ public boolean isMesEvenementsMenuVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Mes Demandes d'Aide Sociale - Menu personnel pour les demandes d'aide
+ * Visible pour TOUS les membres
+ */
+ public boolean isMesAidesSocialesMenuVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Mes Formations - Catalogue et inscriptions aux formations
+ * Visible pour TOUS les membres
+ */
+ public boolean isMesFormationsMenuVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Mes Communications - Messages et notifications personnelles
+ * Visible pour TOUS les membres
+ */
+ public boolean isMesCommunicationsMenuVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ // ========================================================================
+ // MENUS DE GESTION - Visible pour les responsables uniquement
+ // ========================================================================
+
+ /**
+ * Gestion des Membres - Administration des membres
+ * Visible pour SECRETAIRE et ADMIN uniquement
+ */
+ public boolean isGestionMembresMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
+ }
+
+ /**
+ * Annuaire des Membres - Consultation de la liste (pas de modification)
+ * Visible pour les responsables et bureau SEULEMENT (PAS pour MEMBRE_ACTIF)
+ *
+ * Raison métier: Un membre simple n'a généralement pas besoin de voir la liste complète
+ * des autres membres. Cela peut poser des problèmes de:
+ * - RGPD: Exposition non justifiée de données personnelles
+ * - Sécurité: Risque de spam/phishing entre membres
+ * - UX: Surcharge du menu pour un usage limité
+ *
+ * Si l'organisation souhaite activer l'annuaire pour MEMBRE_ACTIF, cela doit être
+ * fait via configuration explicite (future Phase 3).
+ */
+ public boolean isAnnuaireMembresVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "TRESORIER",
+ "RESPONSABLE_SOCIAL", "RESPONSABLE_EVENEMENTS", "RESPONSABLE_CREDIT",
+ "MEMBRE_BUREAU");
+ // MEMBRE_ACTIF retiré intentionnellement pour raisons UX et RGPD
+ }
+
+ /**
+ * Gestion Financière - Administration finances (trésorerie, budgets, comptabilité)
+ * Visible pour TRESORIER et ADMIN uniquement
+ */
+ public boolean isGestionFinancesMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
+ }
+
+ /**
+ * Gestion Événements - Création et organisation des événements
+ * Visible pour RESPONSABLE_EVENEMENTS, SECRETAIRE et ADMIN
+ */
+ public boolean isGestionEvenementsMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "RESPONSABLE_EVENEMENTS");
+ }
+
+ /**
+ * Gestion Aide Sociale - Traitement des demandes d'aide
+ * Visible pour RESPONSABLE_SOCIAL et ADMIN
+ */
+ public boolean isGestionAidesSocialesMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_SOCIAL");
+ }
+
+ /**
+ * Organisations - Visible pour admins et super-admins
+ */
+ public boolean isOrganisationsMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION");
+ }
+
+ /**
+ * Adhésions - Visible pour admins, secrétaires, bureau
+ */
+ public boolean isAdhesionsMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU");
+ }
+
+ /**
+ * Communication - Visible pour admins, secrétaires, bureau
+ */
+ public boolean isCommunicationMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "RESPONSABLE_EVENEMENTS", "MEMBRE_BUREAU");
+ }
+
+ /**
+ * Documents - Visible pour tous sauf membres simples
+ */
+ public boolean isDocumentsMenuVisible() {
+ return !hasAnyRole("MEMBRE_SIMPLE");
+ }
+
+ /**
+ * Formation - Visible pour tous les membres actifs et plus
+ */
+ public boolean isFormationMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU", "MEMBRE_ACTIF");
+ }
+
+ /**
+ * Rapports et Analyses - Visible pour admins, trésoriers, secrétaires, bureau
+ */
+ public boolean isRapportsMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER", "SECRETAIRE", "MEMBRE_BUREAU");
+ }
+
+ /**
+ * Outils et Utilitaires - Visible pour admins et secrétaires
+ */
+ public boolean isOutilsMenuVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU");
+ }
+
+ /**
+ * Mon Espace Personnel - Visible pour tous les utilisateurs connectés
+ */
+ public boolean isPersonnelMenuVisible() {
+ return true; // Tous les utilisateurs connectés
+ }
+
+ /**
+ * Aide et Support - Visible pour tous
+ */
+ public boolean isAideMenuVisible() {
+ return true; // Tous les utilisateurs
+ }
+
+ // ========================================================================
+ // ITEMS DE MENUS PERSONNELS - Actions membre
+ // ========================================================================
+
+ /**
+ * Consulter mon épargne - Visible pour TOUS
+ */
+ public boolean isMonEpargneVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Payer mes cotisations - Visible pour TOUS
+ */
+ public boolean isPaiementCotisationVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Demander un prêt/crédit - Visible pour TOUS
+ */
+ public boolean isDemandePretVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Mes prêts en cours - Visible pour TOUS
+ */
+ public boolean isMesPretsVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Demander une aide sociale - Visible pour TOUS
+ */
+ public boolean isDemandeAideSocialeVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Mes demandes d'aide en cours - Visible pour TOUS
+ */
+ public boolean isMesDemandesAideVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * M'inscrire à un événement - Visible pour TOUS
+ */
+ public boolean isInscriptionEvenementVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Mes inscriptions aux événements - Visible pour TOUS
+ */
+ public boolean isMesInscriptionsEvenementsVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * M'inscrire à une formation - Visible pour TOUS
+ */
+ public boolean isInscriptionFormationVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Mes formations - Visible pour TOUS
+ */
+ public boolean isMesFormationsVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Mes messages personnels - Visible pour TOUS
+ */
+ public boolean isMesMessagesVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ /**
+ * Annonces officielles (lecture seule) - Visible pour TOUS
+ */
+ public boolean isAnnoncesLectureVisible() {
+ return !securityIdentity.isAnonymous();
+ }
+
+ // ========================================================================
+ // ITEMS DE MENUS SPÉCIFIQUES - Administration
+ // ========================================================================
+
+ /**
+ * Items Keycloak User Manager - Visible uniquement pour SUPER_ADMIN
+ */
+ public boolean isKeycloakUserManagerVisible() {
+ return hasAnyRole("SUPER_ADMIN");
+ }
+
+ /**
+ * Gestion des cotisations (admin) - Visible pour admins et trésoriers
+ */
+ public boolean isCotisationsAdminVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
+ }
+
+ /**
+ * Comptabilité - Visible pour admins et trésoriers
+ */
+ public boolean isComptabiliteVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
+ }
+
+ /**
+ * Trésorerie - Visible pour admins et trésoriers
+ */
+ public boolean isTresorerieVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
+ }
+
+ /**
+ * Épargne/Crédit (spécifique mutuelles) - Visible pour trésoriers et responsables crédit
+ */
+ public boolean isEpargneCreditVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER", "RESPONSABLE_CREDIT");
+ }
+
+ /**
+ * Inscription de membres - Visible pour admins et secrétaires
+ */
+ public boolean isInscriptionMembreVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
+ }
+
+ /**
+ * Import/Export de membres - Visible pour admins et secrétaires
+ */
+ public boolean isImportExportMembreVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
+ }
+
+ /**
+ * Validation des adhésions - Visible pour admins et secrétaires
+ */
+ public boolean isValidationAdhesionVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
+ }
+
+ /**
+ * Traitement des demandes d'aide - Visible pour admins et responsables sociaux
+ */
+ public boolean isTraitementAideVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_SOCIAL");
+ }
+
+ /**
+ * Évaluation sociale - Visible pour responsables sociaux
+ */
+ public boolean isEvaluationSocialeVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_SOCIAL");
+ }
+
+ /**
+ * Création d'événements - Visible pour admins et responsables événements
+ */
+ public boolean isCreationEvenementVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_EVENEMENTS", "SECRETAIRE");
+ }
+
+ /**
+ * Logistique événements - Visible pour responsables événements
+ */
+ public boolean isLogistiqueEvenementVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_EVENEMENTS");
+ }
+
+ /**
+ * Envoi SMS/Email - Visible pour admins et secrétaires
+ */
+ public boolean isCommunicationMasseVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE");
+ }
+
+ /**
+ * Sauvegardes et maintenance - Visible uniquement pour SUPER_ADMIN
+ */
+ public boolean isMaintenanceVisible() {
+ return hasAnyRole("SUPER_ADMIN");
+ }
+
+ /**
+ * Rapports financiers - Visible pour admins et trésoriers
+ */
+ public boolean isRapportFinancierVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER");
+ }
+
+ /**
+ * Exports personnalisés - Visible pour admins, trésoriers, secrétaires
+ */
+ public boolean isExportsPersonnalisesVisible() {
+ return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER", "SECRETAIRE");
+ }
+
+ // ========================================================================
+ // HELPERS
+ // ========================================================================
+
+ /**
+ * Vérifie si l'utilisateur est un super-admin
+ */
+ public boolean isSuperAdmin() {
+ return hasAnyRole("SUPER_ADMIN");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est un admin d'organisation
+ */
+ public boolean isAdminOrganisation() {
+ return hasAnyRole("ADMIN_ORGANISATION");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est un trésorier
+ */
+ public boolean isTresorier() {
+ return hasAnyRole("TRESORIER");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est un secrétaire
+ */
+ public boolean isSecretaire() {
+ return hasAnyRole("SECRETAIRE");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est un responsable social
+ */
+ public boolean isResponsableSocial() {
+ return hasAnyRole("RESPONSABLE_SOCIAL");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est un responsable événements
+ */
+ public boolean isResponsableEvenements() {
+ return hasAnyRole("RESPONSABLE_EVENEMENTS");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est un responsable crédit
+ */
+ public boolean isResponsableCredit() {
+ return hasAnyRole("RESPONSABLE_CREDIT");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est membre du bureau
+ */
+ public boolean isMembreBureau() {
+ return hasAnyRole("MEMBRE_BUREAU");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est membre actif
+ */
+ public boolean isMembreActif() {
+ return hasAnyRole("MEMBRE_ACTIF");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est membre simple
+ */
+ public boolean isMembreSimple() {
+ return hasAnyRole("MEMBRE_SIMPLE");
+ }
+
+ // ========================================================================
+ // MENUS PAR MODULE (conditionnels selon le type d'organisation active)
+ // Chaque méthode combine : rôle requis + module actif dans l'org active.
+ // Un SUPERADMIN voit tout sans restriction de module.
+ // ========================================================================
+
+ /**
+ * Vérifie si un module est actif pour l'organisation courante.
+ * Les SUPER_ADMIN voient tous les modules.
+ */
+ private boolean hasModule(String module) {
+ if (hasAnyRole("SUPER_ADMIN")) return true;
+ if (userSession == null) return false;
+ return userSession.hasModuleActif(module);
+ }
+
+ /** Menu Tontine — visible si module TONTINE actif + rôle adéquat. */
+ public boolean isTontineMenuVisible() {
+ return hasModule("TONTINE") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER",
+ "TONTINE_RESP", "TONTINE_MANAGER", "TONTINE_COLLECTOR");
+ }
+
+ /** Menu Tontine (membres) — consultation de ses propres tontines. */
+ public boolean isTontineMemberVisible() {
+ return hasModule("TONTINE") && !securityIdentity.isAnonymous();
+ }
+
+ /** Menu Épargne — visible si module EPARGNE actif. */
+ public boolean isEpargneMenuVisible() {
+ return hasModule("EPARGNE") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER",
+ "MUTUELLE_RESP", "EPARGNE_MANAGER");
+ }
+
+ /** Menu Épargne (membres). */
+ public boolean isEpargneMemberVisible() {
+ return hasModule("EPARGNE") && !securityIdentity.isAnonymous();
+ }
+
+ /** Menu Crédit — visible si module CREDIT actif. */
+ public boolean isCreditMenuVisible() {
+ return hasModule("CREDIT") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER",
+ "MUTUELLE_RESP", "CREDIT_ANALYSTE", "RESPONSABLE_CREDIT");
+ }
+
+ /** Menu Crédit (membres). */
+ public boolean isCreditMemberVisible() {
+ return hasModule("CREDIT") && !securityIdentity.isAnonymous();
+ }
+
+ /** Menu Agriculture / Campagnes — visible si module AGRICULTURE actif. */
+ public boolean isAgricoleMenuVisible() {
+ return hasModule("AGRICULTURE") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "COOP_RESP");
+ }
+
+ /** Menu Agriculture (membres). */
+ public boolean isAgricoleMemberVisible() {
+ return hasModule("AGRICULTURE") && !securityIdentity.isAnonymous();
+ }
+
+ /** Menu Collecte de fonds — visible si module COLLECTE_FONDS actif. */
+ public boolean isCollecteFondsMenuVisible() {
+ return hasModule("COLLECTE_FONDS") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "COLLECTE_RESP");
+ }
+
+ /** Menu Projets ONG — visible si module PROJETS_ONG actif. */
+ public boolean isProjetOngMenuVisible() {
+ return hasModule("PROJETS_ONG") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "ONG_RESP", "PROJET_MANAGER");
+ }
+
+ /** Menu Culte / Dons religieux — visible si module CULTE_DONS actif. */
+ public boolean isCulteMenuVisible() {
+ return hasModule("CULTE_DONS") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "CULTE_RESP", "PASTEUR", "DIACRE");
+ }
+
+ /** Menu Vote — visible si module VOTES actif. */
+ public boolean isVoteMenuVisible() {
+ return hasModule("VOTES") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "VOTE_RESP", "SCRUTATEUR");
+ }
+
+ /** Menu Registre / Agrément — visible si module REGISTRE_AGREMENT actif. */
+ public boolean isRegistreAgrementMenuVisible() {
+ return hasModule("REGISTRE_AGREMENT") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "REGISTRE_RESP");
+ }
+
+ /** Menu Gouvernance / Organigramme — visible si module GOUVERNANCE actif. */
+ public boolean isGouvernanceMenuVisible() {
+ return hasModule("GOUVERNANCE") &&
+ hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION");
+ }
+
+ /**
+ * Retourne true si l'organisation active dispose d'au moins un module métier spécifique
+ * (au-delà des modules communs toujours disponibles).
+ * Utilisé pour afficher/masquer la section "Modules métier" dans la navigation.
+ */
+ public boolean hasAnyBusinessModule() {
+ if (hasAnyRole("SUPER_ADMIN")) return true;
+ return isTontineMenuVisible() || isCreditMenuVisible() || isEpargneMenuVisible()
+ || isAgricoleMenuVisible() || isCollecteFondsMenuVisible()
+ || isProjetOngMenuVisible() || isCulteMenuVisible()
+ || isVoteMenuVisible() || isRegistreAgrementMenuVisible()
+ || isGouvernanceMenuVisible();
+ }
+}
diff --git a/src/main/java/dev/lions/unionflow/client/bean/PageSecurityBean.java b/src/main/java/dev/lions/unionflow/client/bean/PageSecurityBean.java
index 514efdc..4564a21 100644
--- a/src/main/java/dev/lions/unionflow/client/bean/PageSecurityBean.java
+++ b/src/main/java/dev/lions/unionflow/client/bean/PageSecurityBean.java
@@ -1,179 +1,179 @@
-package dev.lions.unionflow.client.bean;
-
-import io.quarkus.security.identity.SecurityIdentity;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.faces.context.FacesContext;
-import jakarta.inject.Inject;
-import jakarta.inject.Named;
-import org.jboss.logging.Logger;
-
-import java.io.IOException;
-
-/**
- * Bean centralisé pour la sécurisation des pages basée sur les rôles.
- * Fournit des méthodes réutilisables pour vérifier l'accès et rediriger si nécessaire.
- *
- * Principe DRY/WOU : Une seule implémentation de la logique de sécurité,
- * réutilisée par toutes les pages via un composant Facelet.
- *
- * @author UnionFlow Team
- * @version 1.0
- * @since 2026-03-02
- */
-@Named("pageSecurityBean")
-@ApplicationScoped
-public class PageSecurityBean {
-
- private static final Logger LOG = Logger.getLogger(PageSecurityBean.class);
- private static final String ACCESS_DENIED_PAGE = "/pages/secure/access-denied.xhtml";
-
- @Inject
- SecurityIdentity securityIdentity;
-
- @Inject
- MenuBean menuBean;
-
- /**
- * Vérifie si l'utilisateur a le droit d'accéder à une page donnée.
- * Si non autorisé, redirige vers la page access-denied.
- *
- * @param allowedRoles Rôles autorisés séparés par des virgules (ex: "ADMIN,TRESORIER")
- * @return true si autorisé, false sinon (après redirection)
- */
- public boolean checkAccessOrRedirect(String allowedRoles) {
- if (allowedRoles == null || allowedRoles.trim().isEmpty()) {
- // Aucune restriction = accès autorisé pour tous les utilisateurs authentifiés
- return !securityIdentity.isAnonymous();
- }
-
- String[] roles = allowedRoles.split(",");
- boolean hasAccess = false;
-
- for (String role : roles) {
- String trimmedRole = role.trim();
- if (hasRole(trimmedRole)) {
- hasAccess = true;
- break;
- }
- }
-
- if (!hasAccess) {
- LOG.warnf("Accès refusé pour l'utilisateur %s à une page nécessitant les rôles: %s",
- securityIdentity.getPrincipal().getName(), allowedRoles);
- redirectToAccessDenied();
- return false;
- }
-
- return true;
- }
-
- /**
- * Vérifie si l'utilisateur possède un rôle spécifique.
- *
- * @param role Le rôle à vérifier
- * @return true si l'utilisateur a ce rôle
- */
- private boolean hasRole(String role) {
- return switch (role) {
- case "SUPER_ADMIN" -> menuBean.isSuperAdmin();
- case "ADMIN_ORGANISATION", "ADMIN" -> menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "TRESORIER" -> menuBean.isTresorier() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "SECRETAIRE" -> menuBean.isSecretaire() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "RESPONSABLE_SOCIAL" -> menuBean.isResponsableSocial() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "RESPONSABLE_EVENEMENTS" -> menuBean.isResponsableEvenements() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "RESPONSABLE_CREDIT" -> menuBean.isResponsableCredit() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "MEMBRE_BUREAU" -> menuBean.isMembreBureau() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "MEMBRE_ACTIF" -> menuBean.isMembreActif() || menuBean.isMembreBureau() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "MEMBRE_SIMPLE" -> menuBean.isMembreSimple() || menuBean.isMembreActif() || menuBean.isMembreBureau() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
- case "ALL" -> !securityIdentity.isAnonymous(); // Tous les utilisateurs authentifiés
- default -> {
- LOG.warnf("Rôle inconnu: %s", role);
- yield false;
- }
- };
- }
-
- /**
- * Redirige vers la page d'accès refusé.
- */
- private void redirectToAccessDenied() {
- try {
- FacesContext ctx = FacesContext.getCurrentInstance();
- if (ctx != null && !ctx.getResponseComplete()) {
- String contextPath = ctx.getExternalContext().getRequestContextPath();
- ctx.getExternalContext().redirect(contextPath + ACCESS_DENIED_PAGE);
- ctx.responseComplete();
- }
- } catch (IOException e) {
- LOG.error("Erreur lors de la redirection vers access-denied", e);
- }
- }
-
- // ═══════════════════════════════════════════════════════════════════════
- // Méthodes helper pour vérifications rapides (utilisées dans les pages)
- // ═══════════════════════════════════════════════════════════════════════
-
- /**
- * Vérifie si l'utilisateur peut gérer les membres.
- * @return true si SECRETAIRE, ADMIN, ou SUPER_ADMIN
- */
- public boolean canManageMembers() {
- return hasRole("SECRETAIRE");
- }
-
- /**
- * Vérifie si l'utilisateur peut gérer les finances.
- * @return true si TRESORIER, ADMIN, ou SUPER_ADMIN
- */
- public boolean canManageFinances() {
- return hasRole("TRESORIER");
- }
-
- /**
- * Vérifie si l'utilisateur peut gérer les événements.
- * @return true si RESPONSABLE_EVENEMENTS, SECRETAIRE, ADMIN, ou SUPER_ADMIN
- */
- public boolean canManageEvents() {
- return hasRole("RESPONSABLE_EVENEMENTS");
- }
-
- /**
- * Vérifie si l'utilisateur peut gérer les aides sociales.
- * @return true si RESPONSABLE_SOCIAL, ADMIN, ou SUPER_ADMIN
- */
- public boolean canManageSocialAid() {
- return hasRole("RESPONSABLE_SOCIAL");
- }
-
- /**
- * Vérifie si l'utilisateur peut voir les rapports financiers.
- * @return true si TRESORIER, SECRETAIRE, ADMIN, ou SUPER_ADMIN
- */
- public boolean canViewFinancialReports() {
- return hasRole("TRESORIER") || hasRole("SECRETAIRE");
- }
-
- /**
- * Vérifie si l'utilisateur peut exporter des données.
- * @return true si TRESORIER, SECRETAIRE, ADMIN, ou SUPER_ADMIN
- */
- public boolean canExportData() {
- return hasRole("TRESORIER") || hasRole("SECRETAIRE");
- }
-
- /**
- * Vérifie si l'utilisateur est un simple membre (MEMBRE_ACTIF uniquement).
- * @return true si MEMBRE_ACTIF mais pas d'autre rôle administratif
- */
- public boolean isSimpleMember() {
- return menuBean.isMembreActif() &&
- !menuBean.isSecretaire() &&
- !menuBean.isTresorier() &&
- !menuBean.isResponsableSocial() &&
- !menuBean.isResponsableEvenements() &&
- !menuBean.isResponsableCredit() &&
- !menuBean.isMembreBureau() &&
- !menuBean.isAdminOrganisation() &&
- !menuBean.isSuperAdmin();
- }
-}
+package dev.lions.unionflow.client.bean;
+
+import io.quarkus.security.identity.SecurityIdentity;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.faces.context.FacesContext;
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+import org.jboss.logging.Logger;
+
+import java.io.IOException;
+
+/**
+ * Bean centralisé pour la sécurisation des pages basée sur les rôles.
+ * Fournit des méthodes réutilisables pour vérifier l'accès et rediriger si nécessaire.
+ *
+ *
Principe DRY/WOU : Une seule implémentation de la logique de sécurité,
+ * réutilisée par toutes les pages via un composant Facelet.
+ *
+ * @author UnionFlow Team
+ * @version 1.0
+ * @since 2026-03-02
+ */
+@Named("pageSecurityBean")
+@ApplicationScoped
+public class PageSecurityBean {
+
+ private static final Logger LOG = Logger.getLogger(PageSecurityBean.class);
+ private static final String ACCESS_DENIED_PAGE = "/pages/secure/access-denied.xhtml";
+
+ @Inject
+ SecurityIdentity securityIdentity;
+
+ @Inject
+ MenuBean menuBean;
+
+ /**
+ * Vérifie si l'utilisateur a le droit d'accéder à une page donnée.
+ * Si non autorisé, redirige vers la page access-denied.
+ *
+ * @param allowedRoles Rôles autorisés séparés par des virgules (ex: "ADMIN,TRESORIER")
+ * @return true si autorisé, false sinon (après redirection)
+ */
+ public boolean checkAccessOrRedirect(String allowedRoles) {
+ if (allowedRoles == null || allowedRoles.trim().isEmpty()) {
+ // Aucune restriction = accès autorisé pour tous les utilisateurs authentifiés
+ return !securityIdentity.isAnonymous();
+ }
+
+ String[] roles = allowedRoles.split(",");
+ boolean hasAccess = false;
+
+ for (String role : roles) {
+ String trimmedRole = role.trim();
+ if (hasRole(trimmedRole)) {
+ hasAccess = true;
+ break;
+ }
+ }
+
+ if (!hasAccess) {
+ LOG.warnf("Accès refusé pour l'utilisateur %s à une page nécessitant les rôles: %s",
+ securityIdentity.getPrincipal().getName(), allowedRoles);
+ redirectToAccessDenied();
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Vérifie si l'utilisateur possède un rôle spécifique.
+ *
+ * @param role Le rôle à vérifier
+ * @return true si l'utilisateur a ce rôle
+ */
+ private boolean hasRole(String role) {
+ return switch (role) {
+ case "SUPER_ADMIN" -> menuBean.isSuperAdmin();
+ case "ADMIN_ORGANISATION", "ADMIN" -> menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "TRESORIER" -> menuBean.isTresorier() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "SECRETAIRE" -> menuBean.isSecretaire() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "RESPONSABLE_SOCIAL" -> menuBean.isResponsableSocial() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "RESPONSABLE_EVENEMENTS" -> menuBean.isResponsableEvenements() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "RESPONSABLE_CREDIT" -> menuBean.isResponsableCredit() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "MEMBRE_BUREAU" -> menuBean.isMembreBureau() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "MEMBRE_ACTIF" -> menuBean.isMembreActif() || menuBean.isMembreBureau() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "MEMBRE_SIMPLE" -> menuBean.isMembreSimple() || menuBean.isMembreActif() || menuBean.isMembreBureau() || menuBean.isAdminOrganisation() || menuBean.isSuperAdmin();
+ case "ALL" -> !securityIdentity.isAnonymous(); // Tous les utilisateurs authentifiés
+ default -> {
+ LOG.warnf("Rôle inconnu: %s", role);
+ yield false;
+ }
+ };
+ }
+
+ /**
+ * Redirige vers la page d'accès refusé.
+ */
+ private void redirectToAccessDenied() {
+ try {
+ FacesContext ctx = FacesContext.getCurrentInstance();
+ if (ctx != null && !ctx.getResponseComplete()) {
+ String contextPath = ctx.getExternalContext().getRequestContextPath();
+ ctx.getExternalContext().redirect(contextPath + ACCESS_DENIED_PAGE);
+ ctx.responseComplete();
+ }
+ } catch (IOException e) {
+ LOG.error("Erreur lors de la redirection vers access-denied", e);
+ }
+ }
+
+ // ═══════════════════════════════════════════════════════════════════════
+ // Méthodes helper pour vérifications rapides (utilisées dans les pages)
+ // ═══════════════════════════════════════════════════════════════════════
+
+ /**
+ * Vérifie si l'utilisateur peut gérer les membres.
+ * @return true si SECRETAIRE, ADMIN, ou SUPER_ADMIN
+ */
+ public boolean canManageMembers() {
+ return hasRole("SECRETAIRE");
+ }
+
+ /**
+ * Vérifie si l'utilisateur peut gérer les finances.
+ * @return true si TRESORIER, ADMIN, ou SUPER_ADMIN
+ */
+ public boolean canManageFinances() {
+ return hasRole("TRESORIER");
+ }
+
+ /**
+ * Vérifie si l'utilisateur peut gérer les événements.
+ * @return true si RESPONSABLE_EVENEMENTS, SECRETAIRE, ADMIN, ou SUPER_ADMIN
+ */
+ public boolean canManageEvents() {
+ return hasRole("RESPONSABLE_EVENEMENTS");
+ }
+
+ /**
+ * Vérifie si l'utilisateur peut gérer les aides sociales.
+ * @return true si RESPONSABLE_SOCIAL, ADMIN, ou SUPER_ADMIN
+ */
+ public boolean canManageSocialAid() {
+ return hasRole("RESPONSABLE_SOCIAL");
+ }
+
+ /**
+ * Vérifie si l'utilisateur peut voir les rapports financiers.
+ * @return true si TRESORIER, SECRETAIRE, ADMIN, ou SUPER_ADMIN
+ */
+ public boolean canViewFinancialReports() {
+ return hasRole("TRESORIER") || hasRole("SECRETAIRE");
+ }
+
+ /**
+ * Vérifie si l'utilisateur peut exporter des données.
+ * @return true si TRESORIER, SECRETAIRE, ADMIN, ou SUPER_ADMIN
+ */
+ public boolean canExportData() {
+ return hasRole("TRESORIER") || hasRole("SECRETAIRE");
+ }
+
+ /**
+ * Vérifie si l'utilisateur est un simple membre (MEMBRE_ACTIF uniquement).
+ * @return true si MEMBRE_ACTIF mais pas d'autre rôle administratif
+ */
+ public boolean isSimpleMember() {
+ return menuBean.isMembreActif() &&
+ !menuBean.isSecretaire() &&
+ !menuBean.isTresorier() &&
+ !menuBean.isResponsableSocial() &&
+ !menuBean.isResponsableEvenements() &&
+ !menuBean.isResponsableCredit() &&
+ !menuBean.isMembreBureau() &&
+ !menuBean.isAdminOrganisation() &&
+ !menuBean.isSuperAdmin();
+ }
+}
diff --git a/src/main/java/dev/lions/unionflow/client/converter/UuidConverter.java b/src/main/java/dev/lions/unionflow/client/converter/UuidConverter.java
index f890da8..b3df4bf 100644
--- a/src/main/java/dev/lions/unionflow/client/converter/UuidConverter.java
+++ b/src/main/java/dev/lions/unionflow/client/converter/UuidConverter.java
@@ -1,37 +1,37 @@
-package dev.lions.unionflow.client.converter;
-
-import jakarta.faces.component.UIComponent;
-import jakarta.faces.context.FacesContext;
-import jakarta.faces.convert.Converter;
-import jakarta.faces.convert.ConverterException;
-import jakarta.faces.convert.FacesConverter;
-
-import java.util.UUID;
-
-/**
- * Convertisseur JSF pour les paramètres de vue et champs liés à {@link UUID}.
- * Permet la conversion String ↔ UUID dans les f:viewParam et composants d'entrée.
- */
-@FacesConverter(value = "uuidConverter", managed = true)
-public class UuidConverter implements Converter {
-
- @Override
- public UUID getAsObject(FacesContext context, UIComponent component, String value) {
- if (value == null || value.isBlank()) {
- return null;
- }
- try {
- return UUID.fromString(value.trim());
- } catch (IllegalArgumentException e) {
- throw new ConverterException("Identifiant invalide : " + value, e);
- }
- }
-
- @Override
- public String getAsString(FacesContext context, UIComponent component, UUID value) {
- if (value == null) {
- return "";
- }
- return value.toString();
- }
-}
+package dev.lions.unionflow.client.converter;
+
+import jakarta.faces.component.UIComponent;
+import jakarta.faces.context.FacesContext;
+import jakarta.faces.convert.Converter;
+import jakarta.faces.convert.ConverterException;
+import jakarta.faces.convert.FacesConverter;
+
+import java.util.UUID;
+
+/**
+ * Convertisseur JSF pour les paramètres de vue et champs liés à {@link UUID}.
+ * Permet la conversion String ↔ UUID dans les f:viewParam et composants d'entrée.
+ */
+@FacesConverter(value = "uuidConverter", managed = true)
+public class UuidConverter implements Converter {
+
+ @Override
+ public UUID getAsObject(FacesContext context, UIComponent component, String value) {
+ if (value == null || value.isBlank()) {
+ return null;
+ }
+ try {
+ return UUID.fromString(value.trim());
+ } catch (IllegalArgumentException e) {
+ throw new ConverterException("Identifiant invalide : " + value, e);
+ }
+ }
+
+ @Override
+ public String getAsString(FacesContext context, UIComponent component, UUID value) {
+ if (value == null) {
+ return "";
+ }
+ return value.toString();
+ }
+}
diff --git a/src/main/java/dev/lions/unionflow/client/service/MembreDashboardRestClient.java b/src/main/java/dev/lions/unionflow/client/service/MembreDashboardRestClient.java
index 779ab0f..2f3b90a 100644
--- a/src/main/java/dev/lions/unionflow/client/service/MembreDashboardRestClient.java
+++ b/src/main/java/dev/lions/unionflow/client/service/MembreDashboardRestClient.java
@@ -1,23 +1,23 @@
-package dev.lions.unionflow.client.service;
-
-import dev.lions.unionflow.client.api.dto.MembreDashboardResponse;
-import dev.lions.unionflow.client.security.AuthHeaderFactory;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
-import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
-
-@RegisterRestClient(configKey = "unionflow-api")
-@RegisterClientHeaders(AuthHeaderFactory.class)
-@Path("/api/dashboard/membre")
-@Consumes(MediaType.APPLICATION_JSON)
-@Produces(MediaType.APPLICATION_JSON)
-public interface MembreDashboardRestClient {
-
- @GET
- @Path("/me")
- MembreDashboardResponse getMonDashboard();
-}
+package dev.lions.unionflow.client.service;
+
+import dev.lions.unionflow.client.api.dto.MembreDashboardResponse;
+import dev.lions.unionflow.client.security.AuthHeaderFactory;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
+import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
+
+@RegisterRestClient(configKey = "unionflow-api")
+@RegisterClientHeaders(AuthHeaderFactory.class)
+@Path("/api/dashboard/membre")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public interface MembreDashboardRestClient {
+
+ @GET
+ @Path("/me")
+ MembreDashboardResponse getMonDashboard();
+}
diff --git a/src/main/java/dev/lions/unionflow/client/view/MesCotisationsPaiementBean.java b/src/main/java/dev/lions/unionflow/client/view/MesCotisationsPaiementBean.java
index 88c49c1..5a2b7a3 100644
--- a/src/main/java/dev/lions/unionflow/client/view/MesCotisationsPaiementBean.java
+++ b/src/main/java/dev/lions/unionflow/client/view/MesCotisationsPaiementBean.java
@@ -1,648 +1,648 @@
-package dev.lions.unionflow.client.view;
-
-import dev.lions.unionflow.server.api.dto.cotisation.response.CotisationResponse;
-import dev.lions.unionflow.server.api.dto.membre.response.MembreResponse;
-import dev.lions.unionflow.server.api.dto.paiement.response.PaiementResponse;
-import dev.lions.unionflow.client.service.CotisationService;
-import dev.lions.unionflow.client.service.ErrorHandlerService;
-import dev.lions.unionflow.client.service.ExportClientService;
-import dev.lions.unionflow.client.service.MembreService;
-import dev.lions.unionflow.client.service.RetryService;
-import io.quarkus.security.identity.SecurityIdentity;
-import jakarta.annotation.PostConstruct;
-import jakarta.faces.context.ExternalContext;
-import jakarta.faces.view.ViewScoped;
-import jakarta.inject.Inject;
-import jakarta.inject.Named;
-import org.eclipse.microprofile.rest.client.inject.RestClient;
-import org.jboss.logging.Logger;
-
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-/**
- * Bean pour le paiement des cotisations du membre connecté (MEMBRE_ACTIF).
- * Affiche uniquement les cotisations personnelles, pas les données admin.
- *
- * Pattern DRY: Réutilise la logique de MembreCotisationBean et DashboardMembreBean
- *
- * @author UnionFlow Team
- * @version 1.0
- * @since 2026-03-02
- */
-@Named("mesCotisationsPaiementBean")
-@ViewScoped
-public class MesCotisationsPaiementBean implements Serializable {
-
- private static final long serialVersionUID = 1L;
- private static final Logger LOG = Logger.getLogger(MesCotisationsPaiementBean.class);
- private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy");
-
- @Inject
- SecurityIdentity securityIdentity;
-
- @Inject
- @RestClient
- private MembreService membreService;
-
- @Inject
- @RestClient
- private CotisationService cotisationService;
-
- @Inject
- @RestClient
- private ExportClientService exportService;
-
- @Inject
- ErrorHandlerService errorHandler;
-
- @Inject
- RetryService retryService;
-
- // Informations du membre connecté
- private UUID membreId;
- private String numeroMembre;
- private MembreResponse membre;
-
- // KPI personnels - Cotisations à payer
- private Integer cotisationsEnAttente = 0;
- private String montantDu = "0 FCFA";
- private String prochaineEcheance = "-";
- private String totalPaye = "0 FCFA";
- private Integer anneeEnCours = LocalDate.now().getYear();
-
- // Listes
- private List mesCotisationsEnAttente = new ArrayList<>();
- private List derniersPaiements = new ArrayList<>();
-
- // Formulaires dialogs
- // Dialog Paiement en Ligne
- private UUID cotisationSelectionneeId;
- private CotisationPerso cotisationSelectionnee;
- private String methodePaiementChoisie = "WAVE";
- private String numeroTelephone;
-
- // Dialog Paiement Manuel
- private String methodePaiementManuel = "ESPECES";
- private String referencePaiementManuel;
- private String commentairePaiement;
-
- // Configuration organisation (TODO: charger depuis API)
- private boolean paiementManuelActive = true;
-
- @PostConstruct
- public void init() {
- LOG.info("Initialisation du bean de paiement des cotisations personnelles");
- detecterMembreConnecte();
- if (membreId != null) {
- chargerDonnees();
- }
- }
-
- /**
- * Auto-détection du membre connecté (Pattern DRY depuis DashboardMembreBean)
- */
- private void detecterMembreConnecte() {
- try {
- String username = securityIdentity.getPrincipal().getName();
- LOG.infof("Auto-détection du membre connecté: %s", username);
-
- // Récupérer directement le membre connecté via l'endpoint /me
- membre = retryService.executeWithRetrySupplier(
- () -> membreService.obtenirMembreConnecte(),
- "récupération du membre connecté"
- );
-
- if (membre != null) {
- membreId = membre.getId();
- numeroMembre = membre.getNumeroMembre();
- LOG.infof("Membre connecté détecté: %s (%s)", numeroMembre, membreId);
- } else {
- LOG.warnf("Aucun membre trouvé pour l'utilisateur: %s", username);
- errorHandler.showWarning("Attention",
- "Impossible de charger vos cotisations. Veuillez contacter l'administrateur.");
- }
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors de l'auto-détection du membre connecté");
- errorHandler.handleException(e, "lors du chargement de vos cotisations", null);
- }
- }
-
- /**
- * Charge toutes les données personnelles de cotisations et paiements
- */
- private void chargerDonnees() {
- chargerCotisationsEnAttente();
- chargerDerniersPaiements();
- calculerKPI();
- }
-
- /**
- * Charge les cotisations en attente du membre connecté
- * Pattern DRY: Réutilise la logique de MembreCotisationBean.chargerCotisations()
- */
- private void chargerCotisationsEnAttente() {
- try {
- // TODO: Créer endpoint GET /api/cotisations/mes-cotisations/en-attente
- // Pour l'instant, utiliser l'endpoint existant avec filtre statut
- List cotisationsDTO = retryService.executeWithRetrySupplier(
- () -> cotisationService.rechercher(
- membreId,
- "EN_ATTENTE", // Statut
- null, // Type
- anneeEnCours,
- null, // Mois
- 0,
- 100
- ),
- "chargement des cotisations en attente"
- );
-
- mesCotisationsEnAttente = new ArrayList<>();
- for (CotisationResponse dto : cotisationsDTO) {
- CotisationPerso cotisation = new CotisationPerso();
- cotisation.setId(dto.getId());
- cotisation.setReference(dto.getNumeroReference() != null ? dto.getNumeroReference() : "");
- cotisation.setType(dto.getTypeCotisation() != null ? dto.getTypeCotisation() : "MENSUELLE");
- cotisation.setPeriode(formaterPeriode(dto.getDateEcheance()));
- cotisation.setMontantDu(dto.getMontantDu() != null ? dto.getMontantDu() : BigDecimal.ZERO);
- cotisation.setDateEcheance(dto.getDateEcheance());
- mesCotisationsEnAttente.add(cotisation);
- }
-
- LOG.infof("Cotisations en attente chargées: %d", mesCotisationsEnAttente.size());
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors du chargement des cotisations en attente");
- errorHandler.handleException(e, "lors du chargement de vos cotisations en attente", null);
- mesCotisationsEnAttente = new ArrayList<>();
- }
- }
-
- /**
- * Charge les 5 derniers paiements du membre connecté
- */
- private void chargerDerniersPaiements() {
- try {
- // TODO: Créer endpoint GET /api/paiements/mes-paiements/historique?limit=5
- // Pour l'instant, charger toutes les cotisations payées et prendre les 5 dernières
- List cotisationsPayees = retryService.executeWithRetrySupplier(
- () -> cotisationService.rechercher(
- membreId,
- "PAYEE", // Statut
- null, // Type
- null, // Année
- null, // Mois
- 0,
- 5
- ),
- "chargement de l'historique des paiements"
- );
-
- derniersPaiements = new ArrayList<>();
- for (CotisationResponse dto : cotisationsPayees) {
- PaiementPerso paiement = new PaiementPerso();
- paiement.setId(dto.getId());
- paiement.setReference(dto.getNumeroReference() != null ? dto.getNumeroReference() : "");
- paiement.setPeriode(formaterPeriode(dto.getDateEcheance()));
- paiement.setMontant(dto.getMontantDu() != null ? dto.getMontantDu() : BigDecimal.ZERO);
- if (dto.getDatePaiement() != null) {
- paiement.setDatePaiement(dto.getDatePaiement().toLocalDate());
- }
- // Note: methodePaiement non disponible dans CotisationResponse
- paiement.setMethodePaiement("Non renseignée");
- derniersPaiements.add(paiement);
- }
-
- LOG.infof("Derniers paiements chargés: %d", derniersPaiements.size());
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors du chargement des derniers paiements");
- errorHandler.handleException(e, "lors du chargement de votre historique", null);
- derniersPaiements = new ArrayList<>();
- }
- }
-
- /**
- * Calcule les KPI personnels depuis les données chargées
- */
- private void calculerKPI() {
- // Cotisations en attente
- cotisationsEnAttente = mesCotisationsEnAttente.size();
-
- // Montant dû total
- BigDecimal montantTotal = mesCotisationsEnAttente.stream()
- .map(CotisationPerso::getMontantDu)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
- montantDu = formaterMontant(montantTotal);
-
- // Prochaine échéance
- if (!mesCotisationsEnAttente.isEmpty()) {
- LocalDate prochaine = mesCotisationsEnAttente.stream()
- .map(CotisationPerso::getDateEcheance)
- .filter(d -> d != null)
- .min(LocalDate::compareTo)
- .orElse(null);
- prochaineEcheance = prochaine != null ? prochaine.format(DATE_FORMATTER) : "-";
- } else {
- prochaineEcheance = "Aucune";
- }
-
- // Total payé cette année
- BigDecimal totalPayeAnnee = derniersPaiements.stream()
- .filter(p -> p.getDatePaiement() != null && p.getDatePaiement().getYear() == anneeEnCours)
- .map(PaiementPerso::getMontant)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
- totalPaye = formaterMontant(totalPayeAnnee);
-
- LOG.infof("KPI calculés: %d cotisations en attente, %s à payer", cotisationsEnAttente, montantDu);
- }
-
- // ═══════════════════════════════════════════════════════════════════════
- // Actions
- // ═══════════════════════════════════════════════════════════════════════
-
- /**
- * Sélectionne une cotisation et prépare le dialog de paiement en ligne
- */
- public void initierPaiementEnLigne(CotisationPerso cotis) {
- this.cotisationSelectionnee = cotis;
- this.cotisationSelectionneeId = cotis != null ? cotis.getId() : null;
- this.numeroTelephone = null;
- this.methodePaiementChoisie = "WAVE_MONEY";
- LOG.infof("Dialog paiement en ligne ouvert pour cotisation: %s", cotisationSelectionneeId);
- }
-
- /**
- * Sélectionne une cotisation et prépare le dialog de paiement manuel
- */
- public void selectionnerCotisation(CotisationPerso cotis) {
- this.cotisationSelectionnee = cotis;
- this.cotisationSelectionneeId = cotis != null ? cotis.getId() : null;
- this.methodePaiementManuel = "ESPECES";
- this.referencePaiementManuel = null;
- this.commentairePaiement = null;
- LOG.infof("Dialog paiement manuel ouvert pour cotisation: %s", cotisationSelectionneeId);
- }
-
- /**
- * Procède au paiement en ligne (Wave, Orange, Free Money, Carte)
- */
- public void procederPaiementEnLigne() {
- if (cotisationSelectionneeId == null) {
- errorHandler.showWarning("Attention", "Veuillez sélectionner une cotisation à payer");
- return;
- }
-
- if (numeroTelephone == null || numeroTelephone.trim().isEmpty()) {
- errorHandler.showWarning("Attention", "Veuillez saisir votre numéro de téléphone");
- return;
- }
-
- try {
- // TODO: Créer endpoint POST /api/paiements/initier-paiement-en-ligne
- // Body: { cotisationId, methodePaiement, numeroTelephone }
- // Retour: { redirectUrl, transactionId }
- LOG.infof("Paiement en ligne initié: cotisation=%s, méthode=%s, téléphone=%s",
- cotisationSelectionneeId, methodePaiementChoisie, numeroTelephone);
-
- errorHandler.showInfo("Paiement en ligne",
- "Redirection vers le gateway de paiement " + methodePaiementChoisie + "...");
-
- // TODO: Rediriger vers l'URL du gateway de paiement
- // ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
- // ec.redirect(paymentGatewayUrl);
-
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors de l'initiation du paiement en ligne");
- errorHandler.handleException(e, "lors de l'initiation du paiement", null);
- }
- }
-
- /**
- * Déclare un paiement manuel (espèces, virement, chèque)
- * Statut: EN_ATTENTE_VALIDATION (le trésorier doit valider)
- */
- public void declarerPaiementManuel() {
- if (cotisationSelectionneeId == null) {
- errorHandler.showWarning("Attention", "Veuillez sélectionner une cotisation");
- return;
- }
-
- if (methodePaiementManuel == null || methodePaiementManuel.trim().isEmpty()) {
- errorHandler.showWarning("Attention", "Veuillez sélectionner une méthode de paiement");
- return;
- }
-
- try {
- // TODO: Créer endpoint POST /api/paiements/declarer-paiement-manuel
- // Body: { cotisationId, methodePaiement, reference, commentaire }
- // Retour: 201 Created
- LOG.infof("Paiement manuel déclaré: cotisation=%s, méthode=%s, ref=%s",
- cotisationSelectionneeId, methodePaiementManuel, referencePaiementManuel);
-
- errorHandler.showSuccess("Paiement déclaré",
- "Votre paiement a été enregistré. Il sera validé par le trésorier.");
-
- // Recharger les données
- chargerDonnees();
-
- // Réinitialiser le formulaire
- cotisationSelectionneeId = null;
- methodePaiementManuel = "ESPECES";
- referencePaiementManuel = null;
- commentairePaiement = null;
-
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors de la déclaration du paiement manuel");
- errorHandler.handleException(e, "lors de la déclaration du paiement", null);
- }
- }
-
- /**
- * Télécharge le reçu PDF d'un paiement
- */
- public void telechargerRecu(PaiementPerso paiement) {
- if (paiement == null || paiement.getId() == null) {
- errorHandler.showWarning("Attention", "Impossible de télécharger le reçu");
- return;
- }
-
- UUID paiementId = paiement.getId();
- try {
- // TODO: Créer endpoint GET /api/paiements/telecharger-recu/{id}
- byte[] recu = retryService.executeWithRetrySupplier(
- () -> exportService.genererRecu(paiementId),
- "génération d'un reçu"
- );
-
- String nomFichier = "recu-" + paiementId + ".pdf";
- telechargerFichier(recu, nomFichier, "application/pdf");
-
- errorHandler.showSuccess("Reçu téléchargé", "Le reçu a été téléchargé avec succès");
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors du téléchargement du reçu");
- errorHandler.handleException(e, "lors du téléchargement du reçu", null);
- }
- }
-
- /**
- * Actualise les données
- */
- public void actualiser() {
- LOG.info("Actualisation des données de paiement");
- chargerDonnees();
- errorHandler.showSuccess("Actualisation", "Les données ont été actualisées");
- }
-
- // ═══════════════════════════════════════════════════════════════════════
- // Helpers
- // ═══════════════════════════════════════════════════════════════════════
-
- private String formaterPeriode(LocalDate dateEcheance) {
- if (dateEcheance == null) {
- return "";
- }
- String[] moisNoms = {"Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
- "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"};
- int mois = dateEcheance.getMonthValue();
- int annee = dateEcheance.getYear();
- return moisNoms[mois - 1] + " " + annee;
- }
-
- private String formaterMontant(BigDecimal montant) {
- if (montant == null) {
- return "0 FCFA";
- }
- return String.format("%,.0f FCFA", montant);
- }
-
- private void telechargerFichier(byte[] data, String nomFichier, String contentType) {
- try {
- jakarta.faces.context.FacesContext fc = jakarta.faces.context.FacesContext.getCurrentInstance();
- ExternalContext ec = fc.getExternalContext();
- ec.responseReset();
- ec.setResponseContentType(contentType + "; charset=UTF-8");
- ec.setResponseContentLength(data.length);
- ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + nomFichier + "\"");
- OutputStream output = ec.getResponseOutputStream();
- output.write(data);
- output.flush();
- fc.responseComplete();
- } catch (Exception e) {
- LOG.errorf(e, "Erreur téléchargement fichier");
- throw new RuntimeException("Erreur lors du téléchargement", e);
- }
- }
-
- // ═══════════════════════════════════════════════════════════════════════
- // Getters / Setters
- // ═══════════════════════════════════════════════════════════════════════
-
- public UUID getMembreId() { return membreId; }
- public String getNumeroMembre() { return numeroMembre; }
- public MembreResponse getMembre() { return membre; }
-
- public Integer getCotisationsEnAttente() { return cotisationsEnAttente; }
- public String getMontantDu() { return montantDu; }
- public String getProchaineEcheance() { return prochaineEcheance; }
- public String getTotalPaye() { return totalPaye; }
- public Integer getAnneeEnCours() { return anneeEnCours; }
-
- public List getMesCotisationsEnAttente() { return mesCotisationsEnAttente; }
- public List getDerniersPaiements() { return derniersPaiements; }
-
- public UUID getCotisationSelectionneeId() { return cotisationSelectionneeId; }
- public void setCotisationSelectionneeId(UUID cotisationSelectionneeId) { this.cotisationSelectionneeId = cotisationSelectionneeId; }
-
- public CotisationPerso getCotisationSelectionnee() { return cotisationSelectionnee; }
-
- public String getMethodePaiementChoisie() { return methodePaiementChoisie; }
- public void setMethodePaiementChoisie(String methodePaiementChoisie) { this.methodePaiementChoisie = methodePaiementChoisie; }
-
- public String getNumeroTelephone() { return numeroTelephone; }
- public void setNumeroTelephone(String numeroTelephone) { this.numeroTelephone = numeroTelephone; }
-
- public String getMethodePaiementManuel() { return methodePaiementManuel; }
- public void setMethodePaiementManuel(String methodePaiementManuel) { this.methodePaiementManuel = methodePaiementManuel; }
-
- public String getReferencePaiementManuel() { return referencePaiementManuel; }
- public void setReferencePaiementManuel(String referencePaiementManuel) { this.referencePaiementManuel = referencePaiementManuel; }
-
- public String getCommentairePaiement() { return commentairePaiement; }
- public void setCommentairePaiement(String commentairePaiement) { this.commentairePaiement = commentairePaiement; }
-
- public boolean isPaiementManuelActive() { return paiementManuelActive; }
-
- // ═══════════════════════════════════════════════════════════════════════
- // DTOs internes
- // ═══════════════════════════════════════════════════════════════════════
-
- public static class CotisationPerso implements Serializable {
- private static final long serialVersionUID = 1L;
-
- private UUID id;
- private String reference;
- private String type;
- private String periode;
- private BigDecimal montantDu;
- private LocalDate dateEcheance;
-
- // Getters / Setters
- public UUID getId() { return id; }
- public void setId(UUID id) { this.id = id; }
-
- public String getReference() { return reference; }
- public void setReference(String reference) { this.reference = reference; }
-
- public String getType() { return type; }
- public void setType(String type) { this.type = type; }
-
- public String getPeriode() { return periode; }
- public void setPeriode(String periode) { this.periode = periode; }
-
- public BigDecimal getMontantDu() { return montantDu; }
- public void setMontantDu(BigDecimal montantDu) { this.montantDu = montantDu; }
-
- public LocalDate getDateEcheance() { return dateEcheance; }
- public void setDateEcheance(LocalDate dateEcheance) { this.dateEcheance = dateEcheance; }
-
- // Méthodes dérivées pour l'affichage
- public String getTypeSeverity() {
- return switch (type) {
- case "MENSUELLE" -> "info";
- case "SPECIALE" -> "warning";
- case "ADHESION" -> "success";
- default -> "secondary";
- };
- }
-
- public String getTypeIcon() {
- return switch (type) {
- case "MENSUELLE" -> "pi-calendar";
- case "SPECIALE" -> "pi-star";
- case "ADHESION" -> "pi-user-plus";
- default -> "pi-circle";
- };
- }
-
- public String getMontantDuFormatte() {
- return montantDu != null ? String.format("%,.0f FCFA", montantDu) : "0 FCFA";
- }
-
- public String getDateEcheanceFormattee() {
- return dateEcheance != null ? dateEcheance.format(DATE_FORMATTER) : "-";
- }
-
- public String getTypeLibelle() {
- if (type == null) return "Cotisation";
- return switch (type) {
- case "MENSUELLE" -> "Mensuelle";
- case "SPECIALE" -> "Spéciale";
- case "ADHESION" -> "Adhésion";
- case "ANNUELLE" -> "Annuelle";
- default -> type;
- };
- }
-
- public String getLibelle() {
- return getTypeLibelle() + (periode != null && !periode.isBlank() ? " — " + periode : "");
- }
-
- public String getPeriodeFormatee() {
- return periode != null ? periode : "-";
- }
-
- public String getRetardColor() {
- if (dateEcheance == null) return "text-600";
- long jours = java.time.temporal.ChronoUnit.DAYS.between(LocalDate.now(), dateEcheance);
- if (jours < 0) return "text-red-600 font-bold";
- if (jours <= 7) return "text-orange-600";
- return "text-600";
- }
-
- public String getStatutEcheance() {
- if (dateEcheance == null) return "-";
- long jours = java.time.temporal.ChronoUnit.DAYS.between(LocalDate.now(), dateEcheance);
- if (jours < 0) return "En retard (" + Math.abs(jours) + " j)";
- if (jours == 0) return "Aujourd'hui";
- if (jours == 1) return "Demain";
- return "Dans " + jours + " jours";
- }
- }
-
- public static class PaiementPerso implements Serializable {
- private static final long serialVersionUID = 1L;
-
- private UUID id;
- private String reference;
- private String periode;
- private BigDecimal montant;
- private LocalDate datePaiement;
- private String methodePaiement;
-
- // Getters / Setters
- public UUID getId() { return id; }
- public void setId(UUID id) { this.id = id; }
-
- public String getReference() { return reference; }
- public void setReference(String reference) { this.reference = reference; }
-
- public String getPeriode() { return periode; }
- public void setPeriode(String periode) { this.periode = periode; }
-
- public BigDecimal getMontant() { return montant; }
- public void setMontant(BigDecimal montant) { this.montant = montant; }
-
- public LocalDate getDatePaiement() { return datePaiement; }
- public void setDatePaiement(LocalDate datePaiement) { this.datePaiement = datePaiement; }
-
- public String getMethodePaiement() { return methodePaiement; }
- public void setMethodePaiement(String methodePaiement) { this.methodePaiement = methodePaiement; }
-
- // Méthodes dérivées pour l'affichage
- public String getMontantFormatte() {
- return montant != null ? String.format("%,.0f FCFA", montant) : "0 FCFA";
- }
-
- public String getDatePaiementFormattee() {
- return datePaiement != null ? datePaiement.format(DATE_FORMATTER) : "-";
- }
-
- public String getTypeLibelle() {
- return periode != null && !periode.isBlank() ? periode : "Cotisation";
- }
-
- public String getMethodeSeverity() {
- if (methodePaiement == null) return "secondary";
- return switch (methodePaiement) {
- case "WAVE_MONEY" -> "success";
- case "ORANGE_MONEY" -> "warning";
- case "FREE_MONEY" -> "info";
- case "CARTE_BANCAIRE" -> "primary";
- case "ESPECES" -> "secondary";
- case "VIREMENT" -> "info";
- case "CHEQUE" -> "secondary";
- default -> "secondary";
- };
- }
-
- public String getMethodeIcon() {
- if (methodePaiement == null) return "pi-credit-card";
- return switch (methodePaiement) {
- case "WAVE_MONEY" -> "pi-mobile";
- case "ORANGE_MONEY" -> "pi-mobile";
- case "FREE_MONEY" -> "pi-mobile";
- case "CARTE_BANCAIRE" -> "pi-credit-card";
- case "ESPECES" -> "pi-money-bill";
- case "VIREMENT" -> "pi-building";
- case "CHEQUE" -> "pi-file";
- default -> "pi-credit-card";
- };
- }
- }
-}
+package dev.lions.unionflow.client.view;
+
+import dev.lions.unionflow.server.api.dto.cotisation.response.CotisationResponse;
+import dev.lions.unionflow.server.api.dto.membre.response.MembreResponse;
+import dev.lions.unionflow.server.api.dto.paiement.response.PaiementResponse;
+import dev.lions.unionflow.client.service.CotisationService;
+import dev.lions.unionflow.client.service.ErrorHandlerService;
+import dev.lions.unionflow.client.service.ExportClientService;
+import dev.lions.unionflow.client.service.MembreService;
+import dev.lions.unionflow.client.service.RetryService;
+import io.quarkus.security.identity.SecurityIdentity;
+import jakarta.annotation.PostConstruct;
+import jakarta.faces.context.ExternalContext;
+import jakarta.faces.view.ViewScoped;
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+import org.eclipse.microprofile.rest.client.inject.RestClient;
+import org.jboss.logging.Logger;
+
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Bean pour le paiement des cotisations du membre connecté (MEMBRE_ACTIF).
+ * Affiche uniquement les cotisations personnelles, pas les données admin.
+ *
+ * Pattern DRY: Réutilise la logique de MembreCotisationBean et DashboardMembreBean
+ *
+ * @author UnionFlow Team
+ * @version 1.0
+ * @since 2026-03-02
+ */
+@Named("mesCotisationsPaiementBean")
+@ViewScoped
+public class MesCotisationsPaiementBean implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private static final Logger LOG = Logger.getLogger(MesCotisationsPaiementBean.class);
+ private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy");
+
+ @Inject
+ SecurityIdentity securityIdentity;
+
+ @Inject
+ @RestClient
+ private MembreService membreService;
+
+ @Inject
+ @RestClient
+ private CotisationService cotisationService;
+
+ @Inject
+ @RestClient
+ private ExportClientService exportService;
+
+ @Inject
+ ErrorHandlerService errorHandler;
+
+ @Inject
+ RetryService retryService;
+
+ // Informations du membre connecté
+ private UUID membreId;
+ private String numeroMembre;
+ private MembreResponse membre;
+
+ // KPI personnels - Cotisations à payer
+ private Integer cotisationsEnAttente = 0;
+ private String montantDu = "0 FCFA";
+ private String prochaineEcheance = "-";
+ private String totalPaye = "0 FCFA";
+ private Integer anneeEnCours = LocalDate.now().getYear();
+
+ // Listes
+ private List mesCotisationsEnAttente = new ArrayList<>();
+ private List derniersPaiements = new ArrayList<>();
+
+ // Formulaires dialogs
+ // Dialog Paiement en Ligne
+ private UUID cotisationSelectionneeId;
+ private CotisationPerso cotisationSelectionnee;
+ private String methodePaiementChoisie = "WAVE";
+ private String numeroTelephone;
+
+ // Dialog Paiement Manuel
+ private String methodePaiementManuel = "ESPECES";
+ private String referencePaiementManuel;
+ private String commentairePaiement;
+
+ // Configuration organisation (TODO: charger depuis API)
+ private boolean paiementManuelActive = true;
+
+ @PostConstruct
+ public void init() {
+ LOG.info("Initialisation du bean de paiement des cotisations personnelles");
+ detecterMembreConnecte();
+ if (membreId != null) {
+ chargerDonnees();
+ }
+ }
+
+ /**
+ * Auto-détection du membre connecté (Pattern DRY depuis DashboardMembreBean)
+ */
+ private void detecterMembreConnecte() {
+ try {
+ String username = securityIdentity.getPrincipal().getName();
+ LOG.infof("Auto-détection du membre connecté: %s", username);
+
+ // Récupérer directement le membre connecté via l'endpoint /me
+ membre = retryService.executeWithRetrySupplier(
+ () -> membreService.obtenirMembreConnecte(),
+ "récupération du membre connecté"
+ );
+
+ if (membre != null) {
+ membreId = membre.getId();
+ numeroMembre = membre.getNumeroMembre();
+ LOG.infof("Membre connecté détecté: %s (%s)", numeroMembre, membreId);
+ } else {
+ LOG.warnf("Aucun membre trouvé pour l'utilisateur: %s", username);
+ errorHandler.showWarning("Attention",
+ "Impossible de charger vos cotisations. Veuillez contacter l'administrateur.");
+ }
+ } catch (Exception e) {
+ LOG.errorf(e, "Erreur lors de l'auto-détection du membre connecté");
+ errorHandler.handleException(e, "lors du chargement de vos cotisations", null);
+ }
+ }
+
+ /**
+ * Charge toutes les données personnelles de cotisations et paiements
+ */
+ private void chargerDonnees() {
+ chargerCotisationsEnAttente();
+ chargerDerniersPaiements();
+ calculerKPI();
+ }
+
+ /**
+ * Charge les cotisations en attente du membre connecté
+ * Pattern DRY: Réutilise la logique de MembreCotisationBean.chargerCotisations()
+ */
+ private void chargerCotisationsEnAttente() {
+ try {
+ // TODO: Créer endpoint GET /api/cotisations/mes-cotisations/en-attente
+ // Pour l'instant, utiliser l'endpoint existant avec filtre statut
+ List cotisationsDTO = retryService.executeWithRetrySupplier(
+ () -> cotisationService.rechercher(
+ membreId,
+ "EN_ATTENTE", // Statut
+ null, // Type
+ anneeEnCours,
+ null, // Mois
+ 0,
+ 100
+ ),
+ "chargement des cotisations en attente"
+ );
+
+ mesCotisationsEnAttente = new ArrayList<>();
+ for (CotisationResponse dto : cotisationsDTO) {
+ CotisationPerso cotisation = new CotisationPerso();
+ cotisation.setId(dto.getId());
+ cotisation.setReference(dto.getNumeroReference() != null ? dto.getNumeroReference() : "");
+ cotisation.setType(dto.getTypeCotisation() != null ? dto.getTypeCotisation() : "MENSUELLE");
+ cotisation.setPeriode(formaterPeriode(dto.getDateEcheance()));
+ cotisation.setMontantDu(dto.getMontantDu() != null ? dto.getMontantDu() : BigDecimal.ZERO);
+ cotisation.setDateEcheance(dto.getDateEcheance());
+ mesCotisationsEnAttente.add(cotisation);
+ }
+
+ LOG.infof("Cotisations en attente chargées: %d", mesCotisationsEnAttente.size());
+ } catch (Exception e) {
+ LOG.errorf(e, "Erreur lors du chargement des cotisations en attente");
+ errorHandler.handleException(e, "lors du chargement de vos cotisations en attente", null);
+ mesCotisationsEnAttente = new ArrayList<>();
+ }
+ }
+
+ /**
+ * Charge les 5 derniers paiements du membre connecté
+ */
+ private void chargerDerniersPaiements() {
+ try {
+ // TODO: Créer endpoint GET /api/paiements/mes-paiements/historique?limit=5
+ // Pour l'instant, charger toutes les cotisations payées et prendre les 5 dernières
+ List cotisationsPayees = retryService.executeWithRetrySupplier(
+ () -> cotisationService.rechercher(
+ membreId,
+ "PAYEE", // Statut
+ null, // Type
+ null, // Année
+ null, // Mois
+ 0,
+ 5
+ ),
+ "chargement de l'historique des paiements"
+ );
+
+ derniersPaiements = new ArrayList<>();
+ for (CotisationResponse dto : cotisationsPayees) {
+ PaiementPerso paiement = new PaiementPerso();
+ paiement.setId(dto.getId());
+ paiement.setReference(dto.getNumeroReference() != null ? dto.getNumeroReference() : "");
+ paiement.setPeriode(formaterPeriode(dto.getDateEcheance()));
+ paiement.setMontant(dto.getMontantDu() != null ? dto.getMontantDu() : BigDecimal.ZERO);
+ if (dto.getDatePaiement() != null) {
+ paiement.setDatePaiement(dto.getDatePaiement().toLocalDate());
+ }
+ // Note: methodePaiement non disponible dans CotisationResponse
+ paiement.setMethodePaiement("Non renseignée");
+ derniersPaiements.add(paiement);
+ }
+
+ LOG.infof("Derniers paiements chargés: %d", derniersPaiements.size());
+ } catch (Exception e) {
+ LOG.errorf(e, "Erreur lors du chargement des derniers paiements");
+ errorHandler.handleException(e, "lors du chargement de votre historique", null);
+ derniersPaiements = new ArrayList<>();
+ }
+ }
+
+ /**
+ * Calcule les KPI personnels depuis les données chargées
+ */
+ private void calculerKPI() {
+ // Cotisations en attente
+ cotisationsEnAttente = mesCotisationsEnAttente.size();
+
+ // Montant dû total
+ BigDecimal montantTotal = mesCotisationsEnAttente.stream()
+ .map(CotisationPerso::getMontantDu)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ montantDu = formaterMontant(montantTotal);
+
+ // Prochaine échéance
+ if (!mesCotisationsEnAttente.isEmpty()) {
+ LocalDate prochaine = mesCotisationsEnAttente.stream()
+ .map(CotisationPerso::getDateEcheance)
+ .filter(d -> d != null)
+ .min(LocalDate::compareTo)
+ .orElse(null);
+ prochaineEcheance = prochaine != null ? prochaine.format(DATE_FORMATTER) : "-";
+ } else {
+ prochaineEcheance = "Aucune";
+ }
+
+ // Total payé cette année
+ BigDecimal totalPayeAnnee = derniersPaiements.stream()
+ .filter(p -> p.getDatePaiement() != null && p.getDatePaiement().getYear() == anneeEnCours)
+ .map(PaiementPerso::getMontant)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ totalPaye = formaterMontant(totalPayeAnnee);
+
+ LOG.infof("KPI calculés: %d cotisations en attente, %s à payer", cotisationsEnAttente, montantDu);
+ }
+
+ // ═══════════════════════════════════════════════════════════════════════
+ // Actions
+ // ═══════════════════════════════════════════════════════════════════════
+
+ /**
+ * Sélectionne une cotisation et prépare le dialog de paiement en ligne
+ */
+ public void initierPaiementEnLigne(CotisationPerso cotis) {
+ this.cotisationSelectionnee = cotis;
+ this.cotisationSelectionneeId = cotis != null ? cotis.getId() : null;
+ this.numeroTelephone = null;
+ this.methodePaiementChoisie = "WAVE_MONEY";
+ LOG.infof("Dialog paiement en ligne ouvert pour cotisation: %s", cotisationSelectionneeId);
+ }
+
+ /**
+ * Sélectionne une cotisation et prépare le dialog de paiement manuel
+ */
+ public void selectionnerCotisation(CotisationPerso cotis) {
+ this.cotisationSelectionnee = cotis;
+ this.cotisationSelectionneeId = cotis != null ? cotis.getId() : null;
+ this.methodePaiementManuel = "ESPECES";
+ this.referencePaiementManuel = null;
+ this.commentairePaiement = null;
+ LOG.infof("Dialog paiement manuel ouvert pour cotisation: %s", cotisationSelectionneeId);
+ }
+
+ /**
+ * Procède au paiement en ligne (Wave, Orange, Free Money, Carte)
+ */
+ public void procederPaiementEnLigne() {
+ if (cotisationSelectionneeId == null) {
+ errorHandler.showWarning("Attention", "Veuillez sélectionner une cotisation à payer");
+ return;
+ }
+
+ if (numeroTelephone == null || numeroTelephone.trim().isEmpty()) {
+ errorHandler.showWarning("Attention", "Veuillez saisir votre numéro de téléphone");
+ return;
+ }
+
+ try {
+ // TODO: Créer endpoint POST /api/paiements/initier-paiement-en-ligne
+ // Body: { cotisationId, methodePaiement, numeroTelephone }
+ // Retour: { redirectUrl, transactionId }
+ LOG.infof("Paiement en ligne initié: cotisation=%s, méthode=%s, téléphone=%s",
+ cotisationSelectionneeId, methodePaiementChoisie, numeroTelephone);
+
+ errorHandler.showInfo("Paiement en ligne",
+ "Redirection vers le gateway de paiement " + methodePaiementChoisie + "...");
+
+ // TODO: Rediriger vers l'URL du gateway de paiement
+ // ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
+ // ec.redirect(paymentGatewayUrl);
+
+ } catch (Exception e) {
+ LOG.errorf(e, "Erreur lors de l'initiation du paiement en ligne");
+ errorHandler.handleException(e, "lors de l'initiation du paiement", null);
+ }
+ }
+
+ /**
+ * Déclare un paiement manuel (espèces, virement, chèque)
+ * Statut: EN_ATTENTE_VALIDATION (le trésorier doit valider)
+ */
+ public void declarerPaiementManuel() {
+ if (cotisationSelectionneeId == null) {
+ errorHandler.showWarning("Attention", "Veuillez sélectionner une cotisation");
+ return;
+ }
+
+ if (methodePaiementManuel == null || methodePaiementManuel.trim().isEmpty()) {
+ errorHandler.showWarning("Attention", "Veuillez sélectionner une méthode de paiement");
+ return;
+ }
+
+ try {
+ // TODO: Créer endpoint POST /api/paiements/declarer-paiement-manuel
+ // Body: { cotisationId, methodePaiement, reference, commentaire }
+ // Retour: 201 Created
+ LOG.infof("Paiement manuel déclaré: cotisation=%s, méthode=%s, ref=%s",
+ cotisationSelectionneeId, methodePaiementManuel, referencePaiementManuel);
+
+ errorHandler.showSuccess("Paiement déclaré",
+ "Votre paiement a été enregistré. Il sera validé par le trésorier.");
+
+ // Recharger les données
+ chargerDonnees();
+
+ // Réinitialiser le formulaire
+ cotisationSelectionneeId = null;
+ methodePaiementManuel = "ESPECES";
+ referencePaiementManuel = null;
+ commentairePaiement = null;
+
+ } catch (Exception e) {
+ LOG.errorf(e, "Erreur lors de la déclaration du paiement manuel");
+ errorHandler.handleException(e, "lors de la déclaration du paiement", null);
+ }
+ }
+
+ /**
+ * Télécharge le reçu PDF d'un paiement
+ */
+ public void telechargerRecu(PaiementPerso paiement) {
+ if (paiement == null || paiement.getId() == null) {
+ errorHandler.showWarning("Attention", "Impossible de télécharger le reçu");
+ return;
+ }
+
+ UUID paiementId = paiement.getId();
+ try {
+ // TODO: Créer endpoint GET /api/paiements/telecharger-recu/{id}
+ byte[] recu = retryService.executeWithRetrySupplier(
+ () -> exportService.genererRecu(paiementId),
+ "génération d'un reçu"
+ );
+
+ String nomFichier = "recu-" + paiementId + ".pdf";
+ telechargerFichier(recu, nomFichier, "application/pdf");
+
+ errorHandler.showSuccess("Reçu téléchargé", "Le reçu a été téléchargé avec succès");
+ } catch (Exception e) {
+ LOG.errorf(e, "Erreur lors du téléchargement du reçu");
+ errorHandler.handleException(e, "lors du téléchargement du reçu", null);
+ }
+ }
+
+ /**
+ * Actualise les données
+ */
+ public void actualiser() {
+ LOG.info("Actualisation des données de paiement");
+ chargerDonnees();
+ errorHandler.showSuccess("Actualisation", "Les données ont été actualisées");
+ }
+
+ // ═══════════════════════════════════════════════════════════════════════
+ // Helpers
+ // ═══════════════════════════════════════════════════════════════════════
+
+ private String formaterPeriode(LocalDate dateEcheance) {
+ if (dateEcheance == null) {
+ return "";
+ }
+ String[] moisNoms = {"Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
+ "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"};
+ int mois = dateEcheance.getMonthValue();
+ int annee = dateEcheance.getYear();
+ return moisNoms[mois - 1] + " " + annee;
+ }
+
+ private String formaterMontant(BigDecimal montant) {
+ if (montant == null) {
+ return "0 FCFA";
+ }
+ return String.format("%,.0f FCFA", montant);
+ }
+
+ private void telechargerFichier(byte[] data, String nomFichier, String contentType) {
+ try {
+ jakarta.faces.context.FacesContext fc = jakarta.faces.context.FacesContext.getCurrentInstance();
+ ExternalContext ec = fc.getExternalContext();
+ ec.responseReset();
+ ec.setResponseContentType(contentType + "; charset=UTF-8");
+ ec.setResponseContentLength(data.length);
+ ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + nomFichier + "\"");
+ OutputStream output = ec.getResponseOutputStream();
+ output.write(data);
+ output.flush();
+ fc.responseComplete();
+ } catch (Exception e) {
+ LOG.errorf(e, "Erreur téléchargement fichier");
+ throw new RuntimeException("Erreur lors du téléchargement", e);
+ }
+ }
+
+ // ═══════════════════════════════════════════════════════════════════════
+ // Getters / Setters
+ // ═══════════════════════════════════════════════════════════════════════
+
+ public UUID getMembreId() { return membreId; }
+ public String getNumeroMembre() { return numeroMembre; }
+ public MembreResponse getMembre() { return membre; }
+
+ public Integer getCotisationsEnAttente() { return cotisationsEnAttente; }
+ public String getMontantDu() { return montantDu; }
+ public String getProchaineEcheance() { return prochaineEcheance; }
+ public String getTotalPaye() { return totalPaye; }
+ public Integer getAnneeEnCours() { return anneeEnCours; }
+
+ public List getMesCotisationsEnAttente() { return mesCotisationsEnAttente; }
+ public List getDerniersPaiements() { return derniersPaiements; }
+
+ public UUID getCotisationSelectionneeId() { return cotisationSelectionneeId; }
+ public void setCotisationSelectionneeId(UUID cotisationSelectionneeId) { this.cotisationSelectionneeId = cotisationSelectionneeId; }
+
+ public CotisationPerso getCotisationSelectionnee() { return cotisationSelectionnee; }
+
+ public String getMethodePaiementChoisie() { return methodePaiementChoisie; }
+ public void setMethodePaiementChoisie(String methodePaiementChoisie) { this.methodePaiementChoisie = methodePaiementChoisie; }
+
+ public String getNumeroTelephone() { return numeroTelephone; }
+ public void setNumeroTelephone(String numeroTelephone) { this.numeroTelephone = numeroTelephone; }
+
+ public String getMethodePaiementManuel() { return methodePaiementManuel; }
+ public void setMethodePaiementManuel(String methodePaiementManuel) { this.methodePaiementManuel = methodePaiementManuel; }
+
+ public String getReferencePaiementManuel() { return referencePaiementManuel; }
+ public void setReferencePaiementManuel(String referencePaiementManuel) { this.referencePaiementManuel = referencePaiementManuel; }
+
+ public String getCommentairePaiement() { return commentairePaiement; }
+ public void setCommentairePaiement(String commentairePaiement) { this.commentairePaiement = commentairePaiement; }
+
+ public boolean isPaiementManuelActive() { return paiementManuelActive; }
+
+ // ═══════════════════════════════════════════════════════════════════════
+ // DTOs internes
+ // ═══════════════════════════════════════════════════════════════════════
+
+ public static class CotisationPerso implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private UUID id;
+ private String reference;
+ private String type;
+ private String periode;
+ private BigDecimal montantDu;
+ private LocalDate dateEcheance;
+
+ // Getters / Setters
+ public UUID getId() { return id; }
+ public void setId(UUID id) { this.id = id; }
+
+ public String getReference() { return reference; }
+ public void setReference(String reference) { this.reference = reference; }
+
+ public String getType() { return type; }
+ public void setType(String type) { this.type = type; }
+
+ public String getPeriode() { return periode; }
+ public void setPeriode(String periode) { this.periode = periode; }
+
+ public BigDecimal getMontantDu() { return montantDu; }
+ public void setMontantDu(BigDecimal montantDu) { this.montantDu = montantDu; }
+
+ public LocalDate getDateEcheance() { return dateEcheance; }
+ public void setDateEcheance(LocalDate dateEcheance) { this.dateEcheance = dateEcheance; }
+
+ // Méthodes dérivées pour l'affichage
+ public String getTypeSeverity() {
+ return switch (type) {
+ case "MENSUELLE" -> "info";
+ case "SPECIALE" -> "warning";
+ case "ADHESION" -> "success";
+ default -> "secondary";
+ };
+ }
+
+ public String getTypeIcon() {
+ return switch (type) {
+ case "MENSUELLE" -> "pi-calendar";
+ case "SPECIALE" -> "pi-star";
+ case "ADHESION" -> "pi-user-plus";
+ default -> "pi-circle";
+ };
+ }
+
+ public String getMontantDuFormatte() {
+ return montantDu != null ? String.format("%,.0f FCFA", montantDu) : "0 FCFA";
+ }
+
+ public String getDateEcheanceFormattee() {
+ return dateEcheance != null ? dateEcheance.format(DATE_FORMATTER) : "-";
+ }
+
+ public String getTypeLibelle() {
+ if (type == null) return "Cotisation";
+ return switch (type) {
+ case "MENSUELLE" -> "Mensuelle";
+ case "SPECIALE" -> "Spéciale";
+ case "ADHESION" -> "Adhésion";
+ case "ANNUELLE" -> "Annuelle";
+ default -> type;
+ };
+ }
+
+ public String getLibelle() {
+ return getTypeLibelle() + (periode != null && !periode.isBlank() ? " — " + periode : "");
+ }
+
+ public String getPeriodeFormatee() {
+ return periode != null ? periode : "-";
+ }
+
+ public String getRetardColor() {
+ if (dateEcheance == null) return "text-600";
+ long jours = java.time.temporal.ChronoUnit.DAYS.between(LocalDate.now(), dateEcheance);
+ if (jours < 0) return "text-red-600 font-bold";
+ if (jours <= 7) return "text-orange-600";
+ return "text-600";
+ }
+
+ public String getStatutEcheance() {
+ if (dateEcheance == null) return "-";
+ long jours = java.time.temporal.ChronoUnit.DAYS.between(LocalDate.now(), dateEcheance);
+ if (jours < 0) return "En retard (" + Math.abs(jours) + " j)";
+ if (jours == 0) return "Aujourd'hui";
+ if (jours == 1) return "Demain";
+ return "Dans " + jours + " jours";
+ }
+ }
+
+ public static class PaiementPerso implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private UUID id;
+ private String reference;
+ private String periode;
+ private BigDecimal montant;
+ private LocalDate datePaiement;
+ private String methodePaiement;
+
+ // Getters / Setters
+ public UUID getId() { return id; }
+ public void setId(UUID id) { this.id = id; }
+
+ public String getReference() { return reference; }
+ public void setReference(String reference) { this.reference = reference; }
+
+ public String getPeriode() { return periode; }
+ public void setPeriode(String periode) { this.periode = periode; }
+
+ public BigDecimal getMontant() { return montant; }
+ public void setMontant(BigDecimal montant) { this.montant = montant; }
+
+ public LocalDate getDatePaiement() { return datePaiement; }
+ public void setDatePaiement(LocalDate datePaiement) { this.datePaiement = datePaiement; }
+
+ public String getMethodePaiement() { return methodePaiement; }
+ public void setMethodePaiement(String methodePaiement) { this.methodePaiement = methodePaiement; }
+
+ // Méthodes dérivées pour l'affichage
+ public String getMontantFormatte() {
+ return montant != null ? String.format("%,.0f FCFA", montant) : "0 FCFA";
+ }
+
+ public String getDatePaiementFormattee() {
+ return datePaiement != null ? datePaiement.format(DATE_FORMATTER) : "-";
+ }
+
+ public String getTypeLibelle() {
+ return periode != null && !periode.isBlank() ? periode : "Cotisation";
+ }
+
+ public String getMethodeSeverity() {
+ if (methodePaiement == null) return "secondary";
+ return switch (methodePaiement) {
+ case "WAVE_MONEY" -> "success";
+ case "ORANGE_MONEY" -> "warning";
+ case "FREE_MONEY" -> "info";
+ case "CARTE_BANCAIRE" -> "primary";
+ case "ESPECES" -> "secondary";
+ case "VIREMENT" -> "info";
+ case "CHEQUE" -> "secondary";
+ default -> "secondary";
+ };
+ }
+
+ public String getMethodeIcon() {
+ if (methodePaiement == null) return "pi-credit-card";
+ return switch (methodePaiement) {
+ case "WAVE_MONEY" -> "pi-mobile";
+ case "ORANGE_MONEY" -> "pi-mobile";
+ case "FREE_MONEY" -> "pi-mobile";
+ case "CARTE_BANCAIRE" -> "pi-credit-card";
+ case "ESPECES" -> "pi-money-bill";
+ case "VIREMENT" -> "pi-building";
+ case "CHEQUE" -> "pi-file";
+ default -> "pi-credit-card";
+ };
+ }
+ }
+}
diff --git a/src/main/resources/META-INF/faces-config.xml b/src/main/resources/META-INF/faces-config.xml
index 9d36116..cf81d37 100644
--- a/src/main/resources/META-INF/faces-config.xml
+++ b/src/main/resources/META-INF/faces-config.xml
@@ -1,694 +1,694 @@
-
-
-
- UnionFlow
-
-
-
- omnifaces
-
-
-
-
-
- dev.lions.unionflow.client.exception.ViewExpiredExceptionHandlerFactory
-
-
-
-
- dev.lions.unionflow.client.config.QuarkusApplicationFactory
-
-
-
-
-
- fr
- fr
- en
-
-
-
-
- dev.lions.unionflow.client.el.QuarkusArcELResolver
-
-
-
- *
-
-
-
- Page d'accueil / Dashboard
- dashboardPage
- /pages/secure/dashboard.xhtml
-
-
-
-
-
- Page de liste des membres
- membreListPage
- /pages/secure/membre/liste.xhtml
-
-
-
-
- Page d'inscription de membre
- membreInscriptionPage
- /pages/secure/membre/inscription.xhtml
-
-
-
-
- Page de profil de membre
- membreProfilPage
- /pages/secure/membre/profil.xhtml
-
-
-
-
- Page de recherche de membre
- membreRecherchePage
- /pages/secure/membre/recherche.xhtml
-
-
-
-
- Page de modification de membre
- membreModifierPage
- /pages/secure/membre/inscription.xhtml
-
-
-
-
- Page de cotisations d'un membre
- membreCotisationsPage
- /pages/secure/membre/cotisations.xhtml
-
-
-
-
- Page de validation des inscriptions membres
- /pages/secure/membre/validation
- /pages/secure/membre/validation.xhtml
-
-
-
-
-
- Page des demandes de crédit
- /pages/secure/credit/demandes
- /pages/secure/credit/demandes.xhtml
-
-
-
- Page d'évaluation solvabilité crédit
- /pages/secure/credit/evaluation
- /pages/secure/credit/evaluation.xhtml
-
-
-
- Page de suivi des crédits
- /pages/secure/credit/suivi
- /pages/secure/credit/suivi.xhtml
-
-
-
- Page des remboursements crédit
- /pages/secure/credit/remboursements
- /pages/secure/credit/remboursements.xhtml
-
-
-
- Page des statistiques crédit
- /pages/secure/credit/statistiques
- /pages/secure/credit/statistiques.xhtml
-
-
-
-
-
- Page de liste des organisations
- organisationListPage
- /pages/secure/organisation/liste.xhtml
-
-
-
-
- Page de création d'organisation
- organisationNouvellePage
- /pages/secure/organisation/nouvelle.xhtml
-
-
-
-
- Page de détail d'organisation
- organisationDetailPage
- /pages/secure/organisation/detail.xhtml
-
-
-
-
-
- Page de gestion des événements
- evenementGestionPage
- /pages/secure/evenement/gestion.xhtml
-
-
-
-
- Page de création d'événement
- evenementCreationPage
- /pages/secure/evenement/creation.xhtml
-
-
-
-
- Page de planification d'événement
- evenementPlanificationPage
- /pages/secure/evenement/planification.xhtml
-
-
-
-
- Page de logistique d'événement
- evenementLogistiquePage
- /pages/secure/evenement/logistique.xhtml
-
-
-
-
- Page de bilan d'événement
- evenementBilanPage
- /pages/secure/evenement/bilan.xhtml
-
-
-
-
- Page de réservations d'événement
- evenementReservationsPage
- /pages/secure/evenement/reservations.xhtml
-
-
-
-
- Page de calendrier d'événements
- evenementCalendrierPage
- /pages/secure/evenement/calendrier.xhtml
-
-
-
-
- Page de participants d'événement
- evenementParticipantsPage
- /pages/secure/evenement/participants.xhtml
-
-
-
-
- Page de participation à un événement
- evenementParticipationPage
- /pages/secure/evenement/participation.xhtml
-
-
-
-
-
- Page de collecte de cotisations
- cotisationCollectPage
- /pages/secure/cotisation/collect.xhtml
-
-
-
-
- Page de paiement de cotisation
- cotisationPaiementPage
- /pages/secure/cotisation/paiement.xhtml
-
-
-
-
- Page d'historique des cotisations
- cotisationHistoriquePage
- /pages/secure/cotisation/historique.xhtml
-
-
-
-
- Page de rappels de cotisations
- cotisationRelancesPage
- /pages/secure/cotisation/relances.xhtml
-
-
-
-
- Page de rapports de cotisations
- cotisationRapportsPage
- /pages/secure/cotisation/rapports.xhtml
-
-
-
-
-
- Page de liste des adhésions
- adhesionListPage
- /pages/secure/adhesion/liste.xhtml
-
-
-
-
- Page de nouvelle adhésion
- adhesionNouvellePage
- /pages/secure/adhesion/new.xhtml
-
-
-
-
- Page de demande d'adhésion
- adhesionDemandePage
- /pages/secure/adhesion/demande.xhtml
-
-
-
-
- Page de validation d'adhésion
- adhesionValidationPage
- /pages/secure/adhesion/validation.xhtml
-
-
-
-
- Page de paiement d'adhésion
- adhesionPaiementPage
- /pages/secure/adhesion/paiement.xhtml
-
-
-
-
- Page de renouvellement d'adhésion
- adhesionRenouvellementPage
- /pages/secure/adhesion/renouvellement.xhtml
-
-
-
-
- Page d'historique des adhésions
- adhesionHistoriquePage
- /pages/secure/adhesion/history.xhtml
-
-
-
-
- Page d'adhésions en attente
- adhesionPendingPage
- /pages/secure/adhesion/pending.xhtml
-
-
-
-
-
- Page de demande d'aide
- aideDemandePage
- /pages/secure/aide/demande.xhtml
-
-
-
-
- Page de traitement des demandes d'aide
- aideTraitementPage
- /pages/secure/aide/traitement.xhtml
-
-
-
-
- Page d'historique des demandes d'aide
- aideHistoriquePage
- /pages/secure/aide/historique.xhtml
-
-
-
-
- Page de FAQ
- aideFaqPage
- /pages/secure/aide/faq.xhtml
-
-
-
-
- Page de documentation
- aideDocumentationPage
- /pages/secure/aide/documentation.xhtml
-
-
-
-
- Page de guide
- aideGuidePage
- /pages/secure/aide/guide.xhtml
-
-
-
-
- Page de tutoriels
- aideTutorielsPage
- /pages/secure/aide/tutoriels.xhtml
-
-
-
-
- Page de support
- aideSupportPage
- /pages/secure/aide/support.xhtml
-
-
-
-
- Page de tickets
- aideTicketsPage
- /pages/secure/aide/tickets.xhtml
-
-
-
-
- Page de statistiques d'aide
- aideStatistiquesPage
- /pages/secure/aide/statistiques.xhtml
-
-
-
-
-
- Page de rapports de membres
- rapportMembresPage
- /pages/secure/rapport/membres.xhtml
-
-
-
-
- Page de rapports financiers
- rapportFinancesPage
- /pages/secure/rapport/finances.xhtml
-
-
-
-
- Page de rapports d'activités
- rapportActivitesPage
- /pages/secure/rapport/activites.xhtml
-
-
-
-
- Page d'export de rapports
- rapportExportPage
- /pages/secure/rapport/export.xhtml
-
-
-
-
- Page de détails d'un rapport
- rapportDetailsPage
- /pages/secure/rapport/details.xhtml
-
-
-
-
-
- Page de profil personnel
- personnelProfilPage
- /pages/secure/personnel/profil.xhtml
-
-
-
-
- Page de notifications personnelles
- personnelNotificationsPage
- /pages/secure/personnel/notifications.xhtml
-
-
-
-
- Page de documents personnels
- personnelDocumentsPage
- /pages/secure/personnel/documents.xhtml
-
-
-
-
- Page d'agenda personnel
- personnelAgendaPage
- /pages/secure/personnel/agenda.xhtml
-
-
-
-
- Page d'activités personnelles
- personnelActivitesPage
- /pages/secure/personnel/activites.xhtml
-
-
-
-
- Page de favoris personnels
- personnelFavorisPage
- /pages/secure/personnel/favoris.xhtml
-
-
-
-
- Page de paramètres personnels
- personnelParametresPage
- /pages/secure/personnel/parametres.xhtml
-
-
-
-
- Page de préférences personnelles
- personnelPreferencesPage
- /pages/secure/personnel/preferences.xhtml
-
-
-
-
-
- Page de gestion des utilisateurs
- adminUtilisateursPage
- /pages/secure/admin/utilisateurs.xhtml
-
-
-
-
- Page de gestion des rôles
- adminRolesPage
- /pages/secure/admin/roles.xhtml
-
-
-
-
- Page de paramètres d'administration
- adminParametresPage
- /pages/secure/admin/parametres.xhtml
-
-
-
-
- Page d'audit
- adminAuditPage
- /pages/secure/admin/audit.xhtml
-
-
-
-
- Page de sauvegarde
- adminSauvegardePage
- /pages/secure/admin/sauvegarde.xhtml
-
-
-
-
-
- Page de dashboard de souscription
- souscriptionDashboardPage
- /pages/secure/souscription/dashboard.xhtml
-
-
-
-
- Page d'upgrade de souscription
- souscriptionUpgradePage
- /pages/secure/souscription/upgrade.xhtml
-
-
-
-
- Page de changement de plan de souscription
- souscriptionChangePlanPage
- /pages/secure/souscription/change-plan.xhtml
-
-
-
-
- Page de renouvellement de souscription
- souscriptionRenewPage
- /pages/secure/souscription/renew.xhtml
-
-
-
-
-
- Page de logs système (Super Admin)
- superAdminLogsPage
- /pages/super-admin/logs.xhtml
-
-
-
-
- Page de création d'organisation (Super Admin)
- organisationNouvellePage
- /pages/secure/organisation/nouvelle.xhtml
-
-
-
-
- Page de gestion des organisations (Super Admin)
- organisationGestionPage
- /pages/secure/organisation/liste.xhtml
-
-
-
-
- Page de rapports (Super Admin)
- superAdminRapportsPage
- /pages/super-admin/rapports.xhtml
-
-
-
-
- Page de configuration (Super Admin)
- superAdminConfigurationPage
- /pages/super-admin/configuration.xhtml
-
-
-
-
- Page d'alertes (Super Admin)
- superAdminAlertesPage
- /pages/super-admin/alertes.xhtml
-
-
-
-
- Page d'activité (Super Admin)
- superAdminActivitePage
- /pages/super-admin/activite.xhtml
-
-
-
-
- Page de détails d'organisation
- organisationDetailsPage
- /pages/secure/organisation/detail.xhtml
-
-
-
-
- Page de gestion des membres (Admin)
- adminMembresGestionPage
- /pages/admin/membres/gestion.xhtml
-
-
-
-
- Page de statistiques d'organisation
- organisationStatistiquesPage
- /pages/secure/organisation/statistiques.xhtml
-
-
-
-
-
- Page d'historique des demandes d'aide
- demandesHistoriquePage
- /pages/admin/demandes/historique.xhtml
-
-
-
-
-
- Page de checkout de souscription
- souscriptionCheckoutPage
- /pages/secure/souscription/checkout.xhtml
-
-
-
-
- Page de détails de formulaire
- formulaireDetailsPage
- /pages/public/formulaires/details.xhtml
-
-
-
-
-
- Page d'historique des versions de documents
- documentsVersionsPage
- /pages/admin/documents/versions.xhtml
-
-
-
-
-
- Page d'événement (Membre)
- membreEvenementPage
- /pages/membre/evenement.xhtml
-
-
-
-
- Page de cotisations (Membre)
- membreCotisationsPage
- /pages/membre/cotisations.xhtml
-
-
-
-
- Page d'historique des cotisations (Membre)
- membreHistoriqueCotisationsPage
- /pages/membre/historique-cotisations.xhtml
-
-
-
-
-
- Page de profil
- profilePage
- /pages/secure/profile.xhtml
-
-
-
-
- Page d'accès refusé
- accessDeniedPage
- /pages/secure/access-denied.xhtml
-
-
-
-
- Page de statistiques
- statsPage
- /pages/secure/stats.xhtml
-
-
-
-
- Page de rapports
- reportsPage
- /pages/secure/reports.xhtml
-
-
-
-
-
+
+
+
+ UnionFlow
+
+
+
+ omnifaces
+
+
+
+
+
+ dev.lions.unionflow.client.exception.ViewExpiredExceptionHandlerFactory
+
+
+
+
+ dev.lions.unionflow.client.config.QuarkusApplicationFactory
+
+
+
+
+
+ fr
+ fr
+ en
+
+
+
+
+ dev.lions.unionflow.client.el.QuarkusArcELResolver
+
+
+
+ *
+
+
+
+ Page d'accueil / Dashboard
+ dashboardPage
+ /pages/secure/dashboard.xhtml
+
+
+
+
+
+ Page de liste des membres
+ membreListPage
+ /pages/secure/membre/liste.xhtml
+
+
+
+
+ Page d'inscription de membre
+ membreInscriptionPage
+ /pages/secure/membre/inscription.xhtml
+
+
+
+
+ Page de profil de membre
+ membreProfilPage
+ /pages/secure/membre/profil.xhtml
+
+
+
+
+ Page de recherche de membre
+ membreRecherchePage
+ /pages/secure/membre/recherche.xhtml
+
+
+
+
+ Page de modification de membre
+ membreModifierPage
+ /pages/secure/membre/inscription.xhtml
+
+
+
+
+ Page de cotisations d'un membre
+ membreCotisationsPage
+ /pages/secure/membre/cotisations.xhtml
+
+
+
+
+ Page de validation des inscriptions membres
+ /pages/secure/membre/validation
+ /pages/secure/membre/validation.xhtml
+
+
+
+
+
+ Page des demandes de crédit
+ /pages/secure/credit/demandes
+ /pages/secure/credit/demandes.xhtml
+
+
+
+ Page d'évaluation solvabilité crédit
+ /pages/secure/credit/evaluation
+ /pages/secure/credit/evaluation.xhtml
+
+
+
+ Page de suivi des crédits
+ /pages/secure/credit/suivi
+ /pages/secure/credit/suivi.xhtml
+
+
+
+ Page des remboursements crédit
+ /pages/secure/credit/remboursements
+ /pages/secure/credit/remboursements.xhtml
+
+
+
+ Page des statistiques crédit
+ /pages/secure/credit/statistiques
+ /pages/secure/credit/statistiques.xhtml
+
+
+
+
+
+ Page de liste des organisations
+ organisationListPage
+ /pages/secure/organisation/liste.xhtml
+
+
+
+
+ Page de création d'organisation
+ organisationNouvellePage
+ /pages/secure/organisation/nouvelle.xhtml
+
+
+
+
+ Page de détail d'organisation
+ organisationDetailPage
+ /pages/secure/organisation/detail.xhtml
+
+
+
+
+
+ Page de gestion des événements
+ evenementGestionPage
+ /pages/secure/evenement/gestion.xhtml
+
+
+
+
+ Page de création d'événement
+ evenementCreationPage
+ /pages/secure/evenement/creation.xhtml
+
+
+
+
+ Page de planification d'événement
+ evenementPlanificationPage
+ /pages/secure/evenement/planification.xhtml
+
+
+
+
+ Page de logistique d'événement
+ evenementLogistiquePage
+ /pages/secure/evenement/logistique.xhtml
+
+
+
+
+ Page de bilan d'événement
+ evenementBilanPage
+ /pages/secure/evenement/bilan.xhtml
+
+
+
+
+ Page de réservations d'événement
+ evenementReservationsPage
+ /pages/secure/evenement/reservations.xhtml
+
+
+
+
+ Page de calendrier d'événements
+ evenementCalendrierPage
+ /pages/secure/evenement/calendrier.xhtml
+
+
+
+
+ Page de participants d'événement
+ evenementParticipantsPage
+ /pages/secure/evenement/participants.xhtml
+
+
+
+
+ Page de participation à un événement
+ evenementParticipationPage
+ /pages/secure/evenement/participation.xhtml
+
+
+
+
+
+ Page de collecte de cotisations
+ cotisationCollectPage
+ /pages/secure/cotisation/collect.xhtml
+
+
+
+
+ Page de paiement de cotisation
+ cotisationPaiementPage
+ /pages/secure/cotisation/paiement.xhtml
+
+
+
+
+ Page d'historique des cotisations
+ cotisationHistoriquePage
+ /pages/secure/cotisation/historique.xhtml
+
+
+
+
+ Page de rappels de cotisations
+ cotisationRelancesPage
+ /pages/secure/cotisation/relances.xhtml
+
+
+
+
+ Page de rapports de cotisations
+ cotisationRapportsPage
+ /pages/secure/cotisation/rapports.xhtml
+
+
+
+
+
+ Page de liste des adhésions
+ adhesionListPage
+ /pages/secure/adhesion/liste.xhtml
+
+
+
+
+ Page de nouvelle adhésion
+ adhesionNouvellePage
+ /pages/secure/adhesion/new.xhtml
+
+
+
+
+ Page de demande d'adhésion
+ adhesionDemandePage
+ /pages/secure/adhesion/demande.xhtml
+
+
+
+
+ Page de validation d'adhésion
+ adhesionValidationPage
+ /pages/secure/adhesion/validation.xhtml
+
+
+
+
+ Page de paiement d'adhésion
+ adhesionPaiementPage
+ /pages/secure/adhesion/paiement.xhtml
+
+
+
+
+ Page de renouvellement d'adhésion
+ adhesionRenouvellementPage
+ /pages/secure/adhesion/renouvellement.xhtml
+
+
+
+
+ Page d'historique des adhésions
+ adhesionHistoriquePage
+ /pages/secure/adhesion/history.xhtml
+
+
+
+
+ Page d'adhésions en attente
+ adhesionPendingPage
+ /pages/secure/adhesion/pending.xhtml
+
+
+
+
+
+ Page de demande d'aide
+ aideDemandePage
+ /pages/secure/aide/demande.xhtml
+
+
+
+
+ Page de traitement des demandes d'aide
+ aideTraitementPage
+ /pages/secure/aide/traitement.xhtml
+
+
+
+
+ Page d'historique des demandes d'aide
+ aideHistoriquePage
+ /pages/secure/aide/historique.xhtml
+
+
+
+
+ Page de FAQ
+ aideFaqPage
+ /pages/secure/aide/faq.xhtml
+
+
+
+
+ Page de documentation
+ aideDocumentationPage
+ /pages/secure/aide/documentation.xhtml
+
+
+
+
+ Page de guide
+ aideGuidePage
+ /pages/secure/aide/guide.xhtml
+
+
+
+
+ Page de tutoriels
+ aideTutorielsPage
+ /pages/secure/aide/tutoriels.xhtml
+
+
+
+
+ Page de support
+ aideSupportPage
+ /pages/secure/aide/support.xhtml
+
+
+
+
+ Page de tickets
+ aideTicketsPage
+ /pages/secure/aide/tickets.xhtml
+
+
+
+
+ Page de statistiques d'aide
+ aideStatistiquesPage
+ /pages/secure/aide/statistiques.xhtml
+
+
+
+
+
+ Page de rapports de membres
+ rapportMembresPage
+ /pages/secure/rapport/membres.xhtml
+
+
+
+
+ Page de rapports financiers
+ rapportFinancesPage
+ /pages/secure/rapport/finances.xhtml
+
+
+
+
+ Page de rapports d'activités
+ rapportActivitesPage
+ /pages/secure/rapport/activites.xhtml
+
+
+
+
+ Page d'export de rapports
+ rapportExportPage
+ /pages/secure/rapport/export.xhtml
+
+
+
+
+ Page de détails d'un rapport
+ rapportDetailsPage
+ /pages/secure/rapport/details.xhtml
+
+
+
+
+
+ Page de profil personnel
+ personnelProfilPage
+ /pages/secure/personnel/profil.xhtml
+
+
+
+
+ Page de notifications personnelles
+ personnelNotificationsPage
+ /pages/secure/personnel/notifications.xhtml
+
+
+
+
+ Page de documents personnels
+ personnelDocumentsPage
+ /pages/secure/personnel/documents.xhtml
+
+
+
+
+ Page d'agenda personnel
+ personnelAgendaPage
+ /pages/secure/personnel/agenda.xhtml
+
+
+
+
+ Page d'activités personnelles
+ personnelActivitesPage
+ /pages/secure/personnel/activites.xhtml
+
+
+
+
+ Page de favoris personnels
+ personnelFavorisPage
+ /pages/secure/personnel/favoris.xhtml
+
+
+
+
+ Page de paramètres personnels
+ personnelParametresPage
+ /pages/secure/personnel/parametres.xhtml
+
+
+
+
+ Page de préférences personnelles
+ personnelPreferencesPage
+ /pages/secure/personnel/preferences.xhtml
+
+
+
+
+
+ Page de gestion des utilisateurs
+ adminUtilisateursPage
+ /pages/secure/admin/utilisateurs.xhtml
+
+
+
+
+ Page de gestion des rôles
+ adminRolesPage
+ /pages/secure/admin/roles.xhtml
+
+
+
+
+ Page de paramètres d'administration
+ adminParametresPage
+ /pages/secure/admin/parametres.xhtml
+
+
+
+
+ Page d'audit
+ adminAuditPage
+ /pages/secure/admin/audit.xhtml
+
+
+
+
+ Page de sauvegarde
+ adminSauvegardePage
+ /pages/secure/admin/sauvegarde.xhtml
+
+
+
+
+
+ Page de dashboard de souscription
+ souscriptionDashboardPage
+ /pages/secure/souscription/dashboard.xhtml
+
+
+
+
+ Page d'upgrade de souscription
+ souscriptionUpgradePage
+ /pages/secure/souscription/upgrade.xhtml
+
+
+
+
+ Page de changement de plan de souscription
+ souscriptionChangePlanPage
+ /pages/secure/souscription/change-plan.xhtml
+
+
+
+
+ Page de renouvellement de souscription
+ souscriptionRenewPage
+ /pages/secure/souscription/renew.xhtml
+
+
+
+
+
+ Page de logs système (Super Admin)
+ superAdminLogsPage
+ /pages/super-admin/logs.xhtml
+
+
+
+
+ Page de création d'organisation (Super Admin)
+ organisationNouvellePage
+ /pages/secure/organisation/nouvelle.xhtml
+
+
+
+
+ Page de gestion des organisations (Super Admin)
+ organisationGestionPage
+ /pages/secure/organisation/liste.xhtml
+
+
+
+
+ Page de rapports (Super Admin)
+ superAdminRapportsPage
+ /pages/super-admin/rapports.xhtml
+
+
+
+
+ Page de configuration (Super Admin)
+ superAdminConfigurationPage
+ /pages/super-admin/configuration.xhtml
+
+
+
+
+ Page d'alertes (Super Admin)
+ superAdminAlertesPage
+ /pages/super-admin/alertes.xhtml
+
+
+
+
+ Page d'activité (Super Admin)
+ superAdminActivitePage
+ /pages/super-admin/activite.xhtml
+
+
+
+
+ Page de détails d'organisation
+ organisationDetailsPage
+ /pages/secure/organisation/detail.xhtml
+
+
+
+
+ Page de gestion des membres (Admin)
+ adminMembresGestionPage
+ /pages/admin/membres/gestion.xhtml
+
+
+
+
+ Page de statistiques d'organisation
+ organisationStatistiquesPage
+ /pages/secure/organisation/statistiques.xhtml
+
+
+
+
+
+ Page d'historique des demandes d'aide
+ demandesHistoriquePage
+ /pages/admin/demandes/historique.xhtml
+
+
+
+
+
+ Page de checkout de souscription
+ souscriptionCheckoutPage
+ /pages/secure/souscription/checkout.xhtml
+
+
+
+
+ Page de détails de formulaire
+ formulaireDetailsPage
+ /pages/public/formulaires/details.xhtml
+
+
+
+
+
+ Page d'historique des versions de documents
+ documentsVersionsPage
+ /pages/admin/documents/versions.xhtml
+
+
+
+
+
+ Page d'événement (Membre)
+ membreEvenementPage
+ /pages/membre/evenement.xhtml
+
+
+
+
+ Page de cotisations (Membre)
+ membreCotisationsPage
+ /pages/membre/cotisations.xhtml
+
+
+
+
+ Page d'historique des cotisations (Membre)
+ membreHistoriqueCotisationsPage
+ /pages/membre/historique-cotisations.xhtml
+
+
+
+
+
+ Page de profil
+ profilePage
+ /pages/secure/profile.xhtml
+
+
+
+
+ Page d'accès refusé
+ accessDeniedPage
+ /pages/secure/access-denied.xhtml
+
+
+
+
+ Page de statistiques
+ statsPage
+ /pages/secure/stats.xhtml
+
+
+
+
+ Page de rapports
+ reportsPage
+ /pages/secure/reports.xhtml
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/index.html b/src/main/resources/META-INF/resources/index.html
index fbcc8ee..1629f60 100644
--- a/src/main/resources/META-INF/resources/index.html
+++ b/src/main/resources/META-INF/resources/index.html
@@ -1,9 +1,9 @@
-
-
-
-
-
- UnionFlow
-
-
-
+
+
+
+
+
+ UnionFlow
+
+
+
diff --git a/src/main/resources/META-INF/resources/index.xhtml b/src/main/resources/META-INF/resources/index.xhtml
index db3ee61..7727724 100644
--- a/src/main/resources/META-INF/resources/index.xhtml
+++ b/src/main/resources/META-INF/resources/index.xhtml
@@ -1,605 +1,605 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- UnionFlow - Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- UNIONFLOW
-
-
-
-
-
-
-
-
-
-
-
-
UnionFlow
-
Fédérez vos membres. Sécurisez vos flux. Pilotez l'avenir.
- Oubliez la gestion manuelle. La plateforme technologique financière qui apporte transparence et rigueur à votre organisation.
-
-
- Accéder à la plateforme
-
-
-
-
-
-
-
-
-
-
1
-
-
1
-
-
Maîtrisez votre Base Membres
- Finies les listes papier perdues. Centralisez les profils, gérez les statuts et gardez le contact avec votre communauté.
-
-
-
-
-
-
-
-
-
-
2
-
-
2
-
-
Sécurisez vos Collectes
-
Automatisez vos appels à cotisation, suivez vos tontines en temps réel et intégrez les paiements par mobile money (ex: Wave) .
-
-
-
-
-
-
-
-
-
-
-
3
-
-
3
-
-
Faites vivre vos Réunions et AG
- Gérez l'organisation des assemblées générales, traquez les présences lors des réunions statutaires et boostez l'engagement.
-
-
-
-
-
-
-
-
-
-
-
4
-
-
4
-
-
L'entraide Transparente
- Sécurisez la gestion de vos cas sociaux (décès, maladie). Approuvez et décaissez les aides avec une traçabilité totale.
-
-
-
-
-
-
-
5
-
-
5
-
-
Scalabilité Absolue
- Conçu pour évoluer : d'une amicale de quartier à un district international du Lions ou Rotary Club avec des milliers de membres.
-
-
-
-
-
-
-
-
-
6
-
-
6
-
-
Reporting et Audit
- Générez des états financiers en un clic pour vos comptabilités et instaurez une gouvernance irréprochable.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sécurité de niveau entreprise
-
-
- Authentification centralisée SSO, gestion des accès par rôle et traçabilité
- complète de toutes les actions sur la plateforme.
-
-
-
-
- Infrastructure hautement sécurisée
-
-
-
- Chaque action est loggée et traçable
-
-
-
- Droits de validation croisée stricts
-
-
-
-
-
-
-
-
-
-
-
-
- Accessible partout, tout le temps
-
-
- Une application web responsive et une application mobile native pour
- que vos gestionnaires et membres restent connectés en toutes circonstances.
-
-
-
-
- Web responsive (tous navigateurs)
-
-
-
- Application mobile iOS & Android
-
-
-
- Disponible 24h/24, 7j/7
-
-
-
-
-
-
-
-
-
-
-
-
- Architecture ultra-rapide
-
-
- Bâtie sur des technologies cloud de dernière génération, la plateforme reste
- fluide et instantanée même avec des milliers de transactions.
-
-
-
-
- Temps de réponse quasi-instantané
-
-
-
- Scalabilité élastique
-
-
-
- Sauvegardes automatisées
-
-
-
-
-
-
-
-
-
-
-
-
- Pilotage par la donnée
-
-
- Des tableaux de bord interactifs et des KPIs en temps réel pour prendre
- les bonnes décisions au bon moment.
-
-
-
-
- Dashboards et KPIs temps réel
-
-
-
- Rapports exportables (PDF, Excel)
-
-
-
- Analyse des tendances et historiques
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Conçu pour les organisations du monde
-
-
- Mutuelles, clubs Lions, associations sportives, fédérations professionnelles —
- UnionFlow s'adapte à toute structure, sur tous les continents.
-
-
-
-
- Mutuelles & caisses de solidarité
-
-
-
- Clubs Lions, Rotary, associations civiques
-
-
-
- Fédérations & réseaux multi-niveaux
-
-
-
-
-
-
-
-
-
-
-
-
- Déploiement selon vos contraintes
-
-
- Hébergez la plateforme chez vous ou laissez-nous la gérer. L'API ouverte
- s'intègre facilement à vos outils existants.
-
-
-
-
- SaaS cloud géré ou on-premise
-
-
-
- API REST ouverte & documentée
-
-
-
- Évolutions et support continus
-
-
-
-
-
-
-
-
-
-
-
-
6+
-
Types d'organisations supportés
-
-
-
100%
-
Données sécurisées et chiffrées
-
-
-
24/7
-
Disponibilité garantie
-
-
-
∞
-
Scalabilité cloud-native
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UnionFlow - Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UNIONFLOW
+
+
+
+
+
+
+
+
+
+
+
+
UnionFlow
+
Fédérez vos membres. Sécurisez vos flux. Pilotez l'avenir.
+ Oubliez la gestion manuelle. La plateforme technologique financière qui apporte transparence et rigueur à votre organisation.
+
+
+ Accéder à la plateforme
+
+
+
+
+
+
+
+
+
+
1
+
+
1
+
+
Maîtrisez votre Base Membres
+ Finies les listes papier perdues. Centralisez les profils, gérez les statuts et gardez le contact avec votre communauté.
+
+
+
+
+
+
+
+
+
+
2
+
+
2
+
+
Sécurisez vos Collectes
+
Automatisez vos appels à cotisation, suivez vos tontines en temps réel et intégrez les paiements par mobile money (ex: Wave) .
+
+
+
+
+
+
+
+
+
+
+
3
+
+
3
+
+
Faites vivre vos Réunions et AG
+ Gérez l'organisation des assemblées générales, traquez les présences lors des réunions statutaires et boostez l'engagement.
+
+
+
+
+
+
+
+
+
+
+
4
+
+
4
+
+
L'entraide Transparente
+ Sécurisez la gestion de vos cas sociaux (décès, maladie). Approuvez et décaissez les aides avec une traçabilité totale.
+
+
+
+
+
+
+
5
+
+
5
+
+
Scalabilité Absolue
+ Conçu pour évoluer : d'une amicale de quartier à un district international du Lions ou Rotary Club avec des milliers de membres.
+
+
+
+
+
+
+
+
+
6
+
+
6
+
+
Reporting et Audit
+ Générez des états financiers en un clic pour vos comptabilités et instaurez une gouvernance irréprochable.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sécurité de niveau entreprise
+
+
+ Authentification centralisée SSO, gestion des accès par rôle et traçabilité
+ complète de toutes les actions sur la plateforme.
+
+
+
+
+ Infrastructure hautement sécurisée
+
+
+
+ Chaque action est loggée et traçable
+
+
+
+ Droits de validation croisée stricts
+
+
+
+
+
+
+
+
+
+
+
+
+ Accessible partout, tout le temps
+
+
+ Une application web responsive et une application mobile native pour
+ que vos gestionnaires et membres restent connectés en toutes circonstances.
+
+
+
+
+ Web responsive (tous navigateurs)
+
+
+
+ Application mobile iOS & Android
+
+
+
+ Disponible 24h/24, 7j/7
+
+
+
+
+
+
+
+
+
+
+
+
+ Architecture ultra-rapide
+
+
+ Bâtie sur des technologies cloud de dernière génération, la plateforme reste
+ fluide et instantanée même avec des milliers de transactions.
+
+
+
+
+ Temps de réponse quasi-instantané
+
+
+
+ Scalabilité élastique
+
+
+
+ Sauvegardes automatisées
+
+
+
+
+
+
+
+
+
+
+
+
+ Pilotage par la donnée
+
+
+ Des tableaux de bord interactifs et des KPIs en temps réel pour prendre
+ les bonnes décisions au bon moment.
+
+
+
+
+ Dashboards et KPIs temps réel
+
+
+
+ Rapports exportables (PDF, Excel)
+
+
+
+ Analyse des tendances et historiques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Conçu pour les organisations du monde
+
+
+ Mutuelles, clubs Lions, associations sportives, fédérations professionnelles —
+ UnionFlow s'adapte à toute structure, sur tous les continents.
+
+
+
+
+ Mutuelles & caisses de solidarité
+
+
+
+ Clubs Lions, Rotary, associations civiques
+
+
+
+ Fédérations & réseaux multi-niveaux
+
+
+
+
+
+
+
+
+
+
+
+
+ Déploiement selon vos contraintes
+
+
+ Hébergez la plateforme chez vous ou laissez-nous la gérer. L'API ouverte
+ s'intègre facilement à vos outils existants.
+
+
+
+
+ SaaS cloud géré ou on-premise
+
+
+
+ API REST ouverte & documentée
+
+
+
+ Évolutions et support continus
+
+
+
+
+
+
+
+
+
+
+
+
6+
+
Types d'organisations supportés
+
+
+
100%
+
Données sécurisées et chiffrées
+
+
+
24/7
+
Disponibilité garantie
+
+
+
∞
+
Scalabilité cloud-native
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/admin/aides/gestion.xhtml b/src/main/resources/META-INF/resources/pages/admin/aides/gestion.xhtml
index 1ab5ef9..8baf90c 100644
--- a/src/main/resources/META-INF/resources/pages/admin/aides/gestion.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/aides/gestion.xhtml
@@ -1,595 +1,595 @@
-
-
-
- Gestion des Aides - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Gestion des Aides
-
-
#{aideBean.totalAides} aides • #{aideBean.montantDistribue} distribués • #{aideBean.budgetDisponible} disponible
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{aideBean.aidesActives}
-
Aides Actives
-
-
-
-
-
-
-
-
-
-
-
-
-
#{aideBean.montantDistribue}
-
Montant Distribué
-
-
-
-
-
-
-
-
-
-
-
-
-
#{aideBean.beneficiaires}
-
Bénéficiaires
-
-
-
-
-
-
-
-
-
-
-
-
-
#{aideBean.enAttente}
-
En Attente
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Budget des Aides
-
-
-
-
#{aideBean.budgetTotal}
-
Budget Total
-
-
-
-
-
#{aideBean.budgetUtilise}
-
Utilisé
-
-
-
-
-
#{aideBean.budgetDisponible}
-
Disponible
-
-
-
-
-
-
-
-
-
-
Prochaines Échéances
-
-
-
-
#{aide.beneficiaire}
-
#{aide.typeAide}
-
-
-
#{aide.prochainVersement}
-
#{aide.dateEcheance}
-
-
-
-
-
-
-
-
-
-
-
-
Évolution des Aides (12 derniers mois)
-
-
-
235
-
Total aides accordées cette année
-
-
-
-
-
-
-
Répartition par Type
-
-
-
-
-
-
-
-
- Gestion des Aides
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{aide.initialesBeneficiaire}
-
-
-
-
#{aide.nomCompletBeneficiaire}
-
- #{aide.numeroMembre}
- •
- #{aide.telephoneBeneficiaire}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{aide.montantTotal}
-
#{aide.frequence}
-
-
-
-
-
-
#{aide.montantVerse}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{aide.prochainVersementMontant}
-
#{aide.prochainVersementDate}
-
- -
-
-
-
-
-
-
-
-
-
-
- #{aideBean.selectedAides.size()} aide(s) sélectionnée(s)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{membre.initiales}
-
-
-
#{membre.nomComplet}
-
#{membre.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Aides - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Gestion des Aides
+
+
#{aideBean.totalAides} aides • #{aideBean.montantDistribue} distribués • #{aideBean.budgetDisponible} disponible
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{aideBean.aidesActives}
+
Aides Actives
+
+
+
+
+
+
+
+
+
+
+
+
+
#{aideBean.montantDistribue}
+
Montant Distribué
+
+
+
+
+
+
+
+
+
+
+
+
+
#{aideBean.beneficiaires}
+
Bénéficiaires
+
+
+
+
+
+
+
+
+
+
+
+
+
#{aideBean.enAttente}
+
En Attente
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Budget des Aides
+
+
+
+
#{aideBean.budgetTotal}
+
Budget Total
+
+
+
+
+
#{aideBean.budgetUtilise}
+
Utilisé
+
+
+
+
+
#{aideBean.budgetDisponible}
+
Disponible
+
+
+
+
+
+
+
+
+
+
Prochaines Échéances
+
+
+
+
#{aide.beneficiaire}
+
#{aide.typeAide}
+
+
+
#{aide.prochainVersement}
+
#{aide.dateEcheance}
+
+
+
+
+
+
+
+
+
+
+
+
Évolution des Aides (12 derniers mois)
+
+
+
235
+
Total aides accordées cette année
+
+
+
+
+
+
+
Répartition par Type
+
+
+
+
+
+
+
+
+ Gestion des Aides
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{aide.initialesBeneficiaire}
+
+
+
+
#{aide.nomCompletBeneficiaire}
+
+ #{aide.numeroMembre}
+ •
+ #{aide.telephoneBeneficiaire}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{aide.montantTotal}
+
#{aide.frequence}
+
+
+
+
+
+
#{aide.montantVerse}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{aide.prochainVersementMontant}
+
#{aide.prochainVersementDate}
+
+ -
+
+
+
+
+
+
+
+
+
+
+ #{aideBean.selectedAides.size()} aide(s) sélectionnée(s)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{membre.initiales}
+
+
+
#{membre.nomComplet}
+
#{membre.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/audit.xhtml b/src/main/resources/META-INF/resources/pages/admin/audit.xhtml
index 2ba44c0..7b9b911 100644
--- a/src/main/resources/META-INF/resources/pages/admin/audit.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/audit.xhtml
@@ -1,20 +1,20 @@
-
-
- UnionFlow - Administration Audit
-
-
-
-
-
Administration - Audit
-
Page d'administration en cours de développement...
-
-
-
-
-
-
+
+
+ UnionFlow - Administration Audit
+
+
+
+
+
Administration - Audit
+
Page d'administration en cours de développement...
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/admin/audit/journal.xhtml b/src/main/resources/META-INF/resources/pages/admin/audit/journal.xhtml
index f3296ba..7d197ca 100644
--- a/src/main/resources/META-INF/resources/pages/admin/audit/journal.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/audit/journal.xhtml
@@ -1,460 +1,460 @@
-
-
-
- Journal d'Audit - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Filtres de Recherche
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Journal d'Audit
-
-
-
-
-
-
#{log.dateFormatee}
-
#{log.heureFormatee}
-
-
-
-
-
-
-
-
-
-
-
-
#{log.utilisateur}
-
#{log.role}
-
-
-
-
-
-
-
- #{log.actionLibelle}
-
-
-
-
-
-
-
-
- #{log.description}
-
- #{log.details}
-
-
-
-
-
- #{log.ipAddress}
-
- #{log.userAgentCourt}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Informations Générales
-
-
-
-
-
Date/Heure
-
#{auditBean.evenementSelectionne.dateHeureComplete}
-
-
-
-
-
-
Utilisateur
-
#{auditBean.evenementSelectionne.utilisateur}
-
-
-
-
-
Rôle
-
#{auditBean.evenementSelectionne.role}
-
-
-
-
-
-
-
-
-
- Détails de l'Action
-
-
-
-
-
Description
-
#{auditBean.evenementSelectionne.description}
-
-
-
-
-
Détails
-
#{auditBean.evenementSelectionne.details}
-
-
-
-
-
Données Avant
-
#{auditBean.evenementSelectionne.donneesAvant}
-
-
-
-
-
Données Après
-
#{auditBean.evenementSelectionne.donneesApres}
-
-
-
-
-
-
-
-
-
- Informations Techniques
-
-
-
-
-
Adresse IP
-
#{auditBean.evenementSelectionne.ipAddress}
-
-
-
-
-
Session ID
-
#{auditBean.evenementSelectionne.sessionId}
-
-
-
-
-
User Agent
-
#{auditBean.evenementSelectionne.userAgent}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Journal d'Audit - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Filtres de Recherche
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Journal d'Audit
+
+
+
+
+
+
#{log.dateFormatee}
+
#{log.heureFormatee}
+
+
+
+
+
+
+
+
+
+
+
+
#{log.utilisateur}
+
#{log.role}
+
+
+
+
+
+
+
+ #{log.actionLibelle}
+
+
+
+
+
+
+
+
+ #{log.description}
+
+ #{log.details}
+
+
+
+
+
+ #{log.ipAddress}
+
+ #{log.userAgentCourt}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Informations Générales
+
+
+
+
+
Date/Heure
+
#{auditBean.evenementSelectionne.dateHeureComplete}
+
+
+
+
+
+
Utilisateur
+
#{auditBean.evenementSelectionne.utilisateur}
+
+
+
+
+
Rôle
+
#{auditBean.evenementSelectionne.role}
+
+
+
+
+
+
+
+
+
+ Détails de l'Action
+
+
+
+
+
Description
+
#{auditBean.evenementSelectionne.description}
+
+
+
+
+
Détails
+
#{auditBean.evenementSelectionne.details}
+
+
+
+
+
Données Avant
+
#{auditBean.evenementSelectionne.donneesAvant}
+
+
+
+
+
Données Après
+
#{auditBean.evenementSelectionne.donneesApres}
+
+
+
+
+
+
+
+
+
+ Informations Techniques
+
+
+
+
+
Adresse IP
+
#{auditBean.evenementSelectionne.ipAddress}
+
+
+
+
+
Session ID
+
#{auditBean.evenementSelectionne.sessionId}
+
+
+
+
+
User Agent
+
#{auditBean.evenementSelectionne.userAgent}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/admin/backup.xhtml b/src/main/resources/META-INF/resources/pages/admin/backup.xhtml
index 2ced305..1b878a5 100644
--- a/src/main/resources/META-INF/resources/pages/admin/backup.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/backup.xhtml
@@ -1,20 +1,20 @@
-
-
- UnionFlow - Administration Backup
-
-
-
-
-
Administration - Backup
-
Page d'administration en cours de développement...
-
-
-
-
-
-
+
+
+ UnionFlow - Administration Backup
+
+
+
+
+
Administration - Backup
+
Page d'administration en cours de développement...
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/admin/cotisations/gestion.xhtml b/src/main/resources/META-INF/resources/pages/admin/cotisations/gestion.xhtml
index 80f3cba..853226a 100644
--- a/src/main/resources/META-INF/resources/pages/admin/cotisations/gestion.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/cotisations/gestion.xhtml
@@ -1,909 +1,909 @@
-
-
-
- Gestion des Cotisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Liste des Cotisations
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisation.nomOrganisation}
-
#{cotisation.regionOrganisation}
-
-
-
-
-
-
-
- #{cotisation.initialesMembre}
-
-
-
#{cotisation.nomCompletMembre}
-
#{cotisation.numeroMembre} • #{cotisation.typeMembre}
-
-
-
-
-
-
-
-
-
-
-
#{cotisation.periode}
-
#{cotisation.annee}
-
-
-
-
- #{cotisation.montantFormatte} FCFA
-
-
-
-
-
-
-
-
-
#{cotisation.dateEcheanceFormattee}
-
#{cotisation.retardTexte}
-
-
-
-
-
-
#{cotisation.datePaiementFormattee}
-
-
- #{cotisation.modePaiementLibelle}
-
-
- Non payé
-
-
-
-
-
-
-
-
-
-
-
-
- #{cotisationsGestionBean.cotisationsSelectionnees.size()} cotisation(s) sélectionnée(s)
-
-
- Montant total: #{cotisationsGestionBean.montantTotalSelectionne}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Cotisations sélectionnées
-
#{cotisationsGestionBean.cotisationsSelectionnees.size()}
-
Montant total: #{cotisationsGestionBean.montantTotalSelectionne}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisationsGestionBean.cotisationDetail.numeroReference}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Progression du paiement
-
-
#{cotisationsGestionBean.cotisationDetail.pourcentagePaiement}%
-
-
-
-
-
- #{cotisationsGestionBean.cotisationDetail.retardTexte}
-
-
-
-
-
Observations
-
#{cotisationsGestionBean.cotisationDetail.observations}
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Cotisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Liste des Cotisations
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisation.nomOrganisation}
+
#{cotisation.regionOrganisation}
+
+
+
+
+
+
+
+ #{cotisation.initialesMembre}
+
+
+
#{cotisation.nomCompletMembre}
+
#{cotisation.numeroMembre} • #{cotisation.typeMembre}
+
+
+
+
+
+
+
+
+
+
+
#{cotisation.periode}
+
#{cotisation.annee}
+
+
+
+
+ #{cotisation.montantFormatte} FCFA
+
+
+
+
+
+
+
+
+
#{cotisation.dateEcheanceFormattee}
+
#{cotisation.retardTexte}
+
+
+
+
+
+
#{cotisation.datePaiementFormattee}
+
+
+ #{cotisation.modePaiementLibelle}
+
+
+ Non payé
+
+
+
+
+
+
+
+
+
+
+
+
+ #{cotisationsGestionBean.cotisationsSelectionnees.size()} cotisation(s) sélectionnée(s)
+
+
+ Montant total: #{cotisationsGestionBean.montantTotalSelectionne}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cotisations sélectionnées
+
#{cotisationsGestionBean.cotisationsSelectionnees.size()}
+
Montant total: #{cotisationsGestionBean.montantTotalSelectionne}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisationsGestionBean.cotisationDetail.numeroReference}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Progression du paiement
+
+
#{cotisationsGestionBean.cotisationDetail.pourcentagePaiement}%
+
+
+
+
+
+ #{cotisationsGestionBean.cotisationDetail.retardTexte}
+
+
+
+
+
Observations
+
#{cotisationsGestionBean.cotisationDetail.observations}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/demandes/aide-sociale.xhtml b/src/main/resources/META-INF/resources/pages/admin/demandes/aide-sociale.xhtml
index 2cbba59..f621789 100644
--- a/src/main/resources/META-INF/resources/pages/admin/demandes/aide-sociale.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/demandes/aide-sociale.xhtml
@@ -1,558 +1,558 @@
-
-
-
- Gestion des Demandes d'Aide - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Gestion des Demandes d'Aide
-
-
Traitement et suivi des demandes d'assistance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.totalDemandes}
-
Total Demandes
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.demandesEnAttente}
-
En Attente
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.demandesApprouvees}
-
Approuvées
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.montantTotalAide}
-
Aide Accordée
-
-
-
-
-
-
-
-
-
-
-
-
🚨 Demandes Prioritaires
-
-
-
-
-
-
-
-
-
-
-
#{demande.demandeur}
-
-
-
-
-
-
-
-
-
- #{demande.dateDemandeFormatee}
-
-
-
- #{demande.localisation}
-
-
-
- #{demande.montantDemandeFormatte}
-
-
-
-
- #{demande.motif}
-
-
-
-
#{demande.joursDepuisDemande} jours
-
-
-
-
-
-
-
-
-
-
-
-
-
📋 Workflow de Traitement
-
-
-
-
-
-
-
-
#{etape.libelle}
-
#{etape.nombre}
-
demandes
-
-
-
-
-
-
-
-
-
-
-
-
Filtres et Recherche
-
-
-
-
-
-
-
-
-
Demandes d'Aide (#{demandesAideBean.demandesFiltrees.size()})
-
-
-
-
-
- #{demandesAideBean.demandesFiltrees.size()} sur #{demandesAideBean.toutesLesDemandes.size()} demandes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demande.demandeur}
-
#{demande.telephone}
-
-
-
-
-
-
-
-
-
- #{demande.motif}
-
- #{demande.description.length() > 50 ? demande.description.substring(0, 50) + '...' : demande.description}
-
-
-
-
- #{demande.montantDemandeFormatte}
-
- Accordé: #{demande.montantAccordeFormatte}
-
-
-
-
- #{demande.dateDemandeFormatee}
- #{demande.joursDepuisDemande} jours
-
-
-
- #{demande.localisation}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Demandes d'Aide - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Gestion des Demandes d'Aide
+
+
Traitement et suivi des demandes d'assistance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.totalDemandes}
+
Total Demandes
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesEnAttente}
+
En Attente
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesApprouvees}
+
Approuvées
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.montantTotalAide}
+
Aide Accordée
+
+
+
+
+
+
+
+
+
+
+
+
🚨 Demandes Prioritaires
+
+
+
+
+
+
+
+
+
+
+
#{demande.demandeur}
+
+
+
+
+
+
+
+
+
+ #{demande.dateDemandeFormatee}
+
+
+
+ #{demande.localisation}
+
+
+
+ #{demande.montantDemandeFormatte}
+
+
+
+
+ #{demande.motif}
+
+
+
+
#{demande.joursDepuisDemande} jours
+
+
+
+
+
+
+
+
+
+
+
+
+
📋 Workflow de Traitement
+
+
+
+
+
+
+
+
#{etape.libelle}
+
#{etape.nombre}
+
demandes
+
+
+
+
+
+
+
+
+
+
+
+
Filtres et Recherche
+
+
+
+
+
+
+
+
+
Demandes d'Aide (#{demandesAideBean.demandesFiltrees.size()})
+
+
+
+
+
+ #{demandesAideBean.demandesFiltrees.size()} sur #{demandesAideBean.toutesLesDemandes.size()} demandes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demande.demandeur}
+
#{demande.telephone}
+
+
+
+
+
+
+
+
+
+ #{demande.motif}
+
+ #{demande.description.length() > 50 ? demande.description.substring(0, 50) + '...' : demande.description}
+
+
+
+
+ #{demande.montantDemandeFormatte}
+
+ Accordé: #{demande.montantAccordeFormatte}
+
+
+
+
+ #{demande.dateDemandeFormatee}
+ #{demande.joursDepuisDemande} jours
+
+
+
+ #{demande.localisation}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/demandes/gestion-old.xhtml b/src/main/resources/META-INF/resources/pages/admin/demandes/gestion-old.xhtml
index d7c7506..c7650ef 100644
--- a/src/main/resources/META-INF/resources/pages/admin/demandes/gestion-old.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/demandes/gestion-old.xhtml
@@ -1,561 +1,561 @@
-
-
-
- Gestion des Demandes d'Aide - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Gestion des Demandes d'Aide
-
-
Traitement et suivi des demandes d'assistance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandeBean.enAttente}
-
En Attente
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandeBean.urgentes}
-
Urgentes
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandeBean.traitees}
-
Traitées
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandeBean.delaiMoyenTraitement}
-
Délai Moyen (jours)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Demandes Urgentes
-
-
-
-
-
-
-
- #{demande.demandeur} • #{demande.numeroMembre}
-
-
- Déposée #{demande.dateDepotRelative} • Échéance: #{demande.dateEcheance}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Dernières Demandes
-
-
-
-
-
-
-
-
- #{demande.objet}
- #{demande.dateDepotRelative}
-
-
- #{demande.demandeur} • #{demande.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Évolution des Demandes
-
-
-
-
-
-
-
Répartition par Type
-
-
-
-
-
-
-
-
- Toutes les Demandes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{demande.initialesDemandeur}
-
-
-
#{demande.nomCompletDemandeur}
-
#{demande.numeroMembre} • #{demande.telephoneDemandeur}
-
-
-
-
-
-
-
-
-
-
#{demande.type}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demande.dateDepot}
-
#{demande.heureDepot}
-
-
-
-
-
-
-
-
-
-
-
- Non assignée
-
-
-
-
-
-
-
-
-
-
- #{demandeBean.selectedDemandes.size()} demande(s) sélectionnée(s)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{membre.initiales}
-
-
-
#{membre.nomComplet}
-
#{membre.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Demandes sélectionnées :
-
#{demandeBean.selectedDemandes.size()} demande(s) seront assignées
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Demandes d'Aide - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Gestion des Demandes d'Aide
+
+
Traitement et suivi des demandes d'assistance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandeBean.enAttente}
+
En Attente
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandeBean.urgentes}
+
Urgentes
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandeBean.traitees}
+
Traitées
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandeBean.delaiMoyenTraitement}
+
Délai Moyen (jours)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Demandes Urgentes
+
+
+
+
+
+
+
+ #{demande.demandeur} • #{demande.numeroMembre}
+
+
+ Déposée #{demande.dateDepotRelative} • Échéance: #{demande.dateEcheance}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dernières Demandes
+
+
+
+
+
+
+
+
+ #{demande.objet}
+ #{demande.dateDepotRelative}
+
+
+ #{demande.demandeur} • #{demande.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Évolution des Demandes
+
+
+
+
+
+
+
Répartition par Type
+
+
+
+
+
+
+
+
+ Toutes les Demandes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{demande.initialesDemandeur}
+
+
+
#{demande.nomCompletDemandeur}
+
#{demande.numeroMembre} • #{demande.telephoneDemandeur}
+
+
+
+
+
+
+
+
+
+
#{demande.type}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demande.dateDepot}
+
#{demande.heureDepot}
+
+
+
+
+
+
+
+
+
+
+
+ Non assignée
+
+
+
+
+
+
+
+
+
+
+ #{demandeBean.selectedDemandes.size()} demande(s) sélectionnée(s)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{membre.initiales}
+
+
+
#{membre.nomComplet}
+
#{membre.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Demandes sélectionnées :
+
#{demandeBean.selectedDemandes.size()} demande(s) seront assignées
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/demandes/gestion.xhtml b/src/main/resources/META-INF/resources/pages/admin/demandes/gestion.xhtml
index 45939d6..c9320d5 100644
--- a/src/main/resources/META-INF/resources/pages/admin/demandes/gestion.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/demandes/gestion.xhtml
@@ -1,714 +1,714 @@
-
-
-
- Gestion des Demandes d'Aide - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Toutes les Demandes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{demande.initialesDemandeur}
-
-
-
#{demande.nomCompletDemandeur}
-
#{demande.numeroMembre} • #{demande.telephoneDemandeur}
-
-
-
-
-
-
-
-
-
-
#{demande.type}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demande.heureDepot}
-
-
-
-
-
-
-
-
-
-
-
#{demande.dateDepotRelative}
-
-
-
-
-
- Non assignée
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Demandes d'Aide - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Toutes les Demandes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{demande.initialesDemandeur}
+
+
+
#{demande.nomCompletDemandeur}
+
#{demande.numeroMembre} • #{demande.telephoneDemandeur}
+
+
+
+
+
+
+
+
+
+
#{demande.type}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demande.heureDepot}
+
+
+
+
+
+
+
+
+
+
+
#{demande.dateDepotRelative}
+
+
+
+
+
+ Non assignée
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/admin/documents/gestion.xhtml b/src/main/resources/META-INF/resources/pages/admin/documents/gestion.xhtml
index 8cdf288..23f97c7 100644
--- a/src/main/resources/META-INF/resources/pages/admin/documents/gestion.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/documents/gestion.xhtml
@@ -1,613 +1,613 @@
-
-
-
- Gestion des Documents - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Filtres et Recherche
-
-
-
-
-
-
-
-
-
-
-
-
-
- Documents (#{documentsBean.documentsFiltres.size()})
-
-
-
-
-
-
-
- #{documentsBean.documentsFiltres.size()} sur #{documentsBean.tousLesDocuments.size()} documents
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{document.nom}
-
#{document.description}
-
-
-
-
-
- #{document.type}
-
-
-
-
-
-
-
- #{document.taille}
-
-
-
-
-
-
-
- #{document.dateCreationFormatee}
- #{document.dateCreationRelative}
-
-
-
-
- #{document.nombreVues}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Documents - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Filtres et Recherche
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Documents (#{documentsBean.documentsFiltres.size()})
+
+
+
+
+
+
+
+ #{documentsBean.documentsFiltres.size()} sur #{documentsBean.tousLesDocuments.size()} documents
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{document.nom}
+
#{document.description}
+
+
+
+
+
+ #{document.type}
+
+
+
+
+
+
+
+ #{document.taille}
+
+
+
+
+
+
+
+ #{document.dateCreationFormatee}
+ #{document.dateCreationRelative}
+
+
+
+
+ #{document.nombreVues}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml b/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml
index 2bce369..adba705 100644
--- a/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml
@@ -1,541 +1,541 @@
-
-
-
- Créer un Événement - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Créer un Nouvel Événement
-
-
Planifiez et organisez vos événements avec tous les détails nécessaires
-
-
-
-
-
-
-
-
-
-
Progression de création
-
-
-
-
-
Informations de base
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Informations de Base
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Date, Heure et Lieu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Participants et Inscription
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tarification et Paiement
-
-
-
-
-
-
-
-
-
-
Tarifs par catégorie
-
-
-
-
-
-
-
-
-
-
-
-
- Notifications et Communication
-
-
-
-
-
-
-
Rappels automatiques
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Documents et Pièces Jointes
-
-
-
-
-
-
-
-
-
-
Finalisation
-
-
-
-
-
Vérifiez toutes les informations
-
L'événement sera créé avec le statut "Planifié" et pourra être modifié ultérieurement
-
-
-
-
-
-
-
-
-
- Les données de l'événement sont sécurisées et conformes RGPD
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{creationEvenementBean.evenement.titre}
-
#{creationEvenementBean.evenement.typeEvenementLibelle}
-
-
-
-
-
-
-
📅 Date et Heure
-
#{creationEvenementBean.evenement.dateCompleteFormatee}
-
-
📍 Lieu
-
#{creationEvenementBean.evenement.lieu}
-
#{creationEvenementBean.evenement.adresse}
-
-
👥 Participants
-
Maximum #{creationEvenementBean.evenement.placesMax} places
-
Public: #{creationEvenementBean.evenement.publicCibleFormate}
-
-
-
-
💰 Tarification
-
- Gratuit
-
- Prix: #{creationEvenementBean.evenement.prix} FCFA
-
-
-
-
🔔 Notifications
-
Canaux: #{creationEvenementBean.evenement.canauxNotificationFormates}
-
-
👨💼 Organisateur
-
#{creationEvenementBean.evenement.organisateur}
-
-
-
-
📝 Description
-
#{creationEvenementBean.evenement.description}
-
-
-
-
-
-
-
-
-
+
+
+
+ Créer un Événement - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Créer un Nouvel Événement
+
+
Planifiez et organisez vos événements avec tous les détails nécessaires
+
+
+
+
+
+
+
+
+
+
Progression de création
+
+
+
+
+
Informations de base
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Informations de Base
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Date, Heure et Lieu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Participants et Inscription
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tarification et Paiement
+
+
+
+
+
+
+
+
+
+
Tarifs par catégorie
+
+
+
+
+
+
+
+
+
+
+
+
+ Notifications et Communication
+
+
+
+
+
+
+
Rappels automatiques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Documents et Pièces Jointes
+
+
+
+
+
+
+
+
+
+
Finalisation
+
+
+
+
+
Vérifiez toutes les informations
+
L'événement sera créé avec le statut "Planifié" et pourra être modifié ultérieurement
+
+
+
+
+
+
+
+
+
+ Les données de l'événement sont sécurisées et conformes RGPD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{creationEvenementBean.evenement.titre}
+
#{creationEvenementBean.evenement.typeEvenementLibelle}
+
+
+
+
+
+
+
📅 Date et Heure
+
#{creationEvenementBean.evenement.dateCompleteFormatee}
+
+
📍 Lieu
+
#{creationEvenementBean.evenement.lieu}
+
#{creationEvenementBean.evenement.adresse}
+
+
👥 Participants
+
Maximum #{creationEvenementBean.evenement.placesMax} places
+
Public: #{creationEvenementBean.evenement.publicCibleFormate}
+
+
+
+
💰 Tarification
+
+ Gratuit
+
+ Prix: #{creationEvenementBean.evenement.prix} FCFA
+
+
+
+
🔔 Notifications
+
Canaux: #{creationEvenementBean.evenement.canauxNotificationFormates}
+
+
👨💼 Organisateur
+
#{creationEvenementBean.evenement.organisateur}
+
+
+
+
📝 Description
+
#{creationEvenementBean.evenement.description}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml b/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml
index fe62f42..b377bbf 100644
--- a/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml
@@ -1,588 +1,588 @@
-
-
-
- Gestion des Événements - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Événements à Venir
-
-
-
-
-
-
-
-
-
- Filtres et Recherche
-
-
-
-
-
-
-
-
-
-
-
-
-
- Liste des Événements
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{evenement.titre}
-
#{evenement.description}
-
-
-
-
-
-
-
-
-
-
-
#{evenement.dateDebutFormatee}
-
#{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}
-
-
-
-
-
-
#{evenement.lieu}
-
#{evenement.adresse}
-
-
-
-
-
-
-
-
#{evenement.organisateur}
-
#{evenement.organisateurEmail}
-
-
-
- Aucun organisateur
-
-
-
-
-
-
#{evenement.participantsInscrits}
-
/#{evenement.capaciteMax} places
-
-
-
-
-
- #{evenement.budgetFormatte}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Événement sélectionné
-
#{evenementsBean.evenementSelectionne.titre}
-
#{evenementsBean.evenementSelectionne.dateDebutFormatee}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Événements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Événements à Venir
+
+
+
+
+
+
+
+
+
+ Filtres et Recherche
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Liste des Événements
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{evenement.titre}
+
#{evenement.description}
+
+
+
+
+
+
+
+
+
+
+
#{evenement.dateDebutFormatee}
+
#{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}
+
+
+
+
+
+
#{evenement.lieu}
+
#{evenement.adresse}
+
+
+
+
+
+
+
+
#{evenement.organisateur}
+
#{evenement.organisateurEmail}
+
+
+
+ Aucun organisateur
+
+
+
+
+
+
#{evenement.participantsInscrits}
+
/#{evenement.capaciteMax} places
+
+
+
+
+
+ #{evenement.budgetFormatte}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Événement sélectionné
+
#{evenementsBean.evenementSelectionne.titre}
+
#{evenementsBean.evenementSelectionne.dateDebutFormatee}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml b/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml
index 451209e..f24c43b 100644
--- a/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml
@@ -1,430 +1,430 @@
-
-
-
- Gestion des Événements - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Gestion des Événements
-
-
#{evenementBean.totalEvenements} événements • #{evenementBean.evenementsActifs} actifs • #{evenementBean.prochainEvenement}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{evenementBean.evenementsActifs}
-
Événements Actifs
-
-
-
-
-
-
-
-
-
-
-
-
-
#{evenementBean.totalParticipants}
-
Participants Inscrits
-
-
-
-
-
-
-
-
-
-
-
-
-
#{evenementBean.revenusEvenements}
-
Revenus Événements
-
-
-
-
-
-
-
-
-
-
-
-
-
#{evenementBean.tauxParticipation}%
-
Taux Participation
-
-
-
-
-
-
-
-
-
-
-
-
-
- Prochains Événements
-
-
-
-
-
-
-
-
#{event.dateFormatee}
-
#{event.titre}
-
-
-
-
-
- #{event.lieu}
-
-
-
- #{event.inscrits}/#{event.placesMax} inscrits
-
-
-
-
-
-
-
-
-
-
-
-
- Tous les Événements
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{evenement.titre}
-
#{evenement.typeEvenementLibelle}
-
-
-
-
-
-
-
#{evenement.dateDebut}
-
#{evenement.heureDebut} - #{evenement.heureFin}
-
-
-
-
-
-
- #{evenement.lieu}
-
-
-
-
-
-
-
-
-
-
#{evenement.nombreInscrits}/#{evenement.placesMax}
-
-
-
-
-
-
-
-
- Gratuit
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{evenementBean.selectedEvenements.size()} événement(s) sélectionné(s)
-
-
-
-
-
-
-
-
-
-
- Vue Calendrier
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Titre
-
#{evenementBean.evenementSelectionne.titre}
-
-
-
-
Type
-
#{evenementBean.evenementSelectionne.typeEvenementLibelle}
-
-
-
-
Date et heure
-
- #{evenementBean.evenementSelectionne.dateComplete}
-
-
-
-
-
Lieu
-
#{evenementBean.evenementSelectionne.lieu}
-
-
-
-
-
-
-
-
Participants
-
- #{evenementBean.evenementSelectionne.nombreInscrits}/#{evenementBean.evenementSelectionne.placesMax}
-
-
-
-
-
Prix
-
-
-
-
- Gratuit
-
-
-
-
-
Organisateur
-
#{evenementBean.evenementSelectionne.organisateur}
-
-
-
-
-
-
Description
-
#{evenementBean.evenementSelectionne.description}
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Événements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Gestion des Événements
+
+
#{evenementBean.totalEvenements} événements • #{evenementBean.evenementsActifs} actifs • #{evenementBean.prochainEvenement}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{evenementBean.evenementsActifs}
+
Événements Actifs
+
+
+
+
+
+
+
+
+
+
+
+
+
#{evenementBean.totalParticipants}
+
Participants Inscrits
+
+
+
+
+
+
+
+
+
+
+
+
+
#{evenementBean.revenusEvenements}
+
Revenus Événements
+
+
+
+
+
+
+
+
+
+
+
+
+
#{evenementBean.tauxParticipation}%
+
Taux Participation
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Prochains Événements
+
+
+
+
+
+
+
+
#{event.dateFormatee}
+
#{event.titre}
+
+
+
+
+
+ #{event.lieu}
+
+
+
+ #{event.inscrits}/#{event.placesMax} inscrits
+
+
+
+
+
+
+
+
+
+
+
+
+ Tous les Événements
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{evenement.titre}
+
#{evenement.typeEvenementLibelle}
+
+
+
+
+
+
+
#{evenement.dateDebut}
+
#{evenement.heureDebut} - #{evenement.heureFin}
+
+
+
+
+
+
+ #{evenement.lieu}
+
+
+
+
+
+
+
+
+
+
#{evenement.nombreInscrits}/#{evenement.placesMax}
+
+
+
+
+
+
+
+
+ Gratuit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{evenementBean.selectedEvenements.size()} événement(s) sélectionné(s)
+
+
+
+
+
+
+
+
+
+
+ Vue Calendrier
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Titre
+
#{evenementBean.evenementSelectionne.titre}
+
+
+
+
Type
+
#{evenementBean.evenementSelectionne.typeEvenementLibelle}
+
+
+
+
Date et heure
+
+ #{evenementBean.evenementSelectionne.dateComplete}
+
+
+
+
+
Lieu
+
#{evenementBean.evenementSelectionne.lieu}
+
+
+
+
+
+
+
+
Participants
+
+ #{evenementBean.evenementSelectionne.nombreInscrits}/#{evenementBean.evenementSelectionne.placesMax}
+
+
+
+
+
Prix
+
+
+
+
+ Gratuit
+
+
+
+
+
Organisateur
+
#{evenementBean.evenementSelectionne.organisateur}
+
+
+
+
+
+
Description
+
#{evenementBean.evenementSelectionne.description}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/evenements/participants.xhtml b/src/main/resources/META-INF/resources/pages/admin/evenements/participants.xhtml
index ab9ee4b..672cd33 100644
--- a/src/main/resources/META-INF/resources/pages/admin/evenements/participants.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/evenements/participants.xhtml
@@ -1,517 +1,517 @@
-
-
-
- Gestion des Participants - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Gestion des Participants
-
-
#{participantBean.evenement.titre} • #{participantBean.dateEvenement} • #{participantBean.nombreInscrits}/#{participantBean.placesMax} places
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{participantBean.nombreInscrits}
-
Inscrits Confirmés
-
-
-
-
-
-
-
-
#{participantBean.tauxRemplissage}% de remplissage
-
-
-
-
-
-
-
-
-
#{participantBean.enAttente}
-
En Attente
-
-
-
-
-
-
-
-
-
-
-
-
-
#{participantBean.montantCollecte}
-
Collecté
-
-
-
-
-
-
-
-
-
-
-
-
-
#{participantBean.accompagnateurs}
-
Accompagnateurs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Liste des Participants
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{participant.initiales}
-
-
-
-
#{participant.nomComplet}
-
- #{participant.numeroMembre}
- •
- #{participant.telephone}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{participant.dateInscription}
-
#{participant.heureInscription}
-
-
-
-
-
-
#{participant.montantPaye}
-
-
-
-
-
-
- #{participant.nombreAccompagnateurs}
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- #{participantBean.selectedParticipants.size()} participant(s) sélectionné(s)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{membre.initiales}
-
-
-
#{membre.nomComplet}
-
#{membre.numeroMembre} • #{membre.typeMembre}
-
-
-
-
-
-
-
-
-
-
-
#{participantBean.montantAPayer} FCFA
-
#{participantBean.detailTarification}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{p.initiales}
-
-
-
#{p.nomComplet}
-
#{p.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Participants - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Gestion des Participants
+
+
#{participantBean.evenement.titre} • #{participantBean.dateEvenement} • #{participantBean.nombreInscrits}/#{participantBean.placesMax} places
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{participantBean.nombreInscrits}
+
Inscrits Confirmés
+
+
+
+
+
+
+
+
#{participantBean.tauxRemplissage}% de remplissage
+
+
+
+
+
+
+
+
+
#{participantBean.enAttente}
+
En Attente
+
+
+
+
+
+
+
+
+
+
+
+
+
#{participantBean.montantCollecte}
+
Collecté
+
+
+
+
+
+
+
+
+
+
+
+
+
#{participantBean.accompagnateurs}
+
Accompagnateurs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Liste des Participants
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{participant.initiales}
+
+
+
+
#{participant.nomComplet}
+
+ #{participant.numeroMembre}
+ •
+ #{participant.telephone}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{participant.dateInscription}
+
#{participant.heureInscription}
+
+
+
+
+
+
#{participant.montantPaye}
+
+
+
+
+
+
+ #{participant.nombreAccompagnateurs}
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+ #{participantBean.selectedParticipants.size()} participant(s) sélectionné(s)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{membre.initiales}
+
+
+
#{membre.nomComplet}
+
#{membre.numeroMembre} • #{membre.typeMembre}
+
+
+
+
+
+
+
+
+
+
+
#{participantBean.montantAPayer} FCFA
+
#{participantBean.detailTarification}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{p.initiales}
+
+
+
#{p.nomComplet}
+
#{p.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/finance/caisse.xhtml b/src/main/resources/META-INF/resources/pages/admin/finance/caisse.xhtml
index 7f9c9f5..8d1c539 100644
--- a/src/main/resources/META-INF/resources/pages/admin/finance/caisse.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/finance/caisse.xhtml
@@ -1,385 +1,385 @@
-
-
-
- Caisse de l'Entité - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Caisse de l'Entité
-
-
#{caisseBean.nomEntite} • Dernière mise à jour: #{caisseBean.derniereMAJ}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Répartition par Catégorie
-
-
-
-
-
-
-
-
- Journal de Caisse
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{mouvement.modePaiement}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Total Entrées
-
#{caisseBean.totalEntreesPeriode}
-
-
-
-
-
Total Sorties
-
#{caisseBean.totalSortiesPeriode}
-
-
-
-
-
Solde Période
-
#{caisseBean.soldePeriode}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Caisse de l'Entité - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Caisse de l'Entité
+
+
#{caisseBean.nomEntite} • Dernière mise à jour: #{caisseBean.derniereMAJ}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Répartition par Catégorie
+
+
+
+
+
+
+
+
+ Journal de Caisse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{mouvement.modePaiement}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Total Entrées
+
#{caisseBean.totalEntreesPeriode}
+
+
+
+
+
Total Sorties
+
#{caisseBean.totalSortiesPeriode}
+
+
+
+
+
Solde Période
+
#{caisseBean.soldePeriode}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/rapports/finances.xhtml b/src/main/resources/META-INF/resources/pages/admin/rapports/finances.xhtml
index 9cfb019..b1a4a80 100644
--- a/src/main/resources/META-INF/resources/pages/admin/rapports/finances.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/rapports/finances.xhtml
@@ -1,449 +1,449 @@
-
-
-
- Rapports Financiers - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Rapports Financiers
-
-
Analyse complète de la situation financière • #{rapportBean.periodeAnalyse}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Évolution Revenus vs Dépenses
-
📊
Graphique en cours de développement
-
-
-
-
-
-
-
Sources de Revenus
-
📊
Graphique en cours de développement
-
-
-
-
-
-
-
Catégories de Dépenses
-
📊
Graphique en cours de développement
-
-
-
-
-
-
-
Cash Flow Mensuel
-
📊
Graphique en cours de développement
-
-
-
-
-
-
-
-
-
-
-
-
Top 10 Contributeurs
-
-
-
-
- #{status.index + 1}
-
-
-
#{contributeur.nom}
-
#{contributeur.numeroMembre}
-
-
-
-
#{contributeur.montantTotal}
-
#{contributeur.nombreContributions} contributions
-
-
-
-
-
-
-
-
-
-
Prévisions Financières
-
-
- Revenus prévus (3 mois)
- #{rapportBean.revenusPrevus3Mois}
-
-
- Dépenses prévues (3 mois)
- #{rapportBean.depensesPrevues3Mois}
-
-
- Solde prévisionnel
- #{rapportBean.soldePrevisionnel}
-
-
-
-
Recommandations
-
-
-
- #{recommandation}
-
-
-
-
-
-
-
-
-
- Détail des Transactions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{revenu.modePaiement}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Indicateurs Clés de Performance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Rapports Financiers - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Rapports Financiers
+
+
Analyse complète de la situation financière • #{rapportBean.periodeAnalyse}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Évolution Revenus vs Dépenses
+
📊
Graphique en cours de développement
+
+
+
+
+
+
+
Sources de Revenus
+
📊
Graphique en cours de développement
+
+
+
+
+
+
+
Catégories de Dépenses
+
📊
Graphique en cours de développement
+
+
+
+
+
+
+
Cash Flow Mensuel
+
📊
Graphique en cours de développement
+
+
+
+
+
+
+
+
+
+
+
+
Top 10 Contributeurs
+
+
+
+
+ #{status.index + 1}
+
+
+
#{contributeur.nom}
+
#{contributeur.numeroMembre}
+
+
+
+
#{contributeur.montantTotal}
+
#{contributeur.nombreContributions} contributions
+
+
+
+
+
+
+
+
+
+
Prévisions Financières
+
+
+ Revenus prévus (3 mois)
+ #{rapportBean.revenusPrevus3Mois}
+
+
+ Dépenses prévues (3 mois)
+ #{rapportBean.depensesPrevues3Mois}
+
+
+ Solde prévisionnel
+ #{rapportBean.soldePrevisionnel}
+
+
+
+
Recommandations
+
+
+
+ #{recommandation}
+
+
+
+
+
+
+
+
+
+ Détail des Transactions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{revenu.modePaiement}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Indicateurs Clés de Performance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/rapports/statistiques.xhtml b/src/main/resources/META-INF/resources/pages/admin/rapports/statistiques.xhtml
index 1ce4092..4834cf5 100644
--- a/src/main/resources/META-INF/resources/pages/admin/rapports/statistiques.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/rapports/statistiques.xhtml
@@ -1,566 +1,566 @@
-
-
-
- Rapports et Statistiques - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
- Période d'Analyse
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alertes et Recommandations
-
-
-
-
-
-
-
-
-
-
- Historique des Rapports
-
-
-
-
- #{rapport.dateGenerationFormatee}
-
-
-
-
-
- #{rapport.typeLibelle}
-
-
-
-
- #{rapport.periodeCouverte}
-
-
-
- #{rapport.generePar}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Rapports et Statistiques - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+ Période d'Analyse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Alertes et Recommandations
+
+
+
+
+
+
+
+
+
+
+ Historique des Rapports
+
+
+
+
+ #{rapport.dateGenerationFormatee}
+
+
+
+
+
+ #{rapport.typeLibelle}
+
+
+
+
+ #{rapport.periodeCouverte}
+
+
+
+ #{rapport.generePar}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/admin/settings.xhtml b/src/main/resources/META-INF/resources/pages/admin/settings.xhtml
index 177d4d9..ef459c2 100644
--- a/src/main/resources/META-INF/resources/pages/admin/settings.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/settings.xhtml
@@ -1,20 +1,20 @@
-
-
- UnionFlow - Administration Settings
-
-
-
-
-
Administration - Settings
-
Page d'administration en cours de développement...
-
-
-
-
-
-
+
+
+ UnionFlow - Administration Settings
+
+
+
+
+
Administration - Settings
+
Page d'administration en cours de développement...
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/admin/users.xhtml b/src/main/resources/META-INF/resources/pages/admin/users.xhtml
index 09801ab..975fd69 100644
--- a/src/main/resources/META-INF/resources/pages/admin/users.xhtml
+++ b/src/main/resources/META-INF/resources/pages/admin/users.xhtml
@@ -1,20 +1,20 @@
-
-
- UnionFlow - Administration Users
-
-
-
-
-
Administration - Users
-
Page d'administration en cours de développement...
-
-
-
-
-
-
+
+
+ UnionFlow - Administration Users
+
+
+
+
+
Administration - Users
+
Page d'administration en cours de développement...
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/membre/cotisations.xhtml b/src/main/resources/META-INF/resources/pages/membre/cotisations.xhtml
index d3dfac2..a6b5550 100644
--- a/src/main/resources/META-INF/resources/pages/membre/cotisations.xhtml
+++ b/src/main/resources/META-INF/resources/pages/membre/cotisations.xhtml
@@ -1,575 +1,575 @@
-
-
-
- Mes Cotisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Mes Cotisations
-
-
Membre #{membreCotisationBean.numeroMembre} • Statut: #{membreCotisationBean.statutCotisations} • Dernière mise à jour: #{membreCotisationBean.derniereMAJ}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreCotisationBean.cotisationsPayees}
-
Cotisations Payées
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreCotisationBean.cotisationsEnAttente}
-
En Attente
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreCotisationBean.montantDu}
-
Montant Dû
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreCotisationBean.totalVerse}
-
Total Versé 2024
-
-
-
-
-
-
-
-
-
-
-
-
-
- Prochaines Échéances
-
-
-
-
-
-
-
-
#{echeance.libelle}
-
#{echeance.periode}
-
-
-
-
-
-
#{echeance.montant}
-
Échéance: #{echeance.dateEcheance}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Historique des Paiements
-
-
-
-
Jan-Mar
-
15,000 FCFA
-
-
-
-
-
Avr-Juin
-
15,000 FCFA
-
-
-
-
-
Jul-Sep
-
15,000 FCFA
-
-
-
-
-
Oct-Déc
-
10,000 FCFA
-
-
-
-
-
55,000 FCFA
-
Total versé en 2024
-
-
-
-
-
-
-
Ma Situation
-
-
-
-
Type: #{membreCotisationBean.typeMembre}
-
-
-
-
- Cotisation Mensuelle
- #{membreCotisationBean.cotisationMensuelle}
-
-
Basée sur votre type de membre
-
-
-
-
- Ponctualité
- #{membreCotisationBean.scorePonctualite}%
-
-
-
#{membreCotisationBean.commentairePonctualite}
-
-
-
-
-
-
Moyens de Paiement
-
-
-
-
-
-
Wave Money
-
Paiement mobile instantané
-
-
-
-
-
-
-
Espèces
-
Paiement auprès du trésorier
-
-
-
-
-
-
-
Virement Bancaire
-
Transfert vers compte association
-
-
-
-
-
-
-
-
-
-
- Historique de mes Cotisations
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisation.libelle}
-
#{cotisation.periode}
-
-
-
-
-
-
-
-
-
-
#{cotisation.montant}
-
FCFA
-
-
-
-
-
-
-
-
-
-
#{cotisation.dateEcheance}
-
#{cotisation.statutEcheance}
-
-
-
-
-
-
-
- Non payée
-
-
-
-
-
- #{cotisation.modePaiement}
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
Total Payé
-
#{membreCotisationBean.totalPayePeriode}
-
-
-
-
-
En Attente
-
#{membreCotisationBean.totalEnAttentePeriode}
-
-
-
-
-
En Retard
-
#{membreCotisationBean.totalEnRetardPeriode}
-
-
-
-
-
Taux Conformité
-
#{membreCotisationBean.tauxConformite}%
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Paiement sécurisé
-
Toutes les transactions sont cryptées et sécurisées
-
-
-
-
-
-
-
-
-
-
-
-
-
Coordonnées bancaires
-
-
Banque: #{membreCotisationBean.banqueAssociation}
-
IBAN: #{membreCotisationBean.ibanAssociation}
-
Référence: [Votre numéro membre]
-
-
-
-
-
-
-
-
- Montant total:
- #{membreCotisationBean.montantAPayer} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Service sécurisé
-
Vos cotisations seront automatiquement prélevées chaque mois
-
-
-
-
-
-
-
-
-
-
-
-
Conditions:
-
- Montant mensuel: #{membreCotisationBean.cotisationMensuelle} FCFA
- Vous pouvez suspendre à tout moment
- Notification 24h avant chaque prélèvement
-
-
-
-
-
-
-
-
-
+
+
+
+ Mes Cotisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Mes Cotisations
+
+
Membre #{membreCotisationBean.numeroMembre} • Statut: #{membreCotisationBean.statutCotisations} • Dernière mise à jour: #{membreCotisationBean.derniereMAJ}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreCotisationBean.cotisationsPayees}
+
Cotisations Payées
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreCotisationBean.cotisationsEnAttente}
+
En Attente
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreCotisationBean.montantDu}
+
Montant Dû
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreCotisationBean.totalVerse}
+
Total Versé 2024
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Prochaines Échéances
+
+
+
+
+
+
+
+
#{echeance.libelle}
+
#{echeance.periode}
+
+
+
+
+
+
#{echeance.montant}
+
Échéance: #{echeance.dateEcheance}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Historique des Paiements
+
+
+
+
Jan-Mar
+
15,000 FCFA
+
+
+
+
+
Avr-Juin
+
15,000 FCFA
+
+
+
+
+
Jul-Sep
+
15,000 FCFA
+
+
+
+
+
Oct-Déc
+
10,000 FCFA
+
+
+
+
+
55,000 FCFA
+
Total versé en 2024
+
+
+
+
+
+
+
Ma Situation
+
+
+
+
Type: #{membreCotisationBean.typeMembre}
+
+
+
+
+ Cotisation Mensuelle
+ #{membreCotisationBean.cotisationMensuelle}
+
+
Basée sur votre type de membre
+
+
+
+
+ Ponctualité
+ #{membreCotisationBean.scorePonctualite}%
+
+
+
#{membreCotisationBean.commentairePonctualite}
+
+
+
+
+
+
Moyens de Paiement
+
+
+
+
+
+
Wave Money
+
Paiement mobile instantané
+
+
+
+
+
+
+
Espèces
+
Paiement auprès du trésorier
+
+
+
+
+
+
+
Virement Bancaire
+
Transfert vers compte association
+
+
+
+
+
+
+
+
+
+
+ Historique de mes Cotisations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisation.libelle}
+
#{cotisation.periode}
+
+
+
+
+
+
+
+
+
+
#{cotisation.montant}
+
FCFA
+
+
+
+
+
+
+
+
+
+
#{cotisation.dateEcheance}
+
#{cotisation.statutEcheance}
+
+
+
+
+
+
+
+ Non payée
+
+
+
+
+
+ #{cotisation.modePaiement}
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
Total Payé
+
#{membreCotisationBean.totalPayePeriode}
+
+
+
+
+
En Attente
+
#{membreCotisationBean.totalEnAttentePeriode}
+
+
+
+
+
En Retard
+
#{membreCotisationBean.totalEnRetardPeriode}
+
+
+
+
+
Taux Conformité
+
#{membreCotisationBean.tauxConformite}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Paiement sécurisé
+
Toutes les transactions sont cryptées et sécurisées
+
+
+
+
+
+
+
+
+
+
+
+
+
Coordonnées bancaires
+
+
Banque: #{membreCotisationBean.banqueAssociation}
+
IBAN: #{membreCotisationBean.ibanAssociation}
+
Référence: [Votre numéro membre]
+
+
+
+
+
+
+
+
+ Montant total:
+ #{membreCotisationBean.montantAPayer} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Service sécurisé
+
Vos cotisations seront automatiquement prélevées chaque mois
+
+
+
+
+
+
+
+
+
+
+
+
Conditions:
+
+ Montant mensuel: #{membreCotisationBean.cotisationMensuelle} FCFA
+ Vous pouvez suspendre à tout moment
+ Notification 24h avant chaque prélèvement
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/membre/dashboard.xhtml b/src/main/resources/META-INF/resources/pages/membre/dashboard.xhtml
index 38f2b35..fc03b0b 100644
--- a/src/main/resources/META-INF/resources/pages/membre/dashboard.xhtml
+++ b/src/main/resources/META-INF/resources/pages/membre/dashboard.xhtml
@@ -1,385 +1,385 @@
-
-
-
- Mon Tableau de Bord - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
- #{membreDashboardBean.membre.initiales}
-
-
-
-
Bonjour #{membreDashboardBean.membre.prenom} ! 👋
-
-
- #{membreDashboardBean.membre.numeroMembre} • #{membreDashboardBean.membre.typeMembre}
-
-
-
- Membre depuis #{membreDashboardBean.membre.dateAdhesionFormatee}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreDashboardBean.statutCotisations}
-
Statut Cotisations
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreDashboardBean.evenementsInscrits}
-
Événements à venir
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreDashboardBean.aidesRecues}
-
Aides Reçues
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreDashboardBean.messagesNonLus}
-
Messages Non Lus
-
-
-
-
-
-
-
-
-
-
-
-
-
- Notifications Importantes
-
-
-
-
-
-
#{alerte.titre}
-
#{alerte.message}
-
#{alerte.dateRelative}
-
-
-
-
-
-
-
-
-
-
-
Actions Rapides
-
-
-
-
-
Cotisations
-
Consultez votre situation et payez en ligne
-
-
-
-
-
-
-
-
-
-
Événements
-
Découvrez et inscrivez-vous aux événements
-
-
-
-
-
-
-
-
-
-
Demandes
-
Faites une demande d'aide ou de service
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mes Prochains Événements
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{evenement.dateComplete}
-
-
-
- #{evenement.lieu}
-
-
- #{evenement.prixFormate}
- #{evenement.nombreParticipants} participants
-
-
-
-
-
-
-
-
-
-
-
Aucun événement à venir
-
-
-
-
-
-
-
-
-
-
-
- Ma Situation
-
-
-
-
- Cotisations 2024
- #{membreDashboardBean.cotisationsPayees}/#{membreDashboardBean.cotisationsTotales}
-
-
-
-
-
-
- Participation aux événements
- #{membreDashboardBean.tauxParticipation}%
-
-
#{membreDashboardBean.evenementsAssistes} événements cette année
-
-
-
-
- Ancienneté
- #{membreDashboardBean.anciennete}
-
-
Membre depuis #{membreDashboardBean.dateAdhesionFormatee}
-
-
-
-
-
-
-
- Rappels
-
-
-
-
-
-
-
#{rappel.titre}
-
#{rappel.echeance}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Activité Récente
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{activite.titre}
-
#{activite.description}
-
#{activite.dateRelative}
-
-
-
-
-
-
-
-
Aucune activité récente
-
-
-
-
-
-
-
+
+
+
+ Mon Tableau de Bord - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+ #{membreDashboardBean.membre.initiales}
+
+
+
+
Bonjour #{membreDashboardBean.membre.prenom} ! 👋
+
+
+ #{membreDashboardBean.membre.numeroMembre} • #{membreDashboardBean.membre.typeMembre}
+
+
+
+ Membre depuis #{membreDashboardBean.membre.dateAdhesionFormatee}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreDashboardBean.statutCotisations}
+
Statut Cotisations
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreDashboardBean.evenementsInscrits}
+
Événements à venir
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreDashboardBean.aidesRecues}
+
Aides Reçues
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreDashboardBean.messagesNonLus}
+
Messages Non Lus
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Notifications Importantes
+
+
+
+
+
+
#{alerte.titre}
+
#{alerte.message}
+
#{alerte.dateRelative}
+
+
+
+
+
+
+
+
+
+
+
Actions Rapides
+
+
+
+
+
Cotisations
+
Consultez votre situation et payez en ligne
+
+
+
+
+
+
+
+
+
+
Événements
+
Découvrez et inscrivez-vous aux événements
+
+
+
+
+
+
+
+
+
+
Demandes
+
Faites une demande d'aide ou de service
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mes Prochains Événements
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{evenement.dateComplete}
+
+
+
+ #{evenement.lieu}
+
+
+ #{evenement.prixFormate}
+ #{evenement.nombreParticipants} participants
+
+
+
+
+
+
+
+
+
+
+
Aucun événement à venir
+
+
+
+
+
+
+
+
+
+
+
+ Ma Situation
+
+
+
+
+ Cotisations 2024
+ #{membreDashboardBean.cotisationsPayees}/#{membreDashboardBean.cotisationsTotales}
+
+
+
+
+
+
+ Participation aux événements
+ #{membreDashboardBean.tauxParticipation}%
+
+
#{membreDashboardBean.evenementsAssistes} événements cette année
+
+
+
+
+ Ancienneté
+ #{membreDashboardBean.anciennete}
+
+
Membre depuis #{membreDashboardBean.dateAdhesionFormatee}
+
+
+
+
+
+
+
+ Rappels
+
+
+
+
+
+
+
#{rappel.titre}
+
#{rappel.echeance}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Activité Récente
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{activite.titre}
+
#{activite.description}
+
#{activite.dateRelative}
+
+
+
+
+
+
+
+
Aucune activité récente
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/public/formulaires.xhtml b/src/main/resources/META-INF/resources/pages/public/formulaires.xhtml
index 04fda58..ca37fcb 100644
--- a/src/main/resources/META-INF/resources/pages/public/formulaires.xhtml
+++ b/src/main/resources/META-INF/resources/pages/public/formulaires.xhtml
@@ -1,294 +1,294 @@
-
-
-
- Nos Formulaires - UnionFlow
-
-
-
-
-
-
-
-
-
-
Choisissez votre formule
-
- Des solutions adaptées à chaque taille d'organisation
-
-
- Gérez efficacement votre association avec nos outils professionnels.
- Commencez gratuitement et évoluez selon vos besoins.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Questions fréquentes
-
-
-
-
-
Puis-je changer de formule ?
-
Oui, vous pouvez upgrader ou downgrader à tout moment selon vos besoins.
-
-
-
-
-
-
Mes données sont-elles sécurisées ?
-
Absolument. Nous utilisons un chiffrement de niveau bancaire pour protéger vos données.
-
-
-
-
-
-
Quel support est disponible ?
-
Support par email pour tous, support prioritaire et téléphonique pour Premium+.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{formulaireBean.formulaireSelectionne.nom}
-
#{formulaireBean.getPrixAffiche(formulaireBean.formulaireSelectionne)}
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Nos Formulaires - UnionFlow
+
+
+
+
+
+
+
+
+
+
Choisissez votre formule
+
+ Des solutions adaptées à chaque taille d'organisation
+
+
+ Gérez efficacement votre association avec nos outils professionnels.
+ Commencez gratuitement et évoluez selon vos besoins.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Questions fréquentes
+
+
+
+
+
Puis-je changer de formule ?
+
Oui, vous pouvez upgrader ou downgrader à tout moment selon vos besoins.
+
+
+
+
+
+
Mes données sont-elles sécurisées ?
+
Absolument. Nous utilisons un chiffrement de niveau bancaire pour protéger vos données.
+
+
+
+
+
+
Quel support est disponible ?
+
Support par email pour tous, support prioritaire et téléphonique pour Premium+.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{formulaireBean.formulaireSelectionne.nom}
+
#{formulaireBean.getPrixAffiche(formulaireBean.formulaireSelectionne)}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/access-denied.xhtml b/src/main/resources/META-INF/resources/pages/secure/access-denied.xhtml
index ed1cd71..9bf4b2f 100644
--- a/src/main/resources/META-INF/resources/pages/secure/access-denied.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/access-denied.xhtml
@@ -1,61 +1,61 @@
-
-
-
- Accès Refusé - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
Accès Refusé
-
-
-
-
Vous n'avez pas les permissions nécessaires pour accéder à cette page.
-
- Connecté en tant que : #{userSession.currentUser.nomComplet}
- Type de compte : #{userSession.typeCompte}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Accès Refusé - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
Accès Refusé
+
+
+
+
Vous n'avez pas les permissions nécessaires pour accéder à cette page.
+
+ Connecté en tant que : #{userSession.currentUser.nomComplet}
+ Type de compte : #{userSession.typeCompte}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/adhesion/cartes-membres.xhtml b/src/main/resources/META-INF/resources/pages/secure/adhesion/cartes-membres.xhtml
index 6538ea3..74bbb93 100644
--- a/src/main/resources/META-INF/resources/pages/secure/adhesion/cartes-membres.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/adhesion/cartes-membres.xhtml
@@ -1,44 +1,44 @@
-
-
-
- Cartes de Membres - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
Fonctionnalité en développement
-
- La gestion des cartes de membres sera bientôt disponible.
- Cette fonctionnalité permettra de générer, imprimer et gérer les cartes d'adhésion des membres.
-
-
-
-
-
-
-
-
+
+
+
+ Cartes de Membres - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
Fonctionnalité en développement
+
+ La gestion des cartes de membres sera bientôt disponible.
+ Cette fonctionnalité permettra de générer, imprimer et gérer les cartes d'adhésion des membres.
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/adhesion/historique.xhtml b/src/main/resources/META-INF/resources/pages/secure/adhesion/historique.xhtml
index cb0b1e9..c50d8b0 100644
--- a/src/main/resources/META-INF/resources/pages/secure/adhesion/historique.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/adhesion/historique.xhtml
@@ -1,93 +1,93 @@
-
-
-
- Historique des Adhésions - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{adhesion.numeroReference}
-
-
- #{adhesion.membreId}
-
-
- #{adhesion.dateDemande}
-
-
-
-
-
- #{adhesion.montantTotal != null ? adhesion.montantTotal : 0} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Historique des Adhésions - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{adhesion.numeroReference}
+
+
+ #{adhesion.membreId}
+
+
+ #{adhesion.dateDemande}
+
+
+
+
+
+ #{adhesion.montantTotal != null ? adhesion.montantTotal : 0} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/adhesion/history.xhtml b/src/main/resources/META-INF/resources/pages/secure/adhesion/history.xhtml
index 7f9b7d9..05e5459 100644
--- a/src/main/resources/META-INF/resources/pages/secure/adhesion/history.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/adhesion/history.xhtml
@@ -1,259 +1,259 @@
-
-
-
-
- Historique des Adhésions - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Filtres de Recherche
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Historique des Adhésions
-
-
-
-
-
- Historique (#{adhesionsBean.adhesionsFiltrees.size()} adhésion(s))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{adhesion.nomMembre}
-
#{adhesion.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Référence
-
#{adhesionsBean.adhesionSelectionnee.numeroReference}
-
-
-
-
-
-
Membre
-
#{adhesionsBean.adhesionSelectionnee.nomMembre}
-
N° #{adhesionsBean.adhesionSelectionnee.numeroMembre}
-
-
-
-
-
Organisation
-
#{adhesionsBean.adhesionSelectionnee.nomOrganisation}
-
-
-
-
-
Date de demande
-
#{adhesionsBean.adhesionSelectionnee.dateDemandeFormatee}
-
-
-
-
-
Frais d'adhésion
-
#{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}
-
-
-
-
-
Montant payé
-
#{adhesionsBean.adhesionSelectionnee.montantPayeFormatte}
-
-
-
-
-
Montant restant
-
#{adhesionsBean.adhesionSelectionnee.montantRestantFormatte}
-
-
-
-
-
Date d'approbation
-
#{adhesionsBean.adhesionSelectionnee.dateApprobationFormatee}
-
-
-
-
-
Date de paiement
-
#{adhesionsBean.adhesionSelectionnee.datePaiementFormatee}
-
-
-
-
-
Méthode de paiement
-
#{adhesionsBean.adhesionSelectionnee.methodePaiementLibelle}
-
-
-
-
-
Observations
-
#{adhesionsBean.adhesionSelectionnee.observations}
-
-
-
-
-
Motif de rejet
-
#{adhesionsBean.adhesionSelectionnee.motifRejet}
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Historique des Adhésions - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Filtres de Recherche
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Historique des Adhésions
+
+
+
+
+
+ Historique (#{adhesionsBean.adhesionsFiltrees.size()} adhésion(s))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{adhesion.nomMembre}
+
#{adhesion.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Référence
+
#{adhesionsBean.adhesionSelectionnee.numeroReference}
+
+
+
+
+
+
Membre
+
#{adhesionsBean.adhesionSelectionnee.nomMembre}
+
N° #{adhesionsBean.adhesionSelectionnee.numeroMembre}
+
+
+
+
+
Organisation
+
#{adhesionsBean.adhesionSelectionnee.nomOrganisation}
+
+
+
+
+
Date de demande
+
#{adhesionsBean.adhesionSelectionnee.dateDemandeFormatee}
+
+
+
+
+
Frais d'adhésion
+
#{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}
+
+
+
+
+
Montant payé
+
#{adhesionsBean.adhesionSelectionnee.montantPayeFormatte}
+
+
+
+
+
Montant restant
+
#{adhesionsBean.adhesionSelectionnee.montantRestantFormatte}
+
+
+
+
+
Date d'approbation
+
#{adhesionsBean.adhesionSelectionnee.dateApprobationFormatee}
+
+
+
+
+
Date de paiement
+
#{adhesionsBean.adhesionSelectionnee.datePaiementFormatee}
+
+
+
+
+
Méthode de paiement
+
#{adhesionsBean.adhesionSelectionnee.methodePaiementLibelle}
+
+
+
+
+
Observations
+
#{adhesionsBean.adhesionSelectionnee.observations}
+
+
+
+
+
Motif de rejet
+
#{adhesionsBean.adhesionSelectionnee.motifRejet}
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/adhesion/new.xhtml b/src/main/resources/META-INF/resources/pages/secure/adhesion/new.xhtml
index 73e1151..4de5281 100644
--- a/src/main/resources/META-INF/resources/pages/secure/adhesion/new.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/adhesion/new.xhtml
@@ -1,117 +1,117 @@
-
-
-
-
- Nouvelle Adhésion - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Créer une Nouvelle Adhésion
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Nouvelle Adhésion - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Créer une Nouvelle Adhésion
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/adhesion/paiement.xhtml b/src/main/resources/META-INF/resources/pages/secure/adhesion/paiement.xhtml
index 883a0d9..7ff5d1d 100644
--- a/src/main/resources/META-INF/resources/pages/secure/adhesion/paiement.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/adhesion/paiement.xhtml
@@ -1,264 +1,264 @@
-
-
-
-
- Paiement des Adhésions - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Adhésions Approuvées en Attente de Paiement
-
-
-
-
-
-
Adhésions à payer
-
-
-
-
-
-
-
-
-
-
-
-
#{adhesion.nomMembre}
-
#{adhesion.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Adhésion
-
#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}
-
Frais d'adhésion: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Adhésion
-
#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}
-
Frais d'adhésion: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}
-
Montant restant: #{adhesionsBean.adhesionSelectionnee.montantRestantFormatte}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Paiement des Adhésions - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adhésions Approuvées en Attente de Paiement
+
+
+
+
+
+
Adhésions à payer
+
+
+
+
+
+
+
+
+
+
+
+
#{adhesion.nomMembre}
+
#{adhesion.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Adhésion
+
#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}
+
Frais d'adhésion: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Adhésion
+
#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}
+
Frais d'adhésion: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}
+
Montant restant: #{adhesionsBean.adhesionSelectionnee.montantRestantFormatte}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml b/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml
index 56e5300..ae2fc7a 100644
--- a/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml
@@ -1,167 +1,167 @@
-
-
-
-
- Renouvellement d'Adhésion - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Adhésions à Renouveler
-
-
-
-
-
- Adhésions nécessitant un renouvellement
-
-
-
-
-
-
#{adhesion.nomMembre}
-
#{adhesion.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Adhésion actuelle
-
#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}
-
Frais actuel: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Renouvellement d'Adhésion - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adhésions à Renouveler
+
+
+
+
+
+ Adhésions nécessitant un renouvellement
+
+
+
+
+
+
#{adhesion.nomMembre}
+
#{adhesion.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Adhésion actuelle
+
#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}
+
Frais actuel: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/admin/audit.xhtml b/src/main/resources/META-INF/resources/pages/secure/admin/audit.xhtml
index ab639ce..4a239d6 100644
--- a/src/main/resources/META-INF/resources/pages/secure/admin/audit.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/admin/audit.xhtml
@@ -1,32 +1,32 @@
-
-
-
-
- Journal d'Audit - UnionFlow
-
-
-
-
-
-
-
Journal d'Audit
-
- Redirection vers la page principale du journal d'audit...
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Journal d'Audit - UnionFlow
+
+
+
+
+
+
+
Journal d'Audit
+
+ Redirection vers la page principale du journal d'audit...
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/admin/parametres.xhtml b/src/main/resources/META-INF/resources/pages/secure/admin/parametres.xhtml
index 86659e3..9619552 100644
--- a/src/main/resources/META-INF/resources/pages/secure/admin/parametres.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/admin/parametres.xhtml
@@ -1,47 +1,47 @@
-
-
-
-
- Paramètres Système - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Configuration Système
-
- La page de configuration système sera disponible prochainement.
-
-
- Elle permettra de configurer les paramètres généraux de l'application.
-
-
-
-
-
-
+
+
+
+
+ Paramètres Système - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Configuration Système
+
+ La page de configuration système sera disponible prochainement.
+
+
+ Elle permettra de configurer les paramètres généraux de l'application.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/admin/roles.xhtml b/src/main/resources/META-INF/resources/pages/secure/admin/roles.xhtml
index fc3e64c..7beeb34 100644
--- a/src/main/resources/META-INF/resources/pages/secure/admin/roles.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/admin/roles.xhtml
@@ -1,53 +1,53 @@
-
-
-
-
- Gestion des Rôles - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Gestion des Rôles via Keycloak
-
- La gestion des rôles et permissions se fait directement via Keycloak Admin Console.
-
-
- Les rôles disponibles incluent : SUPER_ADMIN, ADMIN_ORG, SECRETAIRE, TRESORIER, MEMBRE, etc.
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Gestion des Rôles - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Gestion des Rôles via Keycloak
+
+ La gestion des rôles et permissions se fait directement via Keycloak Admin Console.
+
+
+ Les rôles disponibles incluent : SUPER_ADMIN, ADMIN_ORG, SECRETAIRE, TRESORIER, MEMBRE, etc.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/admin/utilisateurs.xhtml b/src/main/resources/META-INF/resources/pages/secure/admin/utilisateurs.xhtml
index f313a98..944b07e 100644
--- a/src/main/resources/META-INF/resources/pages/secure/admin/utilisateurs.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/admin/utilisateurs.xhtml
@@ -1,53 +1,53 @@
-
-
-
-
- Gestion des Utilisateurs - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Gestion des Utilisateurs via Keycloak
-
- La gestion des utilisateurs se fait directement via Keycloak Admin Console.
-
-
- Pour accéder à la console d'administration Keycloak, veuillez utiliser l'interface dédiée.
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Gestion des Utilisateurs - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Gestion des Utilisateurs via Keycloak
+
+ La gestion des utilisateurs se fait directement via Keycloak Admin Console.
+
+
+ Pour accéder à la console d'administration Keycloak, veuillez utiliser l'interface dédiée.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/approved.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/approved.xhtml
index 0ff7dae..5f24e32 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/approved.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/approved.xhtml
@@ -1,73 +1,73 @@
-
-
-
- Demandes d'Aide Approuvées - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Demandes d'Aide Approuvées
-
-
- Liste des demandes d'aide approuvées et en cours de traitement
-
-
-
-
-
-
-
-
Demandes Approuvées
-
-
-
-
-
-
#{demande.demandeur}
-
#{demande.telephone}
-
-
-
-
-
-
-
-
- #{demande.montantAccorde} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Demandes d'Aide Approuvées - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Demandes d'Aide Approuvées
+
+
+ Liste des demandes d'aide approuvées et en cours de traitement
+
+
+
+
+
+
+
+
Demandes Approuvées
+
+
+
+
+
+
#{demande.demandeur}
+
#{demande.telephone}
+
+
+
+
+
+
+
+
+ #{demande.montantAccorde} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/apropos.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/apropos.xhtml
index dd3c4df..403ec61 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/apropos.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/apropos.xhtml
@@ -1,327 +1,327 @@
-
-
-
-
- À Propos d'UnionFlow
-
-
-
-
-
-
-
-
-
-
-
UnionFlow
-
- La solution complète de gestion d'associations et organisations
-
-
-
-
-
-
-
-
-
99.9%
-
Disponibilité
-
30 derniers jours
-
-
-
-
-
2.3s
-
Temps de Réponse
-
Moyen
-
-
-
-
-
15,647
-
Utilisateurs
-
Actifs ce mois
-
-
-
-
-
4.8★
-
Satisfaction
-
Note moyenne
-
-
-
-
-
-
-
-
-
-
-
-
-
- Notre Mission
-
-
- UnionFlow a été créé avec la vision de simplifier et moderniser la gestion des associations,
- coopératives et organisations communautaires. Notre objectif est de fournir des outils
- puissants et accessibles qui permettent aux dirigeants de se concentrer sur leur mission
- plutôt que sur la paperasse administrative.
-
-
-
- Vision 2025
-
-
- Devenir la plateforme de référence pour la gestion d'organisations en Afrique
- de l'Ouest avec plus de 100,000 utilisateurs actifs.
-
-
-
-
-
-
-
-
-
- Nos Valeurs
-
-
-
-
-
-
Communauté
-
Favoriser l'entraide et la collaboration
-
-
-
-
-
-
Confiance
-
Sécurité et transparence totales
-
-
-
-
-
-
Innovation
-
Solutions modernes et évolutives
-
-
-
-
-
-
Accessibilité
-
Pour tous, partout, sur tout appareil
-
-
-
-
-
-
-
-
-
-
-
-
-
- Informations Système
-
-
-
-
-
🏗️ Architecture
-
-
-
-
Framework
-
Quarkus 3.15.1
-
-
-
-
-
Interface
-
PrimeFaces 14.0.5
-
-
-
-
-
Base de données
-
PostgreSQL 15
-
-
-
-
-
-
-
-
🔧 Environnement
-
-
-
-
-
-
-
Monitoring
-
Prometheus
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Équipe de Développement
-
-
-
-
-
-
-
-
-
Équipe Core
-
- Architectes et développeurs principaux responsables
- de la vision produit et de l'architecture technique.
-
-
-
-
-
-
-
-
-
-
-
Support Technique
-
- Équipe dédiée à l'assistance utilisateurs,
- maintenance et résolution des incidents.
-
-
-
-
-
-
-
-
-
-
-
UX/UI Design
-
- Designers spécialisés dans l'expérience utilisateur
- et l'interface moderne.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nous Contacter
-
-
-
-
-
-
-
Email
-
contact@unionflow.dev
-
-
-
-
-
-
-
Site Web
-
www.unionflow.dev
-
-
-
-
-
-
-
GitHub
-
github.com/unionflow
-
-
-
-
-
-
-
Twitter
-
@unionflow_dev
-
-
-
-
-
-
- © 2024 UnionFlow. Tous droits réservés.
-
-
- Développé avec ❤️ pour les communautés d'Afrique de l'Ouest par Lions Dev
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ À Propos d'UnionFlow
+
+
+
+
+
+
+
+
+
+
+
UnionFlow
+
+ La solution complète de gestion d'associations et organisations
+
+
+
+
+
+
+
+
+
99.9%
+
Disponibilité
+
30 derniers jours
+
+
+
+
+
2.3s
+
Temps de Réponse
+
Moyen
+
+
+
+
+
15,647
+
Utilisateurs
+
Actifs ce mois
+
+
+
+
+
4.8★
+
Satisfaction
+
Note moyenne
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Notre Mission
+
+
+ UnionFlow a été créé avec la vision de simplifier et moderniser la gestion des associations,
+ coopératives et organisations communautaires. Notre objectif est de fournir des outils
+ puissants et accessibles qui permettent aux dirigeants de se concentrer sur leur mission
+ plutôt que sur la paperasse administrative.
+
+
+
+ Vision 2025
+
+
+ Devenir la plateforme de référence pour la gestion d'organisations en Afrique
+ de l'Ouest avec plus de 100,000 utilisateurs actifs.
+
+
+
+
+
+
+
+
+
+ Nos Valeurs
+
+
+
+
+
+
Communauté
+
Favoriser l'entraide et la collaboration
+
+
+
+
+
+
Confiance
+
Sécurité et transparence totales
+
+
+
+
+
+
Innovation
+
Solutions modernes et évolutives
+
+
+
+
+
+
Accessibilité
+
Pour tous, partout, sur tout appareil
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Informations Système
+
+
+
+
+
🏗️ Architecture
+
+
+
+
Framework
+
Quarkus 3.15.1
+
+
+
+
+
Interface
+
PrimeFaces 14.0.5
+
+
+
+
+
Base de données
+
PostgreSQL 15
+
+
+
+
+
+
+
+
🔧 Environnement
+
+
+
+
+
+
+
Monitoring
+
Prometheus
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Équipe de Développement
+
+
+
+
+
+
+
+
+
Équipe Core
+
+ Architectes et développeurs principaux responsables
+ de la vision produit et de l'architecture technique.
+
+
+
+
+
+
+
+
+
+
+
Support Technique
+
+ Équipe dédiée à l'assistance utilisateurs,
+ maintenance et résolution des incidents.
+
+
+
+
+
+
+
+
+
+
+
UX/UI Design
+
+ Designers spécialisés dans l'expérience utilisateur
+ et l'interface moderne.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Nous Contacter
+
+
+
+
+
+
+
Email
+
contact@unionflow.dev
+
+
+
+
+
+
+
Site Web
+
www.unionflow.dev
+
+
+
+
+
+
+
GitHub
+
github.com/unionflow
+
+
+
+
+
+
+
Twitter
+
@unionflow_dev
+
+
+
+
+
+
+ © 2024 UnionFlow. Tous droits réservés.
+
+
+ Développé avec ❤️ pour les communautés d'Afrique de l'Ouest par Lions Dev
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/demande.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/demande.xhtml
index b842b4d..37db037 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/demande.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/demande.xhtml
@@ -1,158 +1,158 @@
-
-
-
-
- Demande d'Aide - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
- Nouvelle Demande d'Aide
-
-
- Soumettez une demande d'aide pour vous ou un membre de votre organisation
-
-
-
-
-
-
-
-
Informations de la Demande
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Votre demande a été soumise avec succès
-
Elle sera traitée dans les plus brefs délais.
-
-
-
-
-
+
+
+
+
+ Demande d'Aide - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+ Nouvelle Demande d'Aide
+
+
+ Soumettez une demande d'aide pour vous ou un membre de votre organisation
+
+
+
+
+
+
+
+
Informations de la Demande
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Votre demande a été soumise avec succès
+
Elle sera traitée dans les plus brefs délais.
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/documentation.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/documentation.xhtml
index 539746f..c7a4c84 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/documentation.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/documentation.xhtml
@@ -1,170 +1,170 @@
-
-
-
-
- Documentation Complète - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Documentation Complète
-
-
- Documentation technique et fonctionnelle d'UnionFlow
-
-
-
-
-
-
-
-
-
-
45
-
Articles
-
Documentation complète
-
-
-
-
-
12
-
Mis à Jour
-
Ce mois-ci
-
-
-
-
-
6
-
Catégories
-
Thématiques
-
-
-
-
-
3
-
Langages
-
API supportées
-
-
-
-
-
-
-
-
-
-
-
-
-
Guide Utilisateur
-
Documentation complète pour l'utilisation d'UnionFlow
-
- 15 min
- 250
-
-
-
-
-
-
-
-
API REST
-
Documentation complète de l'API REST UnionFlow
-
- 25 min
- 180
-
-
-
-
-
-
-
-
Configuration
-
Guide de configuration et paramétrage du système
-
- 20 min
- 95
-
-
-
-
-
-
-
-
Dépannage
-
Solutions aux problèmes courants et dépannage
-
- 30 min
- 340
-
-
-
-
-
-
-
-
Intégrations
-
Intégration avec des systèmes tiers et webhooks
-
- 35 min
- 75
-
-
-
-
-
-
-
-
Sécurité
-
Bonnes pratiques de sécurité et authentification
-
- 28 min
- 120
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Documentation Complète - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Documentation Complète
+
+
+ Documentation technique et fonctionnelle d'UnionFlow
+
+
+
+
+
+
+
+
+
+
45
+
Articles
+
Documentation complète
+
+
+
+
+
12
+
Mis à Jour
+
Ce mois-ci
+
+
+
+
+
6
+
Catégories
+
Thématiques
+
+
+
+
+
3
+
Langages
+
API supportées
+
+
+
+
+
+
+
+
+
+
+
+
+
Guide Utilisateur
+
Documentation complète pour l'utilisation d'UnionFlow
+
+ 15 min
+ 250
+
+
+
+
+
+
+
+
API REST
+
Documentation complète de l'API REST UnionFlow
+
+ 25 min
+ 180
+
+
+
+
+
+
+
+
Configuration
+
Guide de configuration et paramétrage du système
+
+ 20 min
+ 95
+
+
+
+
+
+
+
+
Dépannage
+
Solutions aux problèmes courants et dépannage
+
+ 30 min
+ 340
+
+
+
+
+
+
+
+
Intégrations
+
Intégration avec des systèmes tiers et webhooks
+
+ 35 min
+ 75
+
+
+
+
+
+
+
+
Sécurité
+
Bonnes pratiques de sécurité et authentification
+
+ 28 min
+ 120
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/faq.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/faq.xhtml
index 109f0f3..6a17f20 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/faq.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/faq.xhtml
@@ -1,469 +1,469 @@
-
-
-
-
- Questions Fréquentes - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Questions Fréquentes
-
-
- Trouvez rapidement des réponses aux questions les plus courantes
-
-
-
-
-
-
-
-
-
-
47
-
Questions
-
Dans la FAQ
-
-
-
-
-
94%
-
Résolution
-
Taux de satisfaction
-
-
-
-
-
2.3m
-
Temps Moyen
-
De réponse
-
-
-
-
-
8
-
Catégories
-
Thématiques
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Questions les Plus Populaires
-
-
-
-
-
-
-
-
Comment réinitialiser mon mot de passe ?
-
Procédure de récupération de compte
-
-
-
-
-
-
-
-
-
Comment exporter la liste des membres ?
-
Export Excel et PDF personnalisés
-
-
-
-
-
-
-
-
-
Configurer les notifications email ?
-
Paramétrage des alertes automatiques
-
-
-
-
-
-
-
-
-
-
-
Organiser un événement étape par étape ?
-
Guide complet de création d'événement
-
-
-
-
-
-
-
-
-
Gérer les rôles et permissions ?
-
Attribution des droits d'accès
-
-
-
-
-
-
-
-
-
Problème de connexion lente ?
-
Solutions de performance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- FAQ par Catégories
-
-
-
-
-
-
-
-
- Authentification et Sécurité
-
-
-
-
-
Comment créer un compte utilisateur ?
-
-
-
- Seul un administrateur peut créer de nouveaux comptes utilisateurs. Rendez-vous dans "Administration" → "Gestion Utilisateurs" → "Nouvel Utilisateur".
- Remplissez les informations obligatoires et attribuez un rôle approprié.
-
-
-
-
-
-
-
Pourquoi ma session expire-t-elle souvent ?
-
-
-
- Par sécurité, les sessions expirent après 30 minutes d'inactivité. Vous pouvez cocher "Se souvenir de moi"
- lors de la connexion pour étendre cette durée. Si le problème persiste, videz le cache de votre navigateur.
-
-
-
- Conseil Pro
-
-
- Activez les notifications push pour être alerté avant l'expiration de votre session.
-
-
-
-
-
-
-
Comment activer l'authentification à deux facteurs ?
-
-
-
- Allez dans "Mon Espace Personnel" → "Paramètres Compte" → "Sécurité" → "Authentification 2FA".
- Scannez le QR code avec Google Authenticator ou Authy, puis validez avec le code généré.
-
-
-
-
-
-
-
-
-
-
-
- Inscription et Modification
-
-
-
-
-
Que faire si un membre refuse son adhésion ?
-
-
-
- Rendez-vous dans "Gestion des Adhésions" → "Validation des Demandes", trouvez la demande concernée
- et cliquez sur "Rejeter". Ajoutez un motif de refus qui sera envoyé automatiquement au demandeur.
-
-
-
- Important
-
-
- Assurez-vous de documenter les raisons du refus pour le suivi administratif.
-
-
-
-
-
-
-
Comment transférer un membre vers une autre organisation ?
-
-
-
- Cette fonctionnalité n'est disponible que pour les Super-Administrateurs. Contactez le support
- avec les détails du transfert : membre concerné, organisation de destination et justification.
-
-
-
-
-
-
-
-
-
-
-
- Cotisations et Paiements
-
-
-
-
-
Comment configurer les cotisations automatiques ?
-
-
-
- Allez dans "Gestion Financière" → "Cotisations" → "Configuration Auto". Définissez le montant,
- la périodicité (mensuelle/annuelle) et les conditions de prélèvement automatique.
-
-
-
-
-
-
-
Un paiement mobile money a échoué, que faire ?
-
-
-
- Vérifiez d'abord le statut dans "Historique Paiements". Si le paiement est marqué "Échec",
- cliquez sur "Relancer" ou demandez au membre de réessayer avec un solde suffisant.
-
-
-
-
-
-
-
-
-
-
-
- Problèmes Courants
-
-
-
-
-
L'application est lente ou ne répond pas ?
-
-
-
- 1. Vérifiez votre connexion internet
- 2. Videz le cache : Ctrl+Maj+Suppr (Chrome)
- 3. Redémarrez votre navigateur
- 4. Essayez en navigation privée
-
-
-
- Solution Rapide
-
-
- 90% des problèmes de lenteur sont résolus en vidant le cache navigateur.
-
-
-
-
-
-
-
Erreur "Page non trouvée" en naviguant ?
-
-
-
- Cette erreur peut survenir après une mise à jour. Déconnectez-vous complètement,
- fermez tous les onglets UnionFlow, puis reconnectez-vous.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Questions Fréquentes - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Questions Fréquentes
+
+
+ Trouvez rapidement des réponses aux questions les plus courantes
+
+
+
+
+
+
+
+
+
+
47
+
Questions
+
Dans la FAQ
+
+
+
+
+
94%
+
Résolution
+
Taux de satisfaction
+
+
+
+
+
2.3m
+
Temps Moyen
+
De réponse
+
+
+
+
+
8
+
Catégories
+
Thématiques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Questions les Plus Populaires
+
+
+
+
+
+
+
+
Comment réinitialiser mon mot de passe ?
+
Procédure de récupération de compte
+
+
+
+
+
+
+
+
+
Comment exporter la liste des membres ?
+
Export Excel et PDF personnalisés
+
+
+
+
+
+
+
+
+
Configurer les notifications email ?
+
Paramétrage des alertes automatiques
+
+
+
+
+
+
+
+
+
+
+
Organiser un événement étape par étape ?
+
Guide complet de création d'événement
+
+
+
+
+
+
+
+
+
Gérer les rôles et permissions ?
+
Attribution des droits d'accès
+
+
+
+
+
+
+
+
+
Problème de connexion lente ?
+
Solutions de performance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ FAQ par Catégories
+
+
+
+
+
+
+
+
+ Authentification et Sécurité
+
+
+
+
+
Comment créer un compte utilisateur ?
+
+
+
+ Seul un administrateur peut créer de nouveaux comptes utilisateurs. Rendez-vous dans "Administration" → "Gestion Utilisateurs" → "Nouvel Utilisateur".
+ Remplissez les informations obligatoires et attribuez un rôle approprié.
+
+
+
+
+
+
+
Pourquoi ma session expire-t-elle souvent ?
+
+
+
+ Par sécurité, les sessions expirent après 30 minutes d'inactivité. Vous pouvez cocher "Se souvenir de moi"
+ lors de la connexion pour étendre cette durée. Si le problème persiste, videz le cache de votre navigateur.
+
+
+
+ Conseil Pro
+
+
+ Activez les notifications push pour être alerté avant l'expiration de votre session.
+
+
+
+
+
+
+
Comment activer l'authentification à deux facteurs ?
+
+
+
+ Allez dans "Mon Espace Personnel" → "Paramètres Compte" → "Sécurité" → "Authentification 2FA".
+ Scannez le QR code avec Google Authenticator ou Authy, puis validez avec le code généré.
+
+
+
+
+
+
+
+
+
+
+
+ Inscription et Modification
+
+
+
+
+
Que faire si un membre refuse son adhésion ?
+
+
+
+ Rendez-vous dans "Gestion des Adhésions" → "Validation des Demandes", trouvez la demande concernée
+ et cliquez sur "Rejeter". Ajoutez un motif de refus qui sera envoyé automatiquement au demandeur.
+
+
+
+ Important
+
+
+ Assurez-vous de documenter les raisons du refus pour le suivi administratif.
+
+
+
+
+
+
+
Comment transférer un membre vers une autre organisation ?
+
+
+
+ Cette fonctionnalité n'est disponible que pour les Super-Administrateurs. Contactez le support
+ avec les détails du transfert : membre concerné, organisation de destination et justification.
+
+
+
+
+
+
+
+
+
+
+
+ Cotisations et Paiements
+
+
+
+
+
Comment configurer les cotisations automatiques ?
+
+
+
+ Allez dans "Gestion Financière" → "Cotisations" → "Configuration Auto". Définissez le montant,
+ la périodicité (mensuelle/annuelle) et les conditions de prélèvement automatique.
+
+
+
+
+
+
+
Un paiement mobile money a échoué, que faire ?
+
+
+
+ Vérifiez d'abord le statut dans "Historique Paiements". Si le paiement est marqué "Échec",
+ cliquez sur "Relancer" ou demandez au membre de réessayer avec un solde suffisant.
+
+
+
+
+
+
+
+
+
+
+
+ Problèmes Courants
+
+
+
+
+
L'application est lente ou ne répond pas ?
+
+
+
+ 1. Vérifiez votre connexion internet
+ 2. Videz le cache : Ctrl+Maj+Suppr (Chrome)
+ 3. Redémarrez votre navigateur
+ 4. Essayez en navigation privée
+
+
+
+ Solution Rapide
+
+
+ 90% des problèmes de lenteur sont résolus en vidant le cache navigateur.
+
+
+
+
+
+
+
Erreur "Page non trouvée" en naviguant ?
+
+
+
+ Cette erreur peut survenir après une mise à jour. Déconnectez-vous complètement,
+ fermez tous les onglets UnionFlow, puis reconnectez-vous.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml
index 843f7b5..ce1d8fd 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml
@@ -1,435 +1,435 @@
-
-
-
-
- Guide Utilisateur - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Guide Utilisateur UnionFlow
-
-
- Apprenez à utiliser efficacement toutes les fonctionnalités d'UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Votre Progression
- #{guideBean.sectionsLues} / #{guideBean.totalSections} sections
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Table des Matières
-
-
-
-
-
#{guideBean.pourcentageProgression}% terminé
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{guideBean.sectionCourante.titre}
-
-
-
#{guideBean.sectionCourante.tempsLecture} min de lecture
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Se connecter à UnionFlow
-
-
- Pour accéder à UnionFlow, vous devez disposer d'un compte utilisateur avec les droits appropriés.
- Voici comment procéder pour votre première connexion.
-
-
-
-
-
- Étapes de connexion
-
-
- Rendez-vous sur la page de connexion UnionFlow
- Sélectionnez votre type de compte (Membre, Admin, etc.)
- Saisissez votre email ou nom d'utilisateur
- Entrez votre mot de passe
- Cliquez sur "Se connecter"
-
-
-
-
-
-
- Mot de passe oublié ?
-
-
- Cliquez sur "Mot de passe oublié ?" sur la page de connexion pour recevoir
- un lien de réinitialisation par email.
-
-
-
- Types de comptes disponibles
-
-
-
-
-
Super-Admin
-
Accès complet au système
-
-
-
-
-
-
Admin Organisation
-
Gestion d'une organisation
-
-
-
-
-
-
Membre
-
Accès membre standard
-
-
-
-
-
-
- Inscrire un nouveau membre
-
-
- L'inscription d'un nouveau membre est une procédure simple qui permet d'ajouter
- une personne à votre organisation avec toutes les informations nécessaires.
-
-
-
-
-
- Prérequis
-
-
- Avoir les droits d'administration ou de gestion des membres
- Disposer des informations personnelles du futur membre
- Connaître le type d'adhésion souhaité
-
-
-
- Processus d'inscription
-
-
-
-
-
-
Accéder au formulaire
-
Menu "Gestion des Membres" → "Nouvelle Inscription"
-
-
-
-
-
-
-
Remplir les informations personnelles
-
Nom, prénom, date de naissance, contact, adresse
-
-
-
-
-
-
-
Choisir le type d'adhésion
-
Membre actif, associé, d'honneur, etc.
-
-
-
-
-
-
-
Validation et enregistrement
-
Le membre reçoit automatiquement ses identifiants par email
-
-
-
-
-
-
-
-
-
Sélectionnez une section
-
Choisissez un sujet dans le menu de gauche pour commencer la lecture
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Terme à rechercher
-
-
-
-
-
-
-
-
-
-
-
-
#{resultat.titre}
-
#{resultat.description}
-
-
-
-
-
-
-
-
-
-
Aucun résultat trouvé pour "#{guideBean.termeRecherche}"
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Guide Utilisateur - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Guide Utilisateur UnionFlow
+
+
+ Apprenez à utiliser efficacement toutes les fonctionnalités d'UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Votre Progression
+ #{guideBean.sectionsLues} / #{guideBean.totalSections} sections
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Table des Matières
+
+
+
+
+
#{guideBean.pourcentageProgression}% terminé
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{guideBean.sectionCourante.titre}
+
+
+
#{guideBean.sectionCourante.tempsLecture} min de lecture
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Se connecter à UnionFlow
+
+
+ Pour accéder à UnionFlow, vous devez disposer d'un compte utilisateur avec les droits appropriés.
+ Voici comment procéder pour votre première connexion.
+
+
+
+
+
+ Étapes de connexion
+
+
+ Rendez-vous sur la page de connexion UnionFlow
+ Sélectionnez votre type de compte (Membre, Admin, etc.)
+ Saisissez votre email ou nom d'utilisateur
+ Entrez votre mot de passe
+ Cliquez sur "Se connecter"
+
+
+
+
+
+
+ Mot de passe oublié ?
+
+
+ Cliquez sur "Mot de passe oublié ?" sur la page de connexion pour recevoir
+ un lien de réinitialisation par email.
+
+
+
+ Types de comptes disponibles
+
+
+
+
+
Super-Admin
+
Accès complet au système
+
+
+
+
+
+
Admin Organisation
+
Gestion d'une organisation
+
+
+
+
+
+
Membre
+
Accès membre standard
+
+
+
+
+
+
+ Inscrire un nouveau membre
+
+
+ L'inscription d'un nouveau membre est une procédure simple qui permet d'ajouter
+ une personne à votre organisation avec toutes les informations nécessaires.
+
+
+
+
+
+ Prérequis
+
+
+ Avoir les droits d'administration ou de gestion des membres
+ Disposer des informations personnelles du futur membre
+ Connaître le type d'adhésion souhaité
+
+
+
+ Processus d'inscription
+
+
+
+
+
+
Accéder au formulaire
+
Menu "Gestion des Membres" → "Nouvelle Inscription"
+
+
+
+
+
+
+
Remplir les informations personnelles
+
Nom, prénom, date de naissance, contact, adresse
+
+
+
+
+
+
+
Choisir le type d'adhésion
+
Membre actif, associé, d'honneur, etc.
+
+
+
+
+
+
+
Validation et enregistrement
+
Le membre reçoit automatiquement ses identifiants par email
+
+
+
+
+
+
+
+
+
Sélectionnez une section
+
Choisissez un sujet dans le menu de gauche pour commencer la lecture
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Terme à rechercher
+
+
+
+
+
+
+
+
+
+
+
+
#{resultat.titre}
+
#{resultat.description}
+
+
+
+
+
+
+
+
+
+
Aucun résultat trouvé pour "#{guideBean.termeRecherche}"
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/historique.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/historique.xhtml
index c3b0e7c..1076e30 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/historique.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/historique.xhtml
@@ -1,20 +1,20 @@
-
-
-
-
- Historique des Demandes d'Aide - UnionFlow
-
-
-
-
-
-
-
-
+
+
+
+
+ Historique des Demandes d'Aide - UnionFlow
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/history.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/history.xhtml
index 9cc716b..2a20a6e 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/history.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/history.xhtml
@@ -1,132 +1,132 @@
-
-
-
- Historique des Demandes d'Aide - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Historique des Demandes d'Aide
-
-
- Consultez l'historique complet de toutes les demandes d'aide
-
-
-
-
-
-
-
-
-
-
-
Historique Complet
-
-
-
-
-
-
#{demande.demandeur}
-
#{demande.localisation}
-
-
-
-
-
-
-
-
- #{demande.montantDemande} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Historique des Demandes d'Aide - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Historique des Demandes d'Aide
+
+
+ Consultez l'historique complet de toutes les demandes d'aide
+
+
+
+
+
+
+
+
+
+
+
Historique Complet
+
+
+
+
+
+
#{demande.demandeur}
+
#{demande.localisation}
+
+
+
+
+
+
+
+
+ #{demande.montantDemande} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/nouveautes.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/nouveautes.xhtml
index ef3354d..f2d5f66 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/nouveautes.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/nouveautes.xhtml
@@ -1,401 +1,401 @@
-
-
-
-
- Nouveautés - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Nouveautés UnionFlow
-
-
- Découvrez les dernières fonctionnalités, améliorations et corrections
-
-
-
-
-
-
-
-
-
-
v2.1.3
-
Version Actuelle
-
Stable
-
-
-
-
-
47
-
Nouvelles Fonctionnalités
-
Cette année
-
-
-
-
-
134
-
Améliorations
-
Depuis v2.0
-
-
-
-
-
89
-
Corrections
-
Bugs résolus
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Version 2.1.3 - Dernière version stable
-
Publiée le 18 janvier 2024 • Mise à jour de sécurité importante
-
-
-
-
-
-
-
🔒 Améliorations de Sécurité
-
-
-
- Correction de faille XSS dans les formulaires de commentaires
-
-
-
- Mise à jour des dépendances de sécurité critiques
-
-
-
- Renforcement de la validation des uploads de fichiers
-
-
-
-
🐛 Corrections de Bugs
-
-
-
- Résolution du problème d'export Excel sur Chrome 120+
-
-
-
- Correction de l'affichage des dates sur mobile
-
-
-
-
-
-
📊 Impact de la mise à jour
-
-
-
- Taille
- 15.2 MB
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Historique des Versions
-
-
-
-
-
-
-
-
-
-
Version 2.1.2
-
Publiée le 3 janvier 2024
-
-
-
-
-
-
-
✨ Nouvelles Fonctionnalités
-
-
-
- Système de notifications en temps réel
-
-
-
- Export PDF avec signature électronique
-
-
-
- Interface de gestion des rôles avancée
-
-
-
-
-
⚡ Améliorations
-
-
-
- Performance des rapports (+40%)
-
-
-
- Interface mobile optimisée
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Version 2.1.1
-
Publiée le 15 décembre 2023
-
-
-
-
-
🐛 Corrections
-
-
-
- Correction du bug d'affichage dans les tableaux de données
-
-
-
- Résolution des problèmes de connexion SSO
-
-
-
- Correction des erreurs de validation de formulaires
-
-
-
-
-
-
-
-
-
-
-
-
Version 2.1.0 - Release Majeure
-
Publiée le 1er décembre 2023
-
-
-
-
-
-
-
-
- Points forts de cette version
-
-
- Version LTS avec support étendu jusqu'en décembre 2025.
- Architecture modernisée et nouvelles API REST.
-
-
-
-
-
-
✨ Nouvelles Fonctionnalités
-
-
-
- API REST v2 complète
-
-
-
- Workflow personnalisables
-
-
-
- Tableau de bord configurable
-
-
-
-
-
-
⚡ Améliorations
-
-
-
- Performances globales +60%
-
-
-
- Sécurité renforcée (2FA)
-
-
-
- UX/UI redesignée
-
-
-
-
-
-
🔧 Technique
-
-
-
- Migration Quarkus 3.x
-
-
-
- Base de données optimisée
-
-
-
- Cache distribué Redis
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Version 2.0.5
-
Publiée le 10 novembre 2023 • Support terminé
-
-
-
-
- Dernière version de la branche 2.0.x. Migration vers 2.1.x recommandée pour les corrections de sécurité.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Nouveautés - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Nouveautés UnionFlow
+
+
+ Découvrez les dernières fonctionnalités, améliorations et corrections
+
+
+
+
+
+
+
+
+
+
v2.1.3
+
Version Actuelle
+
Stable
+
+
+
+
+
47
+
Nouvelles Fonctionnalités
+
Cette année
+
+
+
+
+
134
+
Améliorations
+
Depuis v2.0
+
+
+
+
+
89
+
Corrections
+
Bugs résolus
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Version 2.1.3 - Dernière version stable
+
Publiée le 18 janvier 2024 • Mise à jour de sécurité importante
+
+
+
+
+
+
+
🔒 Améliorations de Sécurité
+
+
+
+ Correction de faille XSS dans les formulaires de commentaires
+
+
+
+ Mise à jour des dépendances de sécurité critiques
+
+
+
+ Renforcement de la validation des uploads de fichiers
+
+
+
+
🐛 Corrections de Bugs
+
+
+
+ Résolution du problème d'export Excel sur Chrome 120+
+
+
+
+ Correction de l'affichage des dates sur mobile
+
+
+
+
+
+
📊 Impact de la mise à jour
+
+
+
+ Taille
+ 15.2 MB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Historique des Versions
+
+
+
+
+
+
+
+
+
+
Version 2.1.2
+
Publiée le 3 janvier 2024
+
+
+
+
+
+
+
✨ Nouvelles Fonctionnalités
+
+
+
+ Système de notifications en temps réel
+
+
+
+ Export PDF avec signature électronique
+
+
+
+ Interface de gestion des rôles avancée
+
+
+
+
+
⚡ Améliorations
+
+
+
+ Performance des rapports (+40%)
+
+
+
+ Interface mobile optimisée
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Version 2.1.1
+
Publiée le 15 décembre 2023
+
+
+
+
+
🐛 Corrections
+
+
+
+ Correction du bug d'affichage dans les tableaux de données
+
+
+
+ Résolution des problèmes de connexion SSO
+
+
+
+ Correction des erreurs de validation de formulaires
+
+
+
+
+
+
+
+
+
+
+
+
Version 2.1.0 - Release Majeure
+
Publiée le 1er décembre 2023
+
+
+
+
+
+
+
+
+ Points forts de cette version
+
+
+ Version LTS avec support étendu jusqu'en décembre 2025.
+ Architecture modernisée et nouvelles API REST.
+
+
+
+
+
+
✨ Nouvelles Fonctionnalités
+
+
+
+ API REST v2 complète
+
+
+
+ Workflow personnalisables
+
+
+
+ Tableau de bord configurable
+
+
+
+
+
+
⚡ Améliorations
+
+
+
+ Performances globales +60%
+
+
+
+ Sécurité renforcée (2FA)
+
+
+
+ UX/UI redesignée
+
+
+
+
+
+
🔧 Technique
+
+
+
+ Migration Quarkus 3.x
+
+
+
+ Base de données optimisée
+
+
+
+ Cache distribué Redis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Version 2.0.5
+
Publiée le 10 novembre 2023 • Support terminé
+
+
+
+
+ Dernière version de la branche 2.0.x. Migration vers 2.1.x recommandée pour les corrections de sécurité.
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/requests.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/requests.xhtml
index 0c8521b..aa8bdec 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/requests.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/requests.xhtml
@@ -1,79 +1,79 @@
-
-
-
- Mes Demandes d'Aide - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Mes Demandes d'Aide
-
-
- Consultez l'état de vos demandes d'aide
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Historique de mes Demandes
-
-
-
-
-
-
-
-
- #{demande.montantDemande} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Mes Demandes d'Aide - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Mes Demandes d'Aide
+
+
+ Consultez l'état de vos demandes d'aide
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Historique de mes Demandes
+
+
+
+
+
+
+
+
+ #{demande.montantDemande} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/statistiques.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/statistiques.xhtml
index 4b071db..90143fc 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/statistiques.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/statistiques.xhtml
@@ -1,120 +1,120 @@
-
-
-
-
- Statistiques des Demandes d'Aide - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
- Statistiques des Demandes d'Aide
-
-
- Analyse et statistiques détaillées des demandes d'aide
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.totalDemandes}
-
Total Demandes
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.demandesEnAttente}
-
En Attente
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.demandesApprouvees}
-
Approuvées
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.montantTotalAide}
-
Montant Total
-
-
-
-
-
-
-
-
-
-
-
-
Répartition par Type d'Aide
-
-
-
-
-
Graphique de répartition par type
-
À implémenter avec PrimeNG Charts
-
-
-
-
-
-
Graphique de répartition par statut
-
À implémenter avec PrimeNG Charts
-
-
-
-
-
-
-
+
+
+
+
+ Statistiques des Demandes d'Aide - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+ Statistiques des Demandes d'Aide
+
+
+ Analyse et statistiques détaillées des demandes d'aide
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.totalDemandes}
+
Total Demandes
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesEnAttente}
+
En Attente
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesApprouvees}
+
Approuvées
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.montantTotalAide}
+
Montant Total
+
+
+
+
+
+
+
+
+
+
+
+
Répartition par Type d'Aide
+
+
+
+
+
Graphique de répartition par type
+
À implémenter avec PrimeNG Charts
+
+
+
+
+
+
Graphique de répartition par statut
+
À implémenter avec PrimeNG Charts
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/suggestions.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/suggestions.xhtml
index d010b31..a875669 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/suggestions.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/suggestions.xhtml
@@ -1,475 +1,475 @@
-
-
-
-
- Suggestions et Feedback - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Suggestions et Feedback
-
-
- Partagez vos idées pour améliorer UnionFlow et votez pour les suggestions de la communauté
-
-
-
-
-
-
-
-
-
-
#{suggestionBean.totalSuggestions}
-
Suggestions
-
Soumises
-
-
-
-
-
#{suggestionBean.suggestionsImplementees}
-
Implémentées
-
Dans la v2.0
-
-
-
-
-
#{suggestionBean.totalVotes}
-
Votes
-
Ce mois-ci
-
-
-
-
-
#{suggestionBean.contributeursActifs}
-
Contributeurs
-
Actifs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Suggestions les Plus Populaires
-
-
-
-
-
-
-
-
Mode sombre pour l'interface
-
-
-
-
Proposé par Marie Dubois • il y a 2 semaines
-
- Ajouter un thème sombre à l'interface pour réduire la fatigue visuelle lors de longues sessions de travail.
- Particulièrement utile pour les utilisateurs travaillant en soirée ou dans des environnements peu éclairés.
-
-
-
- 24 commentaires
-
-
- 847 vues
-
-
-
-
-
-
-
-
- Mise à jour: Cette fonctionnalité est en cours de développement et sera disponible dans la version 2.2.
-
-
-
-
-
-
-
-
-
-
Export PDF personnalisé avec logo
-
-
-
-
Proposé par Thomas Martin • il y a 1 mois
-
- Permettre l'ajout du logo de l'organisation sur tous les exports PDF (rapports, listes membres, etc.)
- pour une meilleure présentation des documents officiels.
-
-
-
- 18 commentaires
-
-
- 523 vues
-
-
-
-
-
-
-
-
-
-
-
-
-
Notifications push mobiles
-
-
-
-
-
Proposé par Sophie Leroy • il y a 3 jours
-
- Recevoir des notifications push sur mobile pour les événements importants :
- nouvelles adhésions, rappels de cotisations, événements à venir, etc.
-
-
-
- 7 commentaires
-
-
- 156 vues
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mes Contributions
-
-
-
-
-
-
-
-
Import CSV automatisé
-
-
-
Soumise il y a 1 semaine
-
- Permettre l'import automatique de fichiers CSV pour les inscriptions en masse...
-
-
-
-
-
-
-
-
-
-
Calendrier partagé équipe
-
-
-
Soumise il y a 3 mois
-
- Calendrier collaboratif pour planifier les événements et réunions...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Roadmap des Suggestions
-
-
-
-
-
-
- Version 2.2 (Q2 2024)
-
-
-
-
- Mode sombre
-
-
-
- Export PDF avec logo
-
-
-
- Recherche avancée globale
-
-
-
-
-
-
-
-
- Version 2.3 (Q3 2024)
-
-
-
-
- Notifications push mobiles
-
-
-
- API REST publique
-
-
-
- Tableau de bord personnalisable
-
-
-
-
-
-
-
-
- Version 3.0 (Q4 2024)
-
-
-
-
- Application mobile native
-
-
-
- Intelligence artificielle
-
-
-
- Intégrations avancées
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Suggestions et Feedback - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Suggestions et Feedback
+
+
+ Partagez vos idées pour améliorer UnionFlow et votez pour les suggestions de la communauté
+
+
+
+
+
+
+
+
+
+
#{suggestionBean.totalSuggestions}
+
Suggestions
+
Soumises
+
+
+
+
+
#{suggestionBean.suggestionsImplementees}
+
Implémentées
+
Dans la v2.0
+
+
+
+
+
#{suggestionBean.totalVotes}
+
Votes
+
Ce mois-ci
+
+
+
+
+
#{suggestionBean.contributeursActifs}
+
Contributeurs
+
Actifs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Suggestions les Plus Populaires
+
+
+
+
+
+
+
+
Mode sombre pour l'interface
+
+
+
+
Proposé par Marie Dubois • il y a 2 semaines
+
+ Ajouter un thème sombre à l'interface pour réduire la fatigue visuelle lors de longues sessions de travail.
+ Particulièrement utile pour les utilisateurs travaillant en soirée ou dans des environnements peu éclairés.
+
+
+
+ 24 commentaires
+
+
+ 847 vues
+
+
+
+
+
+
+
+
+ Mise à jour: Cette fonctionnalité est en cours de développement et sera disponible dans la version 2.2.
+
+
+
+
+
+
+
+
+
+
Export PDF personnalisé avec logo
+
+
+
+
Proposé par Thomas Martin • il y a 1 mois
+
+ Permettre l'ajout du logo de l'organisation sur tous les exports PDF (rapports, listes membres, etc.)
+ pour une meilleure présentation des documents officiels.
+
+
+
+ 18 commentaires
+
+
+ 523 vues
+
+
+
+
+
+
+
+
+
+
+
+
+
Notifications push mobiles
+
+
+
+
+
Proposé par Sophie Leroy • il y a 3 jours
+
+ Recevoir des notifications push sur mobile pour les événements importants :
+ nouvelles adhésions, rappels de cotisations, événements à venir, etc.
+
+
+
+ 7 commentaires
+
+
+ 156 vues
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mes Contributions
+
+
+
+
+
+
+
+
Import CSV automatisé
+
+
+
Soumise il y a 1 semaine
+
+ Permettre l'import automatique de fichiers CSV pour les inscriptions en masse...
+
+
+
+
+
+
+
+
+
+
Calendrier partagé équipe
+
+
+
Soumise il y a 3 mois
+
+ Calendrier collaboratif pour planifier les événements et réunions...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Roadmap des Suggestions
+
+
+
+
+
+
+ Version 2.2 (Q2 2024)
+
+
+
+
+ Mode sombre
+
+
+
+ Export PDF avec logo
+
+
+
+ Recherche avancée globale
+
+
+
+
+
+
+
+
+ Version 2.3 (Q3 2024)
+
+
+
+
+ Notifications push mobiles
+
+
+
+ API REST publique
+
+
+
+ Tableau de bord personnalisable
+
+
+
+
+
+
+
+
+ Version 3.0 (Q4 2024)
+
+
+
+
+ Application mobile native
+
+
+
+ Intelligence artificielle
+
+
+
+ Intégrations avancées
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/support.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/support.xhtml
index 4dd77c1..a7946ea 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/support.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/support.xhtml
@@ -1,322 +1,322 @@
-
-
-
-
- Contacter le Support - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Contacter le Support
-
-
- Notre équipe support est là pour vous aider
-
-
-
-
-
-
-
-
-
-
-
Temps de Réponse
-
Moins de 2h
-
-
-
-
-
-
Taux de Résolution
-
98.5%
-
-
-
-
-
-
Satisfaction Client
-
4.8/5
-
-
-
-
-
-
Support
-
7j/7 - 24h/24
-
-
-
-
-
-
-
-
-
-
-
-
-
- Choisissez votre canal de support
-
-
-
-
-
-
-
-
Ticket Support
-
Pour les problèmes techniques et demandes complexes
-
-
Réponse sous 2h
-
-
-
-
-
-
-
-
-
Chat en Direct
-
Support instantané pour les questions urgentes
-
-
Disponible 9h-18h
-
-
-
-
-
-
-
-
-
Support Téléphonique
-
Appelez-nous directement pour une assistance immédiate
-
+33 1 23 45 67 89
-
Lun-Ven 8h-19h
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Questions Fréquentes
-
-
-
-
-
- Pour réinitialiser votre mot de passe, cliquez sur "Mot de passe oublié ?"
- sur la page de connexion. Vous recevrez un email avec un lien de réinitialisation
- valable pendant 24 heures.
-
-
-
-
-
-
- Vous pouvez exporter vos données depuis le menu "Rapports" → "Export Personnalisés".
- Plusieurs formats sont disponibles : Excel, PDF, CSV et JSON.
-
-
-
-
-
-
- Si l'application semble lente, vérifiez votre connexion internet et
- videz le cache de votre navigateur. Pour Chrome : Ctrl+Maj+Suppr.
-
-
-
- Diagnostic automatique
-
-
- Utilisez l'outil de diagnostic intégré pour identifier les problèmes.
-
-
-
-
-
-
- Rendez-vous dans "Mon Espace Personnel" → "Mes Préférences" → "Notifications"
- pour configurer vos alertes par email et dans l'application.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ressources Utiles
-
-
-
-
-
-
-
-
Tutoriels Vidéo
-
Guides visuels étape par étape
-
-
-
-
-
-
-
-
-
Documentation
-
Guide complet d'utilisation
-
-
-
-
-
-
-
-
-
Communauté
-
Forum d'entraide utilisateurs
-
-
-
-
-
-
-
-
-
Nouveautés
-
Dernières fonctionnalités
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Contacter le Support - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Contacter le Support
+
+
+ Notre équipe support est là pour vous aider
+
+
+
+
+
+
+
+
+
+
+
Temps de Réponse
+
Moins de 2h
+
+
+
+
+
+
Taux de Résolution
+
98.5%
+
+
+
+
+
+
Satisfaction Client
+
4.8/5
+
+
+
+
+
+
Support
+
7j/7 - 24h/24
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Choisissez votre canal de support
+
+
+
+
+
+
+
+
Ticket Support
+
Pour les problèmes techniques et demandes complexes
+
+
Réponse sous 2h
+
+
+
+
+
+
+
+
+
Chat en Direct
+
Support instantané pour les questions urgentes
+
+
Disponible 9h-18h
+
+
+
+
+
+
+
+
+
Support Téléphonique
+
Appelez-nous directement pour une assistance immédiate
+
+33 1 23 45 67 89
+
Lun-Ven 8h-19h
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Questions Fréquentes
+
+
+
+
+
+ Pour réinitialiser votre mot de passe, cliquez sur "Mot de passe oublié ?"
+ sur la page de connexion. Vous recevrez un email avec un lien de réinitialisation
+ valable pendant 24 heures.
+
+
+
+
+
+
+ Vous pouvez exporter vos données depuis le menu "Rapports" → "Export Personnalisés".
+ Plusieurs formats sont disponibles : Excel, PDF, CSV et JSON.
+
+
+
+
+
+
+ Si l'application semble lente, vérifiez votre connexion internet et
+ videz le cache de votre navigateur. Pour Chrome : Ctrl+Maj+Suppr.
+
+
+
+ Diagnostic automatique
+
+
+ Utilisez l'outil de diagnostic intégré pour identifier les problèmes.
+
+
+
+
+
+
+ Rendez-vous dans "Mon Espace Personnel" → "Mes Préférences" → "Notifications"
+ pour configurer vos alertes par email et dans l'application.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ressources Utiles
+
+
+
+
+
+
+
+
Tutoriels Vidéo
+
Guides visuels étape par étape
+
+
+
+
+
+
+
+
+
Documentation
+
Guide complet d'utilisation
+
+
+
+
+
+
+
+
+
Communauté
+
Forum d'entraide utilisateurs
+
+
+
+
+
+
+
+
+
Nouveautés
+
Dernières fonctionnalités
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/tickets.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/tickets.xhtml
index 67bbd52..ef0381a 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/tickets.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/tickets.xhtml
@@ -1,335 +1,335 @@
-
-
-
-
- Mes Tickets Support - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Mes Tickets Support
-
-
- Suivez l'état de vos demandes d'assistance et échangez avec notre équipe
-
-
-
-
-
-
-
-
-
-
#{ticketBean.totalTickets}
-
Tickets Créés
-
Au total
-
-
-
-
-
#{ticketBean.ticketsEnAttente}
-
En Attente
-
Réponse support
-
-
-
-
-
#{ticketBean.ticketsResolus}
-
Résolus
-
Avec succès
-
-
-
-
-
#{ticketBean.ticketsFermes}
-
Fermé
-
Sans résolution
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Historique de vos Tickets
-
-
-
-
-
-
-
-
-
-
-
-
#{ticket.numeroTicket} - #{ticket.sujet}
-
-
- Créé le #{ticket.dateCreation != null ? ticket.dateCreation : 'N/A'}
- #{ticket.dateDerniereReponse != null ? ' • Dernière réponse ' + ticket.dateDerniereReponse : ''}
-
-
-
-
- #{ticket.agentNom != null ? '
Agent: ' + ticket.agentNom + '
' : ''}
-
-
-
-
-
-
- #{ticket.description != null ? ticket.description : 'Aucune description'}
-
- #{ticket.resolution != null ? '
Résolution: ' + ticket.resolution + '
' : ''}
-
-
-
- #{ticket.nbMessages != null ? ticket.nbMessages : 0} message#{ticket.nbMessages != null and ticket.nbMessages > 1 ? 's' : ''}
- #{ticket.nbFichiers != null and ticket.nbFichiers > 0 ? '' + ticket.nbFichiers + ' fichier' + (ticket.nbFichiers > 1 ? 's' : '') + ' ' : ''}
-
- #{ticket.noteSatisfaction != null ? '
Note: ' + ticket.noteSatisfaction + '/5
' : ''}
-
-
-
-
-
- #{ticket.numeroTicket}
- #{ticket.sujet}
-
-
-
-
-
-
- #{ticket.dateCreation}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Actions Rapides
-
-
-
-
-
-
-
Nouveau Ticket
-
Créer une demande d'assistance
-
-
-
-
-
-
-
Consulter la FAQ
-
Réponses aux questions courantes
-
-
-
-
-
-
-
Guide Utilisateur
-
Documentation complète
-
-
-
-
-
-
-
Contact Direct
-
Appelez le support
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Mes Tickets Support - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Mes Tickets Support
+
+
+ Suivez l'état de vos demandes d'assistance et échangez avec notre équipe
+
+
+
+
+
+
+
+
+
+
#{ticketBean.totalTickets}
+
Tickets Créés
+
Au total
+
+
+
+
+
#{ticketBean.ticketsEnAttente}
+
En Attente
+
Réponse support
+
+
+
+
+
#{ticketBean.ticketsResolus}
+
Résolus
+
Avec succès
+
+
+
+
+
#{ticketBean.ticketsFermes}
+
Fermé
+
Sans résolution
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Historique de vos Tickets
+
+
+
+
+
+
+
+
+
+
+
+
#{ticket.numeroTicket} - #{ticket.sujet}
+
+
+ Créé le #{ticket.dateCreation != null ? ticket.dateCreation : 'N/A'}
+ #{ticket.dateDerniereReponse != null ? ' • Dernière réponse ' + ticket.dateDerniereReponse : ''}
+
+
+
+
+ #{ticket.agentNom != null ? '
Agent: ' + ticket.agentNom + '
' : ''}
+
+
+
+
+
+
+ #{ticket.description != null ? ticket.description : 'Aucune description'}
+
+ #{ticket.resolution != null ? '
Résolution: ' + ticket.resolution + '
' : ''}
+
+
+
+ #{ticket.nbMessages != null ? ticket.nbMessages : 0} message#{ticket.nbMessages != null and ticket.nbMessages > 1 ? 's' : ''}
+ #{ticket.nbFichiers != null and ticket.nbFichiers > 0 ? '' + ticket.nbFichiers + ' fichier' + (ticket.nbFichiers > 1 ? 's' : '') + ' ' : ''}
+
+ #{ticket.noteSatisfaction != null ? '
Note: ' + ticket.noteSatisfaction + '/5
' : ''}
+
+
+
+
+
+ #{ticket.numeroTicket}
+ #{ticket.sujet}
+
+
+
+
+
+
+ #{ticket.dateCreation}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Actions Rapides
+
+
+
+
+
+
+
Nouveau Ticket
+
Créer une demande d'assistance
+
+
+
+
+
+
+
Consulter la FAQ
+
Réponses aux questions courantes
+
+
+
+
+
+
+
Guide Utilisateur
+
Documentation complète
+
+
+
+
+
+
+
Contact Direct
+
Appelez le support
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/traitement.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/traitement.xhtml
index fddf730..2d87ae8 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/traitement.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/traitement.xhtml
@@ -1,161 +1,161 @@
-
-
-
-
- Traitement des Demandes d'Aide - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
- Traitement des Demandes d'Aide
-
-
- Gérez et traitez les demandes d'aide des membres
-
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.totalDemandes}
-
Total Demandes
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.demandesEnAttente}
-
En Attente
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.demandesApprouvees}
-
Approuvées
-
-
-
-
-
-
-
-
-
-
-
-
#{demandesAideBean.statistiques.demandesRejetees}
-
Rejetées
-
-
-
-
-
-
-
-
-
-
-
-
Demandes à Traiter
-
-
-
-
-
-
#{demande.demandeur}
-
#{demande.telephone}
-
-
-
-
-
-
-
-
- #{demande.montantDemande} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Traitement des Demandes d'Aide - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+ Traitement des Demandes d'Aide
+
+
+ Gérez et traitez les demandes d'aide des membres
+
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.totalDemandes}
+
Total Demandes
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesEnAttente}
+
En Attente
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesApprouvees}
+
Approuvées
+
+
+
+
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesRejetees}
+
Rejetées
+
+
+
+
+
+
+
+
+
+
+
+
Demandes à Traiter
+
+
+
+
+
+
#{demande.demandeur}
+
#{demande.telephone}
+
+
+
+
+
+
+
+
+ #{demande.montantDemande} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/aide/tutoriels.xhtml b/src/main/resources/META-INF/resources/pages/secure/aide/tutoriels.xhtml
index d71cb43..8137765 100644
--- a/src/main/resources/META-INF/resources/pages/secure/aide/tutoriels.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/aide/tutoriels.xhtml
@@ -1,368 +1,368 @@
-
-
-
-
- Tutoriels Vidéo - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Tutoriels Vidéo
-
-
- Apprenez UnionFlow grâce à nos tutoriels vidéo étape par étape
-
-
-
-
-
-
-
-
-
-
24
-
Tutoriels
-
Disponibles
-
-
-
-
-
4h 32m
-
Durée Totale
-
Contenu vidéo
-
-
-
-
-
1,847
-
Vues
-
Ce mois-ci
-
-
-
-
-
4.8★
-
Note Moyenne
-
Sur 156 avis
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Premiers Pas avec UnionFlow
-
-
-
-
-
-
-
-
-
Première Connexion
-
Découvrez comment vous connecter pour la première fois à UnionFlow
-
-
-
- 2,341 vues
-
-
-
- 4.9
-
-
-
-
-
-
-
-
-
-
-
-
Navigation dans l'Interface
-
Tour complet de l'interface utilisateur et des menus principaux
-
-
-
- 1,876 vues
-
-
-
- 4.7
-
-
-
-
-
-
-
-
-
-
-
-
Personnaliser son Profil
-
Comment configurer vos informations personnelles et préférences
-
-
-
- 1,432 vues
-
-
-
- 4.8
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Gestion des Membres
-
-
-
-
-
-
-
-
-
Inscrire un Nouveau Membre
-
Processus complet d'inscription d'un membre avec toutes les étapes
-
-
-
- 987 vues
-
-
-
- 5.0
-
-
-
-
-
-
-
-
-
-
-
-
Recherche Avancée
-
Utiliser les filtres et critères de recherche pour trouver des membres
-
-
-
- 1,234 vues
-
-
-
- 4.6
-
-
-
-
-
-
-
-
-
-
-
-
Export et Rapports Membres
-
Générer des exports Excel et des rapports personnalisés
-
-
-
- 765 vues
-
-
-
- 4.9
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Playlists Recommandées
-
-
-
-
-
-
-
-
-
Formation Complète Débutant
-
8 vidéos • 45 min
-
-
-
- Parcours complet pour débuter avec UnionFlow, de la connexion à la première utilisation
-
-
-
-
-
-
-
-
-
-
-
Administration Avancée
-
12 vidéos • 2h 15min
-
-
-
- Maîtrisez l'administration d'UnionFlow : utilisateurs, rôles, permissions et configuration
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Tutoriels Vidéo - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Tutoriels Vidéo
+
+
+ Apprenez UnionFlow grâce à nos tutoriels vidéo étape par étape
+
+
+
+
+
+
+
+
+
+
24
+
Tutoriels
+
Disponibles
+
+
+
+
+
4h 32m
+
Durée Totale
+
Contenu vidéo
+
+
+
+
+
1,847
+
Vues
+
Ce mois-ci
+
+
+
+
+
4.8★
+
Note Moyenne
+
Sur 156 avis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Premiers Pas avec UnionFlow
+
+
+
+
+
+
+
+
+
Première Connexion
+
Découvrez comment vous connecter pour la première fois à UnionFlow
+
+
+
+ 2,341 vues
+
+
+
+ 4.9
+
+
+
+
+
+
+
+
+
+
+
+
Navigation dans l'Interface
+
Tour complet de l'interface utilisateur et des menus principaux
+
+
+
+ 1,876 vues
+
+
+
+ 4.7
+
+
+
+
+
+
+
+
+
+
+
+
Personnaliser son Profil
+
Comment configurer vos informations personnelles et préférences
+
+
+
+ 1,432 vues
+
+
+
+ 4.8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gestion des Membres
+
+
+
+
+
+
+
+
+
Inscrire un Nouveau Membre
+
Processus complet d'inscription d'un membre avec toutes les étapes
+
+
+
+ 987 vues
+
+
+
+ 5.0
+
+
+
+
+
+
+
+
+
+
+
+
Recherche Avancée
+
Utiliser les filtres et critères de recherche pour trouver des membres
+
+
+
+ 1,234 vues
+
+
+
+ 4.6
+
+
+
+
+
+
+
+
+
+
+
+
Export et Rapports Membres
+
Générer des exports Excel et des rapports personnalisés
+
+
+
+ 765 vues
+
+
+
+ 4.9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Playlists Recommandées
+
+
+
+
+
+
+
+
+
Formation Complète Débutant
+
8 vidéos • 45 min
+
+
+
+ Parcours complet pour débuter avec UnionFlow, de la connexion à la première utilisation
+
+
+
+
+
+
+
+
+
+
+
Administration Avancée
+
12 vidéos • 2h 15min
+
+
+
+ Maîtrisez l'administration d'UnionFlow : utilisateurs, rôles, permissions et configuration
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/communication/notifications.xhtml b/src/main/resources/META-INF/resources/pages/secure/communication/notifications.xhtml
index 5442dd6..96e086a 100644
--- a/src/main/resources/META-INF/resources/pages/secure/communication/notifications.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/communication/notifications.xhtml
@@ -1,126 +1,126 @@
-
-
-
- Notifications - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{notification.sujet}
-
-
- #{notification.corps != null ? (notification.corps.length() > 100 ? notification.corps.substring(0, 100) + '...' : notification.corps) : ''}
-
-
- #{notification.dateCreation}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Notifications - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{notification.sujet}
+
+
+ #{notification.corps != null ? (notification.corps.length() > 100 ? notification.corps.substring(0, 100) + '...' : notification.corps) : ''}
+
+
+ #{notification.dateCreation}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/comptabilite/gestion.xhtml b/src/main/resources/META-INF/resources/pages/secure/comptabilite/gestion.xhtml
index a9a6edd..035cb39 100644
--- a/src/main/resources/META-INF/resources/pages/secure/comptabilite/gestion.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/comptabilite/gestion.xhtml
@@ -1,300 +1,300 @@
-
-
-
- Gestion Comptable - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{compte.numeroCompte}
-
-
- #{compte.libelle}
-
-
-
-
-
- #{compte.classeComptable}
-
-
- #{compte.soldeActuel != null ? compte.soldeActuel : 0} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{journal.code}
-
-
- #{journal.libelle}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{ecriture.dateEcriture}
-
-
- #{ecriture.journalId}
-
-
- #{ecriture.libelle}
-
-
- #{ecriture.montantTotal != null ? ecriture.montantTotal : 0} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion Comptable - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{compte.numeroCompte}
+
+
+ #{compte.libelle}
+
+
+
+
+
+ #{compte.classeComptable}
+
+
+ #{compte.soldeActuel != null ? compte.soldeActuel : 0} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{journal.code}
+
+
+ #{journal.libelle}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{ecriture.dateEcriture}
+
+
+ #{ecriture.journalId}
+
+
+ #{ecriture.libelle}
+
+
+ #{ecriture.montantTotal != null ? ecriture.montantTotal : 0} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/cotisation/collect.xhtml b/src/main/resources/META-INF/resources/pages/secure/cotisation/collect.xhtml
index 4f3f11c..4a5c89a 100644
--- a/src/main/resources/META-INF/resources/pages/secure/cotisation/collect.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/cotisation/collect.xhtml
@@ -1,456 +1,456 @@
-
-
-
-
- Gestion des Cotisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Liste des Cotisations
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Cotisations (#{cotisationsBean.cotisationsFiltrees.size()})
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisation.nomMembre}
-
#{cotisation.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Informations de la cotisation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Référence
-
#{cotisationsBean.cotisationSelectionnee.numeroReference}
-
-
-
-
-
-
Membre
-
#{cotisationsBean.cotisationSelectionnee.nomMembre}
-
#{cotisationsBean.cotisationSelectionnee.numeroMembre}
-
-
-
-
-
Type
-
#{cotisationsBean.cotisationSelectionnee.typeCotisationLibelle}
-
-
-
-
-
Montant dû
-
#{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
-
-
-
-
-
Montant payé
-
#{cotisationsBean.cotisationSelectionnee.montantPayeFormatte}
-
-
-
-
-
Date d'échéance
-
#{cotisationsBean.cotisationSelectionnee.dateEcheanceFormattee}
-
-
-
-
-
Date de paiement
-
#{cotisationsBean.cotisationSelectionnee.datePaiementFormattee}
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Gestion des Cotisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Liste des Cotisations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cotisations (#{cotisationsBean.cotisationsFiltrees.size()})
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisation.nomMembre}
+
#{cotisation.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Informations de la cotisation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Référence
+
#{cotisationsBean.cotisationSelectionnee.numeroReference}
+
+
+
+
+
+
Membre
+
#{cotisationsBean.cotisationSelectionnee.nomMembre}
+
#{cotisationsBean.cotisationSelectionnee.numeroMembre}
+
+
+
+
+
Type
+
#{cotisationsBean.cotisationSelectionnee.typeCotisationLibelle}
+
+
+
+
+
Montant dû
+
#{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
+
+
+
+
+
Montant payé
+
#{cotisationsBean.cotisationSelectionnee.montantPayeFormatte}
+
+
+
+
+
Date d'échéance
+
#{cotisationsBean.cotisationSelectionnee.dateEcheanceFormattee}
+
+
+
+
+
Date de paiement
+
#{cotisationsBean.cotisationSelectionnee.datePaiementFormattee}
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/cotisation/historique.xhtml b/src/main/resources/META-INF/resources/pages/secure/cotisation/historique.xhtml
index 7a34c8a..c5440db 100644
--- a/src/main/resources/META-INF/resources/pages/secure/cotisation/historique.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/cotisation/historique.xhtml
@@ -1,253 +1,253 @@
-
-
-
-
- Historique des Cotisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Filtres de Recherche
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Historique des Cotisations
-
-
-
-
-
- Historique (#{cotisationsBean.cotisationsFiltrees.size()} cotisation(s))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisation.nomMembre}
-
#{cotisation.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Référence
-
#{cotisationsBean.cotisationSelectionnee.numeroReference}
-
-
-
-
-
-
Membre
-
#{cotisationsBean.cotisationSelectionnee.nomMembre}
-
N° #{cotisationsBean.cotisationSelectionnee.numeroMembre}
-
-
-
-
-
Type
-
#{cotisationsBean.cotisationSelectionnee.typeCotisationLibelle}
-
-
-
-
-
Date d'échéance
-
#{cotisationsBean.cotisationSelectionnee.dateEcheanceFormattee}
-
-
-
-
-
Montant dû
-
#{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
-
-
-
-
-
Montant payé
-
#{cotisationsBean.cotisationSelectionnee.montantPayeFormatte}
-
-
-
-
-
Montant restant
-
#{cotisationsBean.cotisationSelectionnee.montantRestantFormatte}
-
-
-
-
-
Date de paiement
-
#{cotisationsBean.cotisationSelectionnee.datePaiementFormattee}
-
-
-
-
-
Méthode de paiement
-
#{cotisationsBean.cotisationSelectionnee.methodePaiementLibelle}
-
-
-
-
-
Observations
-
#{cotisationsBean.cotisationSelectionnee.observations}
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Historique des Cotisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Filtres de Recherche
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Historique des Cotisations
+
+
+
+
+
+ Historique (#{cotisationsBean.cotisationsFiltrees.size()} cotisation(s))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisation.nomMembre}
+
#{cotisation.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Référence
+
#{cotisationsBean.cotisationSelectionnee.numeroReference}
+
+
+
+
+
+
Membre
+
#{cotisationsBean.cotisationSelectionnee.nomMembre}
+
N° #{cotisationsBean.cotisationSelectionnee.numeroMembre}
+
+
+
+
+
Type
+
#{cotisationsBean.cotisationSelectionnee.typeCotisationLibelle}
+
+
+
+
+
Date d'échéance
+
#{cotisationsBean.cotisationSelectionnee.dateEcheanceFormattee}
+
+
+
+
+
Montant dû
+
#{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
+
+
+
+
+
Montant payé
+
#{cotisationsBean.cotisationSelectionnee.montantPayeFormatte}
+
+
+
+
+
Montant restant
+
#{cotisationsBean.cotisationSelectionnee.montantRestantFormatte}
+
+
+
+
+
Date de paiement
+
#{cotisationsBean.cotisationSelectionnee.datePaiementFormattee}
+
+
+
+
+
Méthode de paiement
+
#{cotisationsBean.cotisationSelectionnee.methodePaiementLibelle}
+
+
+
+
+
Observations
+
#{cotisationsBean.cotisationSelectionnee.observations}
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/cotisation/paiement.xhtml b/src/main/resources/META-INF/resources/pages/secure/cotisation/paiement.xhtml
index c97a1a6..c49db44 100644
--- a/src/main/resources/META-INF/resources/pages/secure/cotisation/paiement.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/cotisation/paiement.xhtml
@@ -1,473 +1,473 @@
-
-
-
-
- #{cotisationsBean.vueAdmin ? 'Paiement de Cotisations' : 'Payer mes Cotisations'} - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Répartition par Méthode de Paiement
-
-
-
-
-
-
-
-
-
-
-
-
#{methode.methode}
-
#{methode.montantFormatte}
-
-
-
-
#{methode.pourcentageInt}%
-
-
-
-
-
-
-
-
-
-
- #{methode.methode}
- #{methode.pourcentageInt}%
-
-
-
-
-
-
-
-
-
-
-
-
- #{cotisationsBean.vueAdmin ? 'Cotisations en Attente de Paiement' : 'Mes Cotisations en Attente'}
-
-
-
-
-
-
Cotisations à payer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisation.nomMembre}
-
#{cotisation.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Cotisation
-
#{cotisationsBean.cotisationSelectionnee.numeroReference} - #{cotisationsBean.cotisationSelectionnee.nomMembre}
-
Montant dû: #{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Cotisation
-
#{cotisationsBean.cotisationSelectionnee.numeroReference} - #{cotisationsBean.cotisationSelectionnee.nomMembre}
-
Montant dû: #{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
-
Montant restant: #{cotisationsBean.cotisationSelectionnee.montantRestantFormatte}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
-
#{cotisationsBean.cotisationSelectionnee.numeroReference}
- — #{cotisationsBean.cotisationSelectionnee.typeCotisationLibelle}
-
-
-
-
-
-
-
-
-
-
- Scannez ce QR code avec l'application Wave
- Le QR code expire dans 30 minutes
-
-
-
-
- ✅
- Paiement confirmé !
- Votre cotisation a été enregistrée.
-
-
-
-
- ⏱️
- Session expirée
- Veuillez fermer et recommencer.
-
-
-
-
-
-
-
- Ouvrez l'application Wave sur votre téléphone
- Appuyez sur Scanner
- Scannez le QR code ci-dessus
- Confirmez le paiement de #{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
- Cette page se mettra à jour automatiquement
-
-
-
-
-
-
-
-
-
-
-
-
- //
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ #{cotisationsBean.vueAdmin ? 'Paiement de Cotisations' : 'Payer mes Cotisations'} - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Répartition par Méthode de Paiement
+
+
+
+
+
+
+
+
+
+
+
+
#{methode.methode}
+
#{methode.montantFormatte}
+
+
+
+
#{methode.pourcentageInt}%
+
+
+
+
+
+
+
+
+
+
+ #{methode.methode}
+ #{methode.pourcentageInt}%
+
+
+
+
+
+
+
+
+
+
+
+
+ #{cotisationsBean.vueAdmin ? 'Cotisations en Attente de Paiement' : 'Mes Cotisations en Attente'}
+
+
+
+
+
+
Cotisations à payer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisation.nomMembre}
+
#{cotisation.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cotisation
+
#{cotisationsBean.cotisationSelectionnee.numeroReference} - #{cotisationsBean.cotisationSelectionnee.nomMembre}
+
Montant dû: #{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cotisation
+
#{cotisationsBean.cotisationSelectionnee.numeroReference} - #{cotisationsBean.cotisationSelectionnee.nomMembre}
+
Montant dû: #{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
+
Montant restant: #{cotisationsBean.cotisationSelectionnee.montantRestantFormatte}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
+
#{cotisationsBean.cotisationSelectionnee.numeroReference}
+ — #{cotisationsBean.cotisationSelectionnee.typeCotisationLibelle}
+
+
+
+
+
+
+
+
+
+
+ Scannez ce QR code avec l'application Wave
+ Le QR code expire dans 30 minutes
+
+
+
+
+ ✅
+ Paiement confirmé !
+ Votre cotisation a été enregistrée.
+
+
+
+
+ ⏱️
+ Session expirée
+ Veuillez fermer et recommencer.
+
+
+
+
+
+
+
+ Ouvrez l'application Wave sur votre téléphone
+ Appuyez sur Scanner
+ Scannez le QR code ci-dessus
+ Confirmez le paiement de #{cotisationsBean.cotisationSelectionnee.montantDuFormatte}
+ Cette page se mettra à jour automatiquement
+
+
+
+
+
+
+
+
+
+
+
+
+ //
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/cotisation/rapports.xhtml b/src/main/resources/META-INF/resources/pages/secure/cotisation/rapports.xhtml
index ce039c7..2f86a69 100644
--- a/src/main/resources/META-INF/resources/pages/secure/cotisation/rapports.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/cotisation/rapports.xhtml
@@ -1,185 +1,185 @@
-
-
-
-
- Rapports Financiers - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Évolution des Paiements (12 derniers mois)
-
-
-
-
-
#{evolution.mois}
-
-
-
-
#{evolution.montantFormatte}
-
-
-
-
-
-
-
-
-
-
-
-
- Répartition par Méthode
-
-
-
-
-
- #{methode.methode}
- #{methode.pourcentageInt}%
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Résumé des Cotisations
-
-
-
-
-
Par Statut
-
-
-
-
Partiellement payées
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Rapports Financiers - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Évolution des Paiements (12 derniers mois)
+
+
+
+
+
#{evolution.mois}
+
+
+
+
#{evolution.montantFormatte}
+
+
+
+
+
+
+
+
+
+
+
+
+ Répartition par Méthode
+
+
+
+
+
+ #{methode.methode}
+ #{methode.pourcentageInt}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Résumé des Cotisations
+
+
+
+
+
Par Statut
+
+
+
+
Partiellement payées
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/cotisation/relances.xhtml b/src/main/resources/META-INF/resources/pages/secure/cotisation/relances.xhtml
index de12092..c1ed95b 100644
--- a/src/main/resources/META-INF/resources/pages/secure/cotisation/relances.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/cotisation/relances.xhtml
@@ -1,229 +1,229 @@
-
-
-
-
- Relances de Cotisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Rappels en Attente
-
-
-
-
-
-
-
#{rappel.nomMembre}
-
#{rappel.club}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cotisations en Retard
-
-
-
-
-
-
Cotisations nécessitant une relance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisation.nomMembre}
-
#{cotisation.numeroMembre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Destinataires :
-
#{cotisationsBean.cotisationsSelectionnees.size()} cotisation(s) sélectionnée(s)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Relances de Cotisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Rappels en Attente
+
+
+
+
+
+
+
#{rappel.nomMembre}
+
#{rappel.club}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cotisations en Retard
+
+
+
+
+
+
Cotisations nécessitant une relance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisation.nomMembre}
+
#{cotisation.numeroMembre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Destinataires :
+
#{cotisationsBean.cotisationsSelectionnees.size()} cotisation(s) sélectionnée(s)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/cotisation/reminders.xhtml b/src/main/resources/META-INF/resources/pages/secure/cotisation/reminders.xhtml
index 1241bde..f6d6a9c 100644
--- a/src/main/resources/META-INF/resources/pages/secure/cotisation/reminders.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/cotisation/reminders.xhtml
@@ -1,108 +1,108 @@
-
-
-
- Rappels de Cotisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Rappels de Cotisations
-
-
- Gérez et envoyez les rappels de cotisations aux membres
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisationsGestionBean.nombreMembresEnRetard}
-
En Retard
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisationsGestionBean.nombreRappelsEnvoyes}
-
Rappels Envoyés
-
-
-
-
-
-
-
-
-
-
-
-
Membres avec Cotisations en Retard
-
-
-
-
-
-
-
-
#{membre.nomComplet}
-
#{membre.numeroMembre}
-
-
-
-
- #{membre.montantDu} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Rappels de Cotisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Rappels de Cotisations
+
+
+ Gérez et envoyez les rappels de cotisations aux membres
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisationsGestionBean.nombreMembresEnRetard}
+
En Retard
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisationsGestionBean.nombreRappelsEnvoyes}
+
Rappels Envoyés
+
+
+
+
+
+
+
+
+
+
+
+
Membres avec Cotisations en Retard
+
+
+
+
+
+
+
+
#{membre.nomComplet}
+
#{membre.numeroMembre}
+
+
+
+
+ #{membre.montantDu} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/cotisation/report.xhtml b/src/main/resources/META-INF/resources/pages/secure/cotisation/report.xhtml
index 1e86f0a..18d8a20 100644
--- a/src/main/resources/META-INF/resources/pages/secure/cotisation/report.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/cotisation/report.xhtml
@@ -1,117 +1,117 @@
-
-
-
- Rapports de Cotisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Rapports de Cotisations
-
-
- Générez et consultez les rapports détaillés sur les cotisations
-
-
-
-
-
-
-
-
-
Paramètres du Rapport
-
-
-
-
-
-
Rapports Disponibles
-
-
-
-
-
-
-
Rapport Mensuel
- Rapport complet du mois
-
-
-
-
-
-
-
-
-
-
-
Rapport Annuel
- Synthèse de l'année
-
-
-
-
-
-
-
-
-
-
-
Rapport Analytique
- Analyses et statistiques
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Rapports de Cotisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Rapports de Cotisations
+
+
+ Générez et consultez les rapports détaillés sur les cotisations
+
+
+
+
+
+
+
+
+
Paramètres du Rapport
+
+
+
+
+
+
Rapports Disponibles
+
+
+
+
+
+
+
Rapport Mensuel
+ Rapport complet du mois
+
+
+
+
+
+
+
+
+
+
+
Rapport Annuel
+ Synthèse de l'année
+
+
+
+
+
+
+
+
+
+
+
Rapport Analytique
+ Analyses et statistiques
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/credit/demandes.xhtml b/src/main/resources/META-INF/resources/pages/secure/credit/demandes.xhtml
index 1e8da72..a2bbb19 100644
--- a/src/main/resources/META-INF/resources/pages/secure/credit/demandes.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/credit/demandes.xhtml
@@ -1,30 +1,30 @@
-
-
-
- Demandes de Crédit - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Demandes de crédit
-
La liste des demandes de crédit à traiter sera affichée ici lorsque le module sera connecté au backend.
-
-
-
-
-
-
+
+
+
+ Demandes de Crédit - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Demandes de crédit
+
La liste des demandes de crédit à traiter sera affichée ici lorsque le module sera connecté au backend.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/credit/evaluation.xhtml b/src/main/resources/META-INF/resources/pages/secure/credit/evaluation.xhtml
index ddeae24..446331c 100644
--- a/src/main/resources/META-INF/resources/pages/secure/credit/evaluation.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/credit/evaluation.xhtml
@@ -1,30 +1,30 @@
-
-
-
- Évaluation Solvabilité - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Évaluation solvabilité
-
Les outils d'évaluation de solvabilité seront disponibles ici lorsque le module crédit sera opérationnel.
-
-
-
-
-
-
+
+
+
+ Évaluation Solvabilité - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Évaluation solvabilité
+
Les outils d'évaluation de solvabilité seront disponibles ici lorsque le module crédit sera opérationnel.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/credit/remboursements.xhtml b/src/main/resources/META-INF/resources/pages/secure/credit/remboursements.xhtml
index 7daf587..c6c14cb 100644
--- a/src/main/resources/META-INF/resources/pages/secure/credit/remboursements.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/credit/remboursements.xhtml
@@ -1,30 +1,30 @@
-
-
-
- Remboursements - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Remboursements
-
La gestion des remboursements sera disponible ici lorsque le module crédit sera branché.
-
-
-
-
-
-
+
+
+
+ Remboursements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Remboursements
+
La gestion des remboursements sera disponible ici lorsque le module crédit sera branché.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/credit/statistiques.xhtml b/src/main/resources/META-INF/resources/pages/secure/credit/statistiques.xhtml
index 56d9f53..3790e87 100644
--- a/src/main/resources/META-INF/resources/pages/secure/credit/statistiques.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/credit/statistiques.xhtml
@@ -1,30 +1,30 @@
-
-
-
- Statistiques Crédit - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Statistiques crédit
-
Les indicateurs et statistiques du portefeuille crédit seront affichés ici lorsque le module sera opérationnel.
-
-
-
-
-
-
+
+
+
+ Statistiques Crédit - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Statistiques crédit
+
Les indicateurs et statistiques du portefeuille crédit seront affichés ici lorsque le module sera opérationnel.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/credit/suivi.xhtml b/src/main/resources/META-INF/resources/pages/secure/credit/suivi.xhtml
index 63f93ef..36a3045 100644
--- a/src/main/resources/META-INF/resources/pages/secure/credit/suivi.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/credit/suivi.xhtml
@@ -1,30 +1,30 @@
-
-
-
- Suivi des Crédits - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Suivi des crédits
-
Le suivi des crédits accordés sera affiché ici une fois le module connecté.
-
-
-
-
-
-
+
+
+
+ Suivi des Crédits - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Suivi des crédits
+
Le suivi des crédits accordés sera affiché ici une fois le module connecté.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/dashboard.xhtml b/src/main/resources/META-INF/resources/pages/secure/dashboard.xhtml
index a259c62..7567042 100644
--- a/src/main/resources/META-INF/resources/pages/secure/dashboard.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/dashboard.xhtml
@@ -1,594 +1,594 @@
-
-
-
- UnionFlow - Tableau de bord
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Tableau de bord UnionFlow
-
Bienvenue #{userSession.currentUser != null ? userSession.currentUser.nomComplet : userSession.username}, voici un aperçu de votre union
-
-
- #{dashboardBean.currentDate}
- |
-
- #{dashboardBean.totalMembers} membres inscrits
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Actions requises aujourd'hui
-
-
-
-
-
-
-
-
-
-
-
#{dashboardBean.cotisationsRetard}
-
Cotisations en retard
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{dashboardBean.adhesionsExpiration}
-
Expire dans 7 jours
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{dashboardBean.demandesToTraiter}
-
Demandes en attente
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{dashboardBean.tachesCompletees}
-
Complétées aujourd'hui
-
-
-
-
-
-
-
-
-
-
-
-
-
- Vue d'ensemble
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Évolution financière (3 derniers mois)
-
-
-
-
-
-
-
-
-
#{mois.libelle}
-
-
-
#{mois.montantFormatte}
-
-
-
-
-
-
-
-
-
-
-
-
#{dashboardBean.evolutionRecettesPrefix}#{dashboardBean.evolutionRecettesPourcent}%
-
Recettes vs mois dernier
-
-
-
-
-
-
-
-
#{dashboardBean.evolutionDepensesPrefix}#{dashboardBean.evolutionDepensesPourcent}%
-
Dépenses vs mois dernier
-
-
-
-
-
-
-
-
#{dashboardBean.tendanceParticipation}
-
Taux de participation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
État des cotisations
-
-
-
-
-
-
- #{dashboardBean.cotisationsAJourPourcent}%
-
-
-
-
-
-
-
-
-
-
#{dashboardBean.cotisationsAJourPourcent}%
-
-
-
-
#{dashboardBean.cotisationsRetardPourcent}%
-
-
-
-
#{dashboardBean.cotisationsImpayeesPourcent}%
-
-
-
-
-
-
-
- Taux de collecte
- #{dashboardBean.tauxCollecte}%
-
-
-
-
-
- Objectif mensuel
- #{dashboardBean.tauxObjectifCotisations}%
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Journal d'activités
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{activity.titre}
-
#{activity.description}
-
-
- #{activity.montant} FCFA
-
-
-
-
-
-
-
-
-
-
-
#{activity.userNom}
-
#{activity.userRole}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Actions rapides
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Tâches prioritaires
-
-
-
-
-
-
-
Valider #{dashboardBean.adhesionsPendantes} adhésions
-
Demandes en attente de validation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Relancer #{dashboardBean.cotisationsRetard} cotisations
-
Paiements en retard
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Traiter #{dashboardBean.aidesEnAttente} aides
-
Demandes d'aide à examiner
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Organiser prochains événements
-
#{dashboardBean.evenementsAPlanifier} événements à planifier
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Résumé financier mensuel
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{dashboardBean.recettesMois} FCFA
-
Recettes totales
-
-
-
-
-
#{dashboardBean.depensesMois} FCFA
-
Dépenses totales
-
-
-
-
-
#{dashboardBean.soldeMois} FCFA
-
Solde net
-
-
-
-
-
#{dashboardBean.tresorerie} FCFA
-
Trésorerie actuelle
-
-
-
-
-
-
-
-
-
+
+
+
+ UnionFlow - Tableau de bord
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Tableau de bord UnionFlow
+
Bienvenue #{userSession.currentUser != null ? userSession.currentUser.nomComplet : userSession.username}, voici un aperçu de votre union
+
+
+ #{dashboardBean.currentDate}
+ |
+
+ #{dashboardBean.totalMembers} membres inscrits
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Actions requises aujourd'hui
+
+
+
+
+
+
+
+
+
+
+
#{dashboardBean.cotisationsRetard}
+
Cotisations en retard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{dashboardBean.adhesionsExpiration}
+
Expire dans 7 jours
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{dashboardBean.demandesToTraiter}
+
Demandes en attente
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{dashboardBean.tachesCompletees}
+
Complétées aujourd'hui
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vue d'ensemble
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Évolution financière (3 derniers mois)
+
+
+
+
+
+
+
+
+
#{mois.libelle}
+
+
+
#{mois.montantFormatte}
+
+
+
+
+
+
+
+
+
+
+
+
#{dashboardBean.evolutionRecettesPrefix}#{dashboardBean.evolutionRecettesPourcent}%
+
Recettes vs mois dernier
+
+
+
+
+
+
+
+
#{dashboardBean.evolutionDepensesPrefix}#{dashboardBean.evolutionDepensesPourcent}%
+
Dépenses vs mois dernier
+
+
+
+
+
+
+
+
#{dashboardBean.tendanceParticipation}
+
Taux de participation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
État des cotisations
+
+
+
+
+
+
+ #{dashboardBean.cotisationsAJourPourcent}%
+
+
+
+
+
+
+
+
+
+
#{dashboardBean.cotisationsAJourPourcent}%
+
+
+
+
#{dashboardBean.cotisationsRetardPourcent}%
+
+
+
+
#{dashboardBean.cotisationsImpayeesPourcent}%
+
+
+
+
+
+
+
+ Taux de collecte
+ #{dashboardBean.tauxCollecte}%
+
+
+
+
+
+ Objectif mensuel
+ #{dashboardBean.tauxObjectifCotisations}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Journal d'activités
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{activity.titre}
+
#{activity.description}
+
+
+ #{activity.montant} FCFA
+
+
+
+
+
+
+
+
+
+
+
#{activity.userNom}
+
#{activity.userRole}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Actions rapides
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Tâches prioritaires
+
+
+
+
+
+
+
Valider #{dashboardBean.adhesionsPendantes} adhésions
+
Demandes en attente de validation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Relancer #{dashboardBean.cotisationsRetard} cotisations
+
Paiements en retard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Traiter #{dashboardBean.aidesEnAttente} aides
+
Demandes d'aide à examiner
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Organiser prochains événements
+
#{dashboardBean.evenementsAPlanifier} événements à planifier
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Résumé financier mensuel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{dashboardBean.recettesMois} FCFA
+
Recettes totales
+
+
+
+
+
#{dashboardBean.depensesMois} FCFA
+
Dépenses totales
+
+
+
+
+
#{dashboardBean.soldeMois} FCFA
+
Solde net
+
+
+
+
+
#{dashboardBean.tresorerie} FCFA
+
Trésorerie actuelle
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/documents/mes-documents.xhtml b/src/main/resources/META-INF/resources/pages/secure/documents/mes-documents.xhtml
index 600990d..064d8f3 100644
--- a/src/main/resources/META-INF/resources/pages/secure/documents/mes-documents.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/documents/mes-documents.xhtml
@@ -1,130 +1,130 @@
-
-
-
- Mes Documents - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{document.nomFichier}
-
-
-
-
-
- #{document.tailleOctets != null ? (document.tailleOctets / 1024) + ' KB' : 'N/A'}
-
-
- #{document.dateCreation}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Mes Documents - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{document.nomFichier}
+
+
+
+
+
+ #{document.tailleOctets != null ? (document.tailleOctets / 1024) + ' KB' : 'N/A'}
+
+
+ #{document.dateCreation}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/bilan.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/bilan.xhtml
index 144cd0c..b6fb687 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/bilan.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/bilan.xhtml
@@ -1,198 +1,198 @@
-
-
-
-
- Bilan des Événements - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Bilans par Événement
-
-
-
-
-
- #{evenement.titre}
-
- #{evenement.typeEvenementLibelle}
-
-
-
-
- #{evenement.dateDebutFormatee}
-
-
-
-
- 0
- / 0 prévus
-
-
-
-
-
- 0 XOF
-
- 0 XOF prévu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Évolution des participations
-
Graphique en développement
-
-
-
-
-
Répartition par type
-
Graphique en développement
-
-
-
-
-
-
+
+
+
+
+ Bilan des Événements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Bilans par Événement
+
+
+
+
+
+ #{evenement.titre}
+
+ #{evenement.typeEvenementLibelle}
+
+
+
+
+ #{evenement.dateDebutFormatee}
+
+
+
+
+ 0
+ / 0 prévus
+
+
+
+
+
+ 0 XOF
+
+ 0 XOF prévu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Évolution des participations
+
Graphique en développement
+
+
+
+
+
Répartition par type
+
Graphique en développement
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/calendar.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/calendar.xhtml
index 83a9abd..a6882df 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/calendar.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/calendar.xhtml
@@ -1,18 +1,18 @@
-
-
-
- Calendrier des Événements - UnionFlow
-
-
-
-
-
-
-
+
+
+
+ Calendrier des Événements - UnionFlow
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/calendrier.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/calendrier.xhtml
index 1bb5e99..e3b6e69 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/calendrier.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/calendrier.xhtml
@@ -1,183 +1,183 @@
-
-
-
-
- Calendrier des Événements - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Calendrier
-
-
-
-
Calendrier des Événements
-
La vue calendrier interactive sera disponible prochainement
-
En attendant, utilisez la liste des événements à venir ci-dessous
-
-
-
-
-
-
-
- Événements à Venir
-
-
-
-
-
-
#{evenement.dateDebutFormatee}
-
#{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}
-
-
-
-
-
-
-
-
#{evenement.titre}
-
#{evenement.lieu}
-
-
-
-
-
-
-
-
-
- #{evenement.participantsInscrits} / #{evenement.capaciteMax}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{evenementsBean.evenementSelectionne.titre}
-
#{evenementsBean.evenementSelectionne.description}
-
-
-
-
-
-
-
-
-
Date de début
-
#{evenementsBean.evenementSelectionne.dateDebutFormatee}
-
#{evenementsBean.evenementSelectionne.heureDebutFormatee}
-
-
-
-
-
-
Lieu
-
#{evenementsBean.evenementSelectionne.lieu}
-
#{evenementsBean.evenementSelectionne.adresseComplete}
-
-
-
-
-
-
Participants
-
#{evenementsBean.evenementSelectionne.participantsInscrits} / #{evenementsBean.evenementSelectionne.capaciteMax}
-
-
-
-
-
-
-
Budget
-
#{evenementsBean.evenementSelectionne.budgetFormate}
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Calendrier des Événements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Calendrier
+
+
+
+
Calendrier des Événements
+
La vue calendrier interactive sera disponible prochainement
+
En attendant, utilisez la liste des événements à venir ci-dessous
+
+
+
+
+
+
+
+ Événements à Venir
+
+
+
+
+
+
#{evenement.dateDebutFormatee}
+
#{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}
+
+
+
+
+
+
+
+
#{evenement.titre}
+
#{evenement.lieu}
+
+
+
+
+
+
+
+
+
+ #{evenement.participantsInscrits} / #{evenement.capaciteMax}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{evenementsBean.evenementSelectionne.titre}
+
#{evenementsBean.evenementSelectionne.description}
+
+
+
+
+
+
+
+
+
Date de début
+
#{evenementsBean.evenementSelectionne.dateDebutFormatee}
+
#{evenementsBean.evenementSelectionne.heureDebutFormatee}
+
+
+
+
+
+
Lieu
+
#{evenementsBean.evenementSelectionne.lieu}
+
#{evenementsBean.evenementSelectionne.adresseComplete}
+
+
+
+
+
+
Participants
+
#{evenementsBean.evenementSelectionne.participantsInscrits} / #{evenementsBean.evenementSelectionne.capaciteMax}
+
+
+
+
+
+
+
Budget
+
#{evenementsBean.evenementSelectionne.budgetFormate}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/create.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/create.xhtml
index 49bab80..6dcdd52 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/create.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/create.xhtml
@@ -1,18 +1,18 @@
-
-
-
- Créer un Événement - UnionFlow
-
-
-
-
-
-
-
+
+
+
+ Créer un Événement - UnionFlow
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/creation.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/creation.xhtml
index 3332ede..017b34b 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/creation.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/creation.xhtml
@@ -1,268 +1,268 @@
-
-
-
-
- Création d'Événement - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Création d'Événement - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/logistique.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/logistique.xhtml
index 54c1473..e0223a1 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/logistique.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/logistique.xhtml
@@ -1,180 +1,180 @@
-
-
-
-
- Logistique des Événements - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Demandes Logistiques
-
-
-
-
- #{evenement.titre}
-
-
-
-
-
-
-
- 0
-
-
-
- À planifier
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Fonctionnalité en développement
-
La gestion logistique complète des événements sera disponible prochainement.
-
-
-
-
-
-
+
+
+
+
+ Logistique des Événements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Demandes Logistiques
+
+
+
+
+ #{evenement.titre}
+
+
+
+
+
+
+
+ 0
+
+
+
+ À planifier
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fonctionnalité en développement
+
La gestion logistique complète des événements sera disponible prochainement.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/participants.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/participants.xhtml
index d14937f..2278dbe 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/participants.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/participants.xhtml
@@ -1,120 +1,120 @@
-
-
-
-
- Gestion des Participants - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sélectionner un Événement
-
-
-
-
-
-
-
- Participants - #{evenementsBean.evenementSelectionne.titre}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Gestion des Participants
-
La gestion détaillée des participants sera disponible prochainement
-
- Participants inscrits: #{evenementsBean.evenementSelectionne.participantsInscrits} /
- Capacité: #{evenementsBean.evenementSelectionne.capaciteMax}
-
-
-
-
-
-
-
-
-
-
Sélectionnez un événement
-
Veuillez sélectionner un événement pour voir ses participants
-
-
-
-
-
+
+
+
+
+ Gestion des Participants - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sélectionner un Événement
+
+
+
+
+
+
+
+ Participants - #{evenementsBean.evenementSelectionne.titre}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Gestion des Participants
+
La gestion détaillée des participants sera disponible prochainement
+
+ Participants inscrits: #{evenementsBean.evenementSelectionne.participantsInscrits} /
+ Capacité: #{evenementsBean.evenementSelectionne.capaciteMax}
+
+
+
+
+
+
+
+
+
+
Sélectionnez un événement
+
Veuillez sélectionner un événement pour voir ses participants
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/participation.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/participation.xhtml
index cbe8671..9c8264e 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/participation.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/participation.xhtml
@@ -1,255 +1,255 @@
-
-
-
-
- Participation aux Événements - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Événements Disponibles
-
-
-
-
-
-
-
-
#{evenement.titre}
-
#{evenement.description}
-
-
-
-
-
-
-
#{evenement.dateDebutFormatee}
-
- #{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}
-
-
-
-
-
-
-
#{evenement.lieu}
-
#{evenement.ville}
-
-
-
-
-
-
#{evenement.participantsInscrits} / #{evenement.capaciteMax}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{evenementsBean.evenementSelectionne.titre}
-
#{evenementsBean.evenementSelectionne.description}
-
-
-
-
-
-
-
-
-
Date de début
-
#{evenementsBean.evenementSelectionne.dateDebutFormatee}
-
#{evenementsBean.evenementSelectionne.heureDebutFormatee}
-
-
-
-
-
-
Date de fin
-
#{evenementsBean.evenementSelectionne.dateFinFormatee}
-
#{evenementsBean.evenementSelectionne.heureFinFormatee}
-
-
-
-
-
-
Lieu
-
#{evenementsBean.evenementSelectionne.adresseComplete}
-
-
-
-
-
-
Participants
-
#{evenementsBean.evenementSelectionne.participantsInscrits} / #{evenementsBean.evenementSelectionne.capaciteMax}
-
-
-
-
-
-
-
Organisateur
-
#{evenementsBean.evenementSelectionne.organisateur}
-
#{evenementsBean.evenementSelectionne.emailOrganisateur}
-
#{evenementsBean.evenementSelectionne.telephoneOrganisateur}
-
-
-
-
-
-
Instructions
-
#{evenementsBean.evenementSelectionne.instructions}
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Participation aux Événements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Événements Disponibles
+
+
+
+
+
+
+
+
#{evenement.titre}
+
#{evenement.description}
+
+
+
+
+
+
+
#{evenement.dateDebutFormatee}
+
+ #{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}
+
+
+
+
+
+
+
#{evenement.lieu}
+
#{evenement.ville}
+
+
+
+
+
+
#{evenement.participantsInscrits} / #{evenement.capaciteMax}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{evenementsBean.evenementSelectionne.titre}
+
#{evenementsBean.evenementSelectionne.description}
+
+
+
+
+
+
+
+
+
Date de début
+
#{evenementsBean.evenementSelectionne.dateDebutFormatee}
+
#{evenementsBean.evenementSelectionne.heureDebutFormatee}
+
+
+
+
+
+
Date de fin
+
#{evenementsBean.evenementSelectionne.dateFinFormatee}
+
#{evenementsBean.evenementSelectionne.heureFinFormatee}
+
+
+
+
+
+
Lieu
+
#{evenementsBean.evenementSelectionne.adresseComplete}
+
+
+
+
+
+
Participants
+
#{evenementsBean.evenementSelectionne.participantsInscrits} / #{evenementsBean.evenementSelectionne.capaciteMax}
+
+
+
+
+
+
+
Organisateur
+
#{evenementsBean.evenementSelectionne.organisateur}
+
#{evenementsBean.evenementSelectionne.emailOrganisateur}
+
#{evenementsBean.evenementSelectionne.telephoneOrganisateur}
+
+
+
+
+
+
Instructions
+
#{evenementsBean.evenementSelectionne.instructions}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/planification.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/planification.xhtml
index 38e0338..b7cb211 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/planification.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/planification.xhtml
@@ -1,179 +1,179 @@
-
-
-
-
- Planification des Événements - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Planifications
-
-
-
-
- #{evenement.titre}
-
-
-
-
-
Date à définir
-
Période: À planifier
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Fonctionnalité en développement
-
La planification avancée des événements sera disponible prochainement.
-
-
-
-
-
-
+
+
+
+
+ Planification des Événements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Planifications
+
+
+
+
+ #{evenement.titre}
+
+
+
+
+
Date à définir
+
Période: À planifier
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fonctionnalité en développement
+
La planification avancée des événements sera disponible prochainement.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/evenement/reservations.xhtml b/src/main/resources/META-INF/resources/pages/secure/evenement/reservations.xhtml
index 51c6629..ac06698 100644
--- a/src/main/resources/META-INF/resources/pages/secure/evenement/reservations.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/evenement/reservations.xhtml
@@ -1,187 +1,187 @@
-
-
-
-
- Réservations d'Événements - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Réservations
-
-
-
-
-
- Nom du membre
-
- email@example.com
-
-
-
-
- #{evenement.titre}
-
-
-
- À définir
-
-
-
- 1
-
-
-
- 0 XOF
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Fonctionnalité en développement
-
Le système de réservations complet sera disponible prochainement.
-
-
-
-
-
-
+
+
+
+
+ Réservations d'Événements - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Réservations
+
+
+
+
+
+ Nom du membre
+
+ email@example.com
+
+
+
+
+ #{evenement.titre}
+
+
+
+ À définir
+
+
+
+ 1
+
+
+
+ 0 XOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fonctionnalité en développement
+
Le système de réservations complet sera disponible prochainement.
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/finance/bilans.xhtml b/src/main/resources/META-INF/resources/pages/secure/finance/bilans.xhtml
index c79fa32..1acc906 100644
--- a/src/main/resources/META-INF/resources/pages/secure/finance/bilans.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/finance/bilans.xhtml
@@ -1,44 +1,44 @@
-
-
-
- Bilans Financiers - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
Fonctionnalité en développement
-
- Les bilans financiers seront bientôt disponibles.
- Cette fonctionnalité permettra de générer et consulter les bilans comptables et financiers.
-
-
-
-
-
-
-
-
+
+
+
+ Bilans Financiers - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
Fonctionnalité en développement
+
+ Les bilans financiers seront bientôt disponibles.
+ Cette fonctionnalité permettra de générer et consulter les bilans comptables et financiers.
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/finance/budgets.xhtml b/src/main/resources/META-INF/resources/pages/secure/finance/budgets.xhtml
index 690dd47..e944b21 100644
--- a/src/main/resources/META-INF/resources/pages/secure/finance/budgets.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/finance/budgets.xhtml
@@ -1,44 +1,44 @@
-
-
-
- Gestion des Budgets - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
Fonctionnalité en développement
-
- La gestion des budgets sera bientôt disponible.
- Cette fonctionnalité permettra de planifier, suivre et analyser les budgets des organisations.
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Budgets - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
Fonctionnalité en développement
+
+ La gestion des budgets sera bientôt disponible.
+ Cette fonctionnalité permettra de planifier, suivre et analyser les budgets des organisations.
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/finance/tresorerie.xhtml b/src/main/resources/META-INF/resources/pages/secure/finance/tresorerie.xhtml
index 340a4eb..25f2a50 100644
--- a/src/main/resources/META-INF/resources/pages/secure/finance/tresorerie.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/finance/tresorerie.xhtml
@@ -1,49 +1,49 @@
-
-
-
-
-
-
-
-
- Trésorerie - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
Fonctionnalité en développement
-
- La gestion de la trésorerie sera bientôt disponible.
- Cette fonctionnalité permettra de suivre les entrées et sorties de fonds en temps réel.
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ Trésorerie - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
Fonctionnalité en développement
+
+ La gestion de la trésorerie sera bientôt disponible.
+ Cette fonctionnalité permettra de suivre les entrées et sorties de fonds en temps réel.
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/cotisations.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/cotisations.xhtml
index b224cd5..1fa4969 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/cotisations.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/cotisations.xhtml
@@ -1,198 +1,198 @@
-
-
-
-
-
-
-
-
-
- Cotisations du Membre - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
- Cotisations du Membre
-
-
- Membre: #{membreCotisationBean.numeroMembre} •
- Statut: #{membreCotisationBean.statutCotisations}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Mes Cotisations
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotisation.libelle}
-
#{cotisation.periode}
-
-
-
-
-
-
-
-
-
-
#{cotisation.montant}
-
FCFA
-
-
-
-
-
-
-
-
-
-
#{cotisation.dateEcheance}
-
#{cotisation.statutEcheance}
-
-
-
-
-
-
-
- Non payée
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ Cotisations du Membre - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+ Cotisations du Membre
+
+
+ Membre: #{membreCotisationBean.numeroMembre} •
+ Statut: #{membreCotisationBean.statutCotisations}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mes Cotisations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotisation.libelle}
+
#{cotisation.periode}
+
+
+
+
+
+
+
+
+
+
#{cotisation.montant}
+
FCFA
+
+
+
+
+
+
+
+
+
+
#{cotisation.dateEcheance}
+
#{cotisation.statutEcheance}
+
+
+
+
+
+
+
+ Non payée
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/export.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/export.xhtml
index 92eba64..58d17e7 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/export.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/export.xhtml
@@ -1,310 +1,310 @@
-
-
-
-
- Export des Membres - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Configuration de l'export
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Sélectionnez au moins une catégorie de colonnes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Le fichier sera protégé par un mot de passe (généré automatiquement ou personnalisé ci-dessous)
-
-
-
-
-
-
-
-
Si vide, un mot de passe aléatoire sera généré et affiché après l'export
-
-
-
-
-
-
-
-
-
-
-
Nombre de membres à exporter :
-
#{membreExportBean.nombreMembresAExporter} membre(s) correspond(ent) aux critères sélectionnés
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Historique des exports
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Export des Membres - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Configuration de l'export
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Sélectionnez au moins une catégorie de colonnes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Le fichier sera protégé par un mot de passe (généré automatiquement ou personnalisé ci-dessous)
+
+
+
+
+
+
+
+
Si vide, un mot de passe aléatoire sera généré et affiché après l'export
+
+
+
+
+
+
+
+
+
+
+
Nombre de membres à exporter :
+
#{membreExportBean.nombreMembresAExporter} membre(s) correspond(ent) aux critères sélectionnés
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Historique des exports
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/import.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/import.xhtml
index 8f6a478..eb5c6dd 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/import.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/import.xhtml
@@ -1,243 +1,243 @@
-
-
-
-
- Import en Masse des Membres - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Instructions d'import
-
- Téléchargez le modèle Excel, remplissez-le avec les données des membres, puis importez-le ici.
-
-
-
-
Format du fichier :
-
- Format Excel (.xlsx) ou CSV (.csv)
- Maximum 1000 lignes par import
- Taille maximale : 10 MB
-
-
-
-
Colonnes requises :
-
- Nom, Prénom (obligatoires)
- Email, Téléphone (obligatoires)
- Date de naissance, Adresse
- Profession, Type membre
-
-
-
-
-
-
-
-
-
-
- Fichier à importer
-
-
-
-
-
-
-
Formats acceptés : .xlsx, .xls, .csv - Maximum 10 MB
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Si coché, les membres existants (même email) seront mis à jour
-
-
-
-
-
-
-
-
Continuer l'import même si certaines lignes contiennent des erreurs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Détails des erreurs :
-
-
-
- Ligne #{erreur.ligne}:
- #{erreur.message}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Import en Masse des Membres - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Instructions d'import
+
+ Téléchargez le modèle Excel, remplissez-le avec les données des membres, puis importez-le ici.
+
+
+
+
Format du fichier :
+
+ Format Excel (.xlsx) ou CSV (.csv)
+ Maximum 1000 lignes par import
+ Taille maximale : 10 MB
+
+
+
+
Colonnes requises :
+
+ Nom, Prénom (obligatoires)
+ Email, Téléphone (obligatoires)
+ Date de naissance, Adresse
+ Profession, Type membre
+
+
+
+
+
+
+
+
+
+
+ Fichier à importer
+
+
+
+
+
+
+
Formats acceptés : .xlsx, .xls, .csv - Maximum 10 MB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Si coché, les membres existants (même email) seront mis à jour
+
+
+
+
+
+
+
+
Continuer l'import même si certaines lignes contiennent des erreurs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Détails des erreurs :
+
+
+
+ Ligne #{erreur.ligne}:
+ #{erreur.message}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/inscription.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/inscription.xhtml
index bf079a4..5e1432a 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/inscription.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/inscription.xhtml
@@ -1,764 +1,764 @@
-
-
-
-
-
-
-
-
-
- Inscription Membre - UnionFlow
-
-
-
-
-
-
-
-
-
-
Numéro: #{membreInscriptionBean.numeroGenere}
-
Généré automatiquement
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Glisser pour positionner Molette pour zoomer
-
-
-
-
-
-
-
-
-
- Choisir une photo
-
-
-
- Supprimer
-
-
-
JPG, PNG ou GIF - Maximum 2MB
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fichiers ajoutés:
-
-
-
-
- #{document}
-
-
-
-
-
-
-
-
-
-
-
-
-
- Formats acceptés: PDF, DOC, DOCX, JPG, PNG - Maximum 5 fichiers de 5MB chacun
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Autorisations
-
-
-
-
-
-
-
-
-
Finaliser l'inscription
-
-
-
-
-
Vérifiez toutes les informations
-
Assurez-vous que tous les champs requis sont remplis correctement
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Toutes les données sont chiffrées et sécurisées selon les standards RGPD
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Traitement en cours...
-
Veuillez patienter pendant l'enregistrement
-
-
-
-
+
+
+
+
+
+
+
+
+
+ Inscription Membre - UnionFlow
+
+
+
+
+
+
+
+
+
+
Numéro: #{membreInscriptionBean.numeroGenere}
+
Généré automatiquement
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Glisser pour positionner Molette pour zoomer
+
+
+
+
+
+
+
+
+
+ Choisir une photo
+
+
+
+ Supprimer
+
+
+
JPG, PNG ou GIF - Maximum 2MB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Fichiers ajoutés:
+
+
+
+
+ #{document}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Formats acceptés: PDF, DOC, DOCX, JPG, PNG - Maximum 5 fichiers de 5MB chacun
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Autorisations
+
+
+
+
+
+
+
+
+
Finaliser l'inscription
+
+
+
+
+
Vérifiez toutes les informations
+
Assurez-vous que tous les champs requis sont remplis correctement
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Toutes les données sont chiffrées et sécurisées selon les standards RGPD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Traitement en cours...
+
Veuillez patienter pendant l'enregistrement
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml
index cf7a8ef..a8972ab 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml
@@ -1,292 +1,292 @@
-
-
-
- Gestion des Membres
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Suspendre ce membre ?
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion des Membres
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Suspendre ce membre ?
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/paiement-mes-cotisations.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/paiement-mes-cotisations.xhtml
index b79ff73..06499b7 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/paiement-mes-cotisations.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/paiement-mes-cotisations.xhtml
@@ -1,349 +1,349 @@
-
-
-
-
- Payer mes Cotisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mes Cotisations en Attente
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{cotis.libelle}
-
#{cotis.periodeFormatee}
-
-
-
-
-
-
#{cotis.montantDuFormatte}
-
FCFA
-
-
-
-
-
-
-
-
-
-
-
#{cotis.statutEcheance}
-
-
-
-
-
-
-
-
-
-
-
-
-
Félicitations !
-
Vous êtes à jour dans vos cotisations.
-
-
-
-
-
-
-
-
- Mes Derniers Paiements
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{paiement.montantFormatte}
-
FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cotisation
- #{mesCotisationsPaiementBean.cotisationSelectionnee.reference}
-
-
-
- Montant à payer
-
- #{mesCotisationsPaiementBean.cotisationSelectionnee.montantDuFormatte} FCFA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Vous allez être redirigé vers la plateforme de paiement sécurisée.
-
Aucun frais supplémentaire n'est appliqué sur votre paiement.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Si vous avez effectué un paiement par un autre moyen (espèces, virement direct, etc.), vous pouvez le déclarer ici.
-
Votre paiement devra être validé par le trésorier.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Payer mes Cotisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mes Cotisations en Attente
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{cotis.libelle}
+
#{cotis.periodeFormatee}
+
+
+
+
+
+
#{cotis.montantDuFormatte}
+
FCFA
+
+
+
+
+
+
+
+
+
+
+
#{cotis.statutEcheance}
+
+
+
+
+
+
+
+
+
+
+
+
+
Félicitations !
+
Vous êtes à jour dans vos cotisations.
+
+
+
+
+
+
+
+
+ Mes Derniers Paiements
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{paiement.montantFormatte}
+
FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cotisation
+ #{mesCotisationsPaiementBean.cotisationSelectionnee.reference}
+
+
+
+ Montant à payer
+
+ #{mesCotisationsPaiementBean.cotisationSelectionnee.montantDuFormatte} FCFA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Vous allez être redirigé vers la plateforme de paiement sécurisée.
+
Aucun frais supplémentaire n'est appliqué sur votre paiement.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Si vous avez effectué un paiement par un autre moyen (espèces, virement direct, etc.), vous pouvez le déclarer ici.
+
Votre paiement devra être validé par le trésorier.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml
index 6bec3c8..3eb39f2 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml
@@ -1,719 +1,719 @@
-
-
-
- Profil de #{membreProfilBean.membre.nomComplet} - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membreProfilBean.membre.nomComplet}
-
-
-
-
-
-
-
-
-
-
-
-
- Cotisations:
- #{membreProfilBean.membre.cotisationStatut}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Informations de base
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Coordonnées
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Famille
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
État des cotisations
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Historique des paiements
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{paiement.modePaiement}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Événements récents
-
-
-
-
-
-
-
#{evenement.titre}
-
- #{evenement.date} • #{evenement.lieu}
-
-
-
-
-
- #{evenement.role}
-
-
-
-
-
-
-
-
Statistiques participation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Aides reçues
-
-
-
-
- #{aide.type}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Demandes en cours
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Activité récente
-
-
-
-
-
-
-
- #{activite.description}
- #{activite.date}
-
-
- Par #{activite.auteur}
-
-
- #{activite.details}
-
-
-
-
-
-
-
-
-
-
-
-
Aucune activité récente
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Profil de #{membreProfilBean.membre.nomComplet} - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membreProfilBean.membre.nomComplet}
+
+
+
+
+
+
+
+
+
+
+
+
+ Cotisations:
+ #{membreProfilBean.membre.cotisationStatut}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Informations de base
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Coordonnées
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Famille
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
État des cotisations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Historique des paiements
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{paiement.modePaiement}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Événements récents
+
+
+
+
+
+
+
#{evenement.titre}
+
+ #{evenement.date} • #{evenement.lieu}
+
+
+
+
+
+ #{evenement.role}
+
+
+
+
+
+
+
+
Statistiques participation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Aides reçues
+
+
+
+
+ #{aide.type}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Demandes en cours
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Activité récente
+
+
+
+
+
+
+
+ #{activite.description}
+ #{activite.date}
+
+
+ Par #{activite.auteur}
+
+
+ #{activite.details}
+
+
+
+
+
+
+
+
+
+
+
+
Aucune activité récente
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/recherche.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/recherche.xhtml
index 06f42d2..665aeb2 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/recherche.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/recherche.xhtml
@@ -1,713 +1,713 @@
-
-
-
- Recherche Avancée des Membres - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Critères de Recherche
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Résultats de recherche
-
-
- #{membreRechercheBean.resultats.size()} membre(s) trouvé(s)
- sur #{membreRechercheBean.statistiques.totalMembres} total
-
- • #{membreRechercheBean.statistiques.filtresActifs} filtre(s) actif(s)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Liste des membres
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{membre.initiales}
-
-
-
-
#{membre.nomComplet}
-
- #{membre.telephone}
- •
- #{membre.email}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{membre.dateAdhesion}
-
#{membre.anciennete}
-
-
-
-
-
-
#{membre.cotisationStatut}
-
#{membre.dernierPaiement}
-
-
-
-
-
-
#{membre.tauxParticipation}%
-
#{membre.evenementsAnnee} événements
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{membreRechercheBean.selectedMembres.size()} membre(s) sélectionné(s)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Critères à sauvegarder :
-
#{membreRechercheBean.statistiques.filtresActifs} filtre(s) actif(s) seront sauvegardés
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{recherche.nom}
-
#{recherche.description}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Destinataires :
-
#{membreRechercheBean.selectedMembres.size()} membre(s) recevront ce message
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Recherche Avancée des Membres - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Critères de Recherche
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Résultats de recherche
+
+
+ #{membreRechercheBean.resultats.size()} membre(s) trouvé(s)
+ sur #{membreRechercheBean.statistiques.totalMembres} total
+
+ • #{membreRechercheBean.statistiques.filtresActifs} filtre(s) actif(s)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Liste des membres
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{membre.initiales}
+
+
+
+
#{membre.nomComplet}
+
+ #{membre.telephone}
+ •
+ #{membre.email}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{membre.dateAdhesion}
+
#{membre.anciennete}
+
+
+
+
+
+
#{membre.cotisationStatut}
+
#{membre.dernierPaiement}
+
+
+
+
+
+
#{membre.tauxParticipation}%
+
#{membre.evenementsAnnee} événements
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{membreRechercheBean.selectedMembres.size()} membre(s) sélectionné(s)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Critères à sauvegarder :
+
#{membreRechercheBean.statistiques.filtresActifs} filtre(s) actif(s) seront sauvegardés
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{recherche.nom}
+
#{recherche.description}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Destinataires :
+
#{membreRechercheBean.selectedMembres.size()} membre(s) recevront ce message
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/membre/validation.xhtml b/src/main/resources/META-INF/resources/pages/secure/membre/validation.xhtml
index 033b257..cb0262d 100644
--- a/src/main/resources/META-INF/resources/pages/secure/membre/validation.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/membre/validation.xhtml
@@ -1,34 +1,34 @@
-
-
-
- Validation des Inscriptions - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Inscriptions en attente
-
- Les demandes d'inscription à valider apparaîtront ici. Utilisez la liste des membres ou le formulaire d'inscription pour gérer les nouveaux membres.
-
-
-
-
-
-
-
+
+
+
+ Validation des Inscriptions - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Inscriptions en attente
+
+ Les demandes d'inscription à valider apparaîtront ici. Utilisez la liste des membres ou le formulaire d'inscription pour gérer les nouveaux membres.
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/organisation/detail.xhtml b/src/main/resources/META-INF/resources/pages/secure/organisation/detail.xhtml
index 57dc5ba..5f69fd9 100644
--- a/src/main/resources/META-INF/resources/pages/secure/organisation/detail.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/organisation/detail.xhtml
@@ -1,742 +1,742 @@
-
-
-
-
- #{empty organisationDetailBean.organisation ? 'Organisation introuvable' : organisationDetailBean.organisation.nom}
-
-
-
-
-
-
-
-
-
-
-
-
-
Organisation introuvable
-
- L'organisation demandée n'existe pas ou n'est pas accessible.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Identification
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Identité
-
Informations d'identification officielle
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Contacts
-
Coordonnées de l'organisation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Géographie & Mission
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Localisation
-
Adresse et situation géographique
-
-
-
-
-
-
-
-
-
-
-
-
-
Localisation administrative
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Mission & Activités
-
Raison d'être et domaines d'action
-
-
-
-
-
-
-
-
-
-
-
-
-
Objectifs & activités
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Organisation interne
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Gouvernance & Membres
-
Structure et politique d'adhésion
-
-
-
-
-
-
-
-
-
-
-
-
-
- Administrateurs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Finance & Cotisations
-
Budget et politique financière
-
-
-
-
-
-
-
-
- Budget annuel
-
-
-
-
-
-
-
-
-
-
-
-
- Budget annuel
-
-
Non renseigné
-
-
-
-
-
-
Cotisations membres
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Réseau & Administratif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Partenariats & Réseaux
-
Présence en ligne et alliances
-
-
-
-
-
-
-
-
-
-
-
-
-
Partenaires & certifications
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Hiérarchie & Notes
-
Rattachement et observations internes
-
-
-
-
-
-
-
-
-
- Rattachée à
-
-
-
-
-
-
-
-
-
-
-
-
- Organisation parente
-
-
Aucune (organisation racine)
-
-
-
-
-
-
Notes administratives
-
-
-
-
-
-
-
-
-
- Aucune note
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Modifier l'organisation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ #{empty organisationDetailBean.organisation ? 'Organisation introuvable' : organisationDetailBean.organisation.nom}
+
+
+
+
+
+
+
+
+
+
+
+
+
Organisation introuvable
+
+ L'organisation demandée n'existe pas ou n'est pas accessible.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Identification
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Identité
+
Informations d'identification officielle
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Contacts
+
Coordonnées de l'organisation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Géographie & Mission
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Localisation
+
Adresse et situation géographique
+
+
+
+
+
+
+
+
+
+
+
+
+
Localisation administrative
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mission & Activités
+
Raison d'être et domaines d'action
+
+
+
+
+
+
+
+
+
+
+
+
+
Objectifs & activités
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Organisation interne
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Gouvernance & Membres
+
Structure et politique d'adhésion
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Administrateurs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Finance & Cotisations
+
Budget et politique financière
+
+
+
+
+
+
+
+
+ Budget annuel
+
+
+
+
+
+
+
+
+
+
+
+
+ Budget annuel
+
+
Non renseigné
+
+
+
+
+
+
Cotisations membres
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Réseau & Administratif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Partenariats & Réseaux
+
Présence en ligne et alliances
+
+
+
+
+
+
+
+
+
+
+
+
+
Partenaires & certifications
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Hiérarchie & Notes
+
Rattachement et observations internes
+
+
+
+
+
+
+
+
+
+ Rattachée à
+
+
+
+
+
+
+
+
+
+
+
+
+ Organisation parente
+
+
Aucune (organisation racine)
+
+
+
+
+
+
Notes administratives
+
+
+
+
+
+
+
+
+
+ Aucune note
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Modifier l'organisation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/organisation/liste.xhtml b/src/main/resources/META-INF/resources/pages/secure/organisation/liste.xhtml
index 22d9a2d..ba186de 100644
--- a/src/main/resources/META-INF/resources/pages/secure/organisation/liste.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/organisation/liste.xhtml
@@ -1,323 +1,323 @@
-
-
-
- Organisations - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Filtres et Recherche
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Liste des Organisations
-
-
-
-
-
-
-
-
-
-
-
-
-
#{org.nom}
-
- #{empty org.nomCourt ? '' : org.nomCourt}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{empty org.nombreMembres ? 0 : org.nombreMembres}
-
-
membres
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Changer le statut de cette organisation ?
-
-
-
-
-
-
- Supprimer définitivement cette organisation ? Cette action est irréversible.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Organisations - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Filtres et Recherche
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Liste des Organisations
+
+
+
+
+
+
+
+
+
+
+
+
+
#{org.nom}
+
+ #{empty org.nomCourt ? '' : org.nomCourt}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{empty org.nombreMembres ? 0 : org.nombreMembres}
+
+
membres
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Changer le statut de cette organisation ?
+
+
+
+
+
+
+ Supprimer définitivement cette organisation ? Cette action est irréversible.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/organisation/statistiques.xhtml b/src/main/resources/META-INF/resources/pages/secure/organisation/statistiques.xhtml
index b31381c..5277c6b 100644
--- a/src/main/resources/META-INF/resources/pages/secure/organisation/statistiques.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/organisation/statistiques.xhtml
@@ -1,115 +1,115 @@
-
-
-
- Statistiques des Organisations
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Graphique de répartition par type d'organisation
-
- (À implémenter avec PrimeFaces Charts)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Graphique d'évolution des inscriptions
-
- (À implémenter avec PrimeFaces Charts)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Carte de répartition géographique des organisations
-
- (À implémenter avec cartes interactives)
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Statistiques des Organisations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Graphique de répartition par type d'organisation
+
+ (À implémenter avec PrimeFaces Charts)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Graphique d'évolution des inscriptions
+
+ (À implémenter avec PrimeFaces Charts)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Carte de répartition géographique des organisations
+
+ (À implémenter avec cartes interactives)
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/outils/exports-masse.xhtml b/src/main/resources/META-INF/resources/pages/secure/outils/exports-masse.xhtml
index f613c0d..80c51ae 100644
--- a/src/main/resources/META-INF/resources/pages/secure/outils/exports-masse.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/outils/exports-masse.xhtml
@@ -1,126 +1,126 @@
-
-
-
- Exports en Masse - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Exports en Masse - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/personnel/activites.xhtml b/src/main/resources/META-INF/resources/pages/secure/personnel/activites.xhtml
index 247aa0e..917a892 100644
--- a/src/main/resources/META-INF/resources/pages/secure/personnel/activites.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/personnel/activites.xhtml
@@ -1,100 +1,100 @@
-
-
-
-
- Mes Activités - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Activités Récentes
-
-
-
-
-
-
-
-
-
-
#{activite.titre}
-
#{activite.description}
-
-
-
-
#{activite.dateHeure}
-
-
-
-
-
-
- Aucune activité récente
-
-
-
-
-
+
+
+
+
+ Mes Activités - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Activités Récentes
+
+
+
+
+
+
+
+
+
+
#{activite.titre}
+
#{activite.description}
+
+
+
+
#{activite.dateHeure}
+
+
+
+
+
+
+ Aucune activité récente
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/personnel/agenda.xhtml b/src/main/resources/META-INF/resources/pages/secure/personnel/agenda.xhtml
index db4e112..d26d238 100644
--- a/src/main/resources/META-INF/resources/pages/secure/personnel/agenda.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/personnel/agenda.xhtml
@@ -1,87 +1,87 @@
-
-
-
-
- Mon Agenda - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Calendrier Mensuel
-
-
-
-
-
-
-
-
+
+
+
+
+ Mon Agenda - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Calendrier Mensuel
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/personnel/documents.xhtml b/src/main/resources/META-INF/resources/pages/secure/personnel/documents.xhtml
index e4a180d..ea40550 100644
--- a/src/main/resources/META-INF/resources/pages/secure/personnel/documents.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/personnel/documents.xhtml
@@ -1,146 +1,146 @@
-
-
-
-
- Mes Documents - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Mes Documents
-
-
-
-
-
-
- #{document.nom}
-
-
-
-
- #{document.type}
-
-
-
- #{document.dateCreation}
-
-
-
- #{document.taille} bytes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Mes Documents - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mes Documents
+
+
+
+
+
+
+ #{document.nom}
+
+
+
+
+ #{document.type}
+
+
+
+ #{document.dateCreation}
+
+
+
+ #{document.taille} bytes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/personnel/favoris.xhtml b/src/main/resources/META-INF/resources/pages/secure/personnel/favoris.xhtml
index 0ac594a..5129101 100644
--- a/src/main/resources/META-INF/resources/pages/secure/personnel/favoris.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/personnel/favoris.xhtml
@@ -1,374 +1,374 @@
-
-
-
-
- Mes Favoris - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Mes Favoris
-
-
- Accédez rapidement à vos pages, documents et fonctionnalités préférés
-
-
-
-
-
-
-
-
-
-
#{favorisBean.totalFavoris}
-
Favoris
-
Total
-
-
-
-
-
#{favorisBean.totalPages}
-
Pages
-
Fonctionnalités
-
-
-
-
-
#{favorisBean.totalDocuments}
-
Documents
-
Fichiers
-
-
-
-
-
#{favorisBean.totalContacts}
-
Contacts
-
Personnes
-
-
-
-
-
-
-
-
-
-
-
-
-
- Accès Rapide
-
-
-
-
-
-
-
-
#{page.titre}
-
#{page.description}
-
-
- #{page.derniereVisite}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Mon Agenda
-
Planning et événements personnels
-
-
- Utilisé il y a 2h
-
-
-
-
-
-
-
-
-
-
-
-
Liste des Membres
-
Annuaire et contacts membres
-
-
- Utilisé hier
-
-
-
-
-
-
-
-
-
-
-
-
Cotisations
-
Paiements et historique
-
-
- Utilisé il y a 3 jours
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Pages Favorites
-
-
-
-
-
-
-
-
-
-
#{page.titre}
-
-
-
-
#{page.description}
-
-
-
#{page.nbVisites} visite#{page.nbVisites > 1 ? 's' : ''} cette semaine
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Documents Favoris
-
-
-
-
-
-
-
-
-
-
-
#{doc.nom}
-
-
#{doc.tailleFormatee}
-
Ajouté aux favoris le #{doc.dateAjout}
-
-
-
#{doc.description}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Contacts Favoris
-
-
-
-
-
-
-
-
-
-
-
-
-
#{contact.nom}
-
#{contact.fonction}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Raccourcis Personnalisés
-
-
-
-
-
-
-
-
#{racc.titre}
-
#{racc.description}
-
-
-
-
-
-
-
-
-
-
Ajouter
-
Créer un nouveau raccourci
-
-
-
-
-
-
-
-
- Conseils d'utilisation
-
-
-
-
- Cliquez sur l'étoile ⭐ à côté des éléments pour les ajouter aux favoris
-
-
-
- Organisez vos favoris par catégorie pour un accès plus rapide
-
-
-
- Créez des raccourcis personnalisés vers vos actions les plus fréquentes
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Mes Favoris - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Mes Favoris
+
+
+ Accédez rapidement à vos pages, documents et fonctionnalités préférés
+
+
+
+
+
+
+
+
+
+
#{favorisBean.totalFavoris}
+
Favoris
+
Total
+
+
+
+
+
#{favorisBean.totalPages}
+
Pages
+
Fonctionnalités
+
+
+
+
+
#{favorisBean.totalDocuments}
+
Documents
+
Fichiers
+
+
+
+
+
#{favorisBean.totalContacts}
+
Contacts
+
Personnes
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Accès Rapide
+
+
+
+
+
+
+
+
#{page.titre}
+
#{page.description}
+
+
+ #{page.derniereVisite}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mon Agenda
+
Planning et événements personnels
+
+
+ Utilisé il y a 2h
+
+
+
+
+
+
+
+
+
+
+
+
Liste des Membres
+
Annuaire et contacts membres
+
+
+ Utilisé hier
+
+
+
+
+
+
+
+
+
+
+
+
Cotisations
+
Paiements et historique
+
+
+ Utilisé il y a 3 jours
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pages Favorites
+
+
+
+
+
+
+
+
+
+
#{page.titre}
+
+
+
+
#{page.description}
+
+
+
#{page.nbVisites} visite#{page.nbVisites > 1 ? 's' : ''} cette semaine
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Documents Favoris
+
+
+
+
+
+
+
+
+
+
+
#{doc.nom}
+
+
#{doc.tailleFormatee}
+
Ajouté aux favoris le #{doc.dateAjout}
+
+
+
#{doc.description}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contacts Favoris
+
+
+
+
+
+
+
+
+
+
+
+
+
#{contact.nom}
+
#{contact.fonction}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Raccourcis Personnalisés
+
+
+
+
+
+
+
+
#{racc.titre}
+
#{racc.description}
+
+
+
+
+
+
+
+
+
+
Ajouter
+
Créer un nouveau raccourci
+
+
+
+
+
+
+
+
+ Conseils d'utilisation
+
+
+
+
+ Cliquez sur l'étoile ⭐ à côté des éléments pour les ajouter aux favoris
+
+
+
+ Organisez vos favoris par catégorie pour un accès plus rapide
+
+
+
+ Créez des raccourcis personnalisés vers vos actions les plus fréquentes
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/personnel/notifications.xhtml b/src/main/resources/META-INF/resources/pages/secure/personnel/notifications.xhtml
index c24d29c..a0206d6 100644
--- a/src/main/resources/META-INF/resources/pages/secure/personnel/notifications.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/personnel/notifications.xhtml
@@ -1,99 +1,99 @@
-
-
-
-
- Mes Notifications - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Notifications Récentes
-
-
-
-
-
-
-
#{notification.titre}
-
-
-
-
- #{notification.message}
-
-
-
- #{notification.dateCreation}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Mes Notifications - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Notifications Récentes
+
+
+
+
+
+
+
#{notification.titre}
+
+
+
+
+ #{notification.message}
+
+
+
+ #{notification.dateCreation}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/personnel/parametres.xhtml b/src/main/resources/META-INF/resources/pages/secure/personnel/parametres.xhtml
index 64bf553..b12dc61 100644
--- a/src/main/resources/META-INF/resources/pages/secure/personnel/parametres.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/personnel/parametres.xhtml
@@ -1,704 +1,704 @@
-
-
-
-
- Paramètres Compte - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Paramètres de Compte
-
-
- Gérez la sécurité, la confidentialité et les paramètres avancés de votre compte
-
-
-
-
-
-
-
-
-
-
-
Compte sécurisé
-
- Votre compte respecte toutes les bonnes pratiques de sécurité. Score: #{parametresBean.scoreSecurite}/100
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mot de Passe
-
-
-
-
-
Mot de passe actuel *
-
-
-
-
-
Nouveau mot de passe *
-
-
-
-
-
Confirmer le mot de passe *
-
-
-
-
-
Critères de sécurité
-
-
-
- Au moins 8 caractères
-
-
-
- Une majuscule
-
-
-
- Un chiffre
-
-
-
- Un caractère spécial
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Authentification à Deux Facteurs (2FA)
-
-
-
-
-
-
2FA Activée
-
Votre compte est protégé par l'authentification à deux facteurs
-
-
-
-
-
-
-
Méthode configurée
-
-
-
-
-
Application Authenticator
-
Google Authenticator, Authy, etc.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sessions Actives
-
-
-
-
-
-
-
-
-
Session Actuelle
-
Chrome 120.0 sur Windows 11
-
IP: 192.168.1.45 • Dakar, Sénégal
-
-
-
-
-
-
-
-
-
-
-
-
-
iPhone 14
-
Safari Mobile
-
IP: 41.82.45.123 • Dernière activité: il y a 3h
-
-
-
-
-
-
-
-
-
-
-
-
iPad Pro
-
Safari
-
IP: 197.25.78.156 • Dernière activité: il y a 1 jour
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Visibilité du Profil
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Partage des Données
-
-
-
-
-
- Adresse email
- Permettre aux autres membres de voir votre email
-
-
-
-
-
-
- Numéro de téléphone
- Afficher votre numéro dans l'annuaire
-
-
-
-
-
-
- Activités publiques
- Participation aux événements et formations
-
-
-
-
-
-
- Statistiques anonymes
- Contribuer aux statistiques générales
-
-
-
-
-
- Information
-
-
- Ces paramètres n'affectent pas les données nécessaires au fonctionnement de l'association.
-
-
-
-
-
-
-
-
-
-
- Gestion des Données Personnelles
-
-
-
-
-
-
-
Exporter mes données
-
- Téléchargez toutes vos données personnelles au format JSON
-
-
-
-
-
-
-
-
-
Actualiser le consentement
-
- Revoir et mettre à jour vos consentements RGPD
-
-
-
-
-
-
-
-
-
Supprimer mon compte
-
- Suppression définitive de toutes vos données
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Communications
-
-
-
-
-
Newsletter hebdomadaire
-
-
-
-
-
Notifications d'événements
-
-
-
-
-
Rappels de cotisations
-
-
-
-
-
Offres promotionnelles
-
-
-
-
-
SMS pour urgences uniquement
-
-
-
-
-
-
-
-
-
- Affichage
-
-
-
-
-
-
-
-
Fuseau horaire
-
-
-
-
-
-
-
-
-
-
Activer les animations
-
-
-
-
-
-
-
-
-
- Sauvegarde et Synchronisation
-
-
-
-
-
-
-
Sauvegarde automatique
-
-
-
- Sauvegarde quotidienne de vos préférences et données
-
-
Dernière sauvegarde: il y a 2h
-
-
-
-
-
-
-
- Synchronisation avec Google Calendar et Outlook
-
-
2 calendriers connectés
-
-
-
-
-
-
-
- Accès limité aux fonctionnalités sans connexion
-
-
Cache: 25 MB
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- API et Intégrations
-
-
-
-
-
Clé API personnelle
-
-
-
Utilisée pour les intégrations tierces
-
- uk_1a2b3c4d5e6f7g8h9i0j...
-
-
-
-
-
-
-
- Sécurité
-
-
- Ne partagez jamais votre clé API. Changez-la si elle est compromise.
-
-
-
-
-
-
-
-
-
-
- Logs d'Activité
-
-
-
-
Niveau de logging
-
-
-
-
-
-
-
-
-
Durée de conservation
-
-
-
-
-
-
-
-
-
-
Permettre le téléchargement des logs
-
-
-
-
-
-
-
-
-
-
-
- Zone Dangereuse
-
-
-
-
-
-
Réinitialiser les préférences
-
- Remet tous vos paramètres aux valeurs par défaut
-
-
-
-
-
-
-
-
Désactiver le compte
-
- Suspend temporairement votre accès
-
-
-
-
-
-
-
-
Supprimer le compte
-
- Action irréversible. Toutes vos données seront perdues
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Sauvegarder toutes les modifications
-
- Les changements seront appliqués immédiatement à votre compte
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Paramètres Compte - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Paramètres de Compte
+
+
+ Gérez la sécurité, la confidentialité et les paramètres avancés de votre compte
+
+
+
+
+
+
+
+
+
+
+
Compte sécurisé
+
+ Votre compte respecte toutes les bonnes pratiques de sécurité. Score: #{parametresBean.scoreSecurite}/100
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mot de Passe
+
+
+
+
+
Mot de passe actuel *
+
+
+
+
+
Nouveau mot de passe *
+
+
+
+
+
Confirmer le mot de passe *
+
+
+
+
+
Critères de sécurité
+
+
+
+ Au moins 8 caractères
+
+
+
+ Une majuscule
+
+
+
+ Un chiffre
+
+
+
+ Un caractère spécial
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Authentification à Deux Facteurs (2FA)
+
+
+
+
+
+
2FA Activée
+
Votre compte est protégé par l'authentification à deux facteurs
+
+
+
+
+
+
+
Méthode configurée
+
+
+
+
+
Application Authenticator
+
Google Authenticator, Authy, etc.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sessions Actives
+
+
+
+
+
+
+
+
+
Session Actuelle
+
Chrome 120.0 sur Windows 11
+
IP: 192.168.1.45 • Dakar, Sénégal
+
+
+
+
+
+
+
+
+
+
+
+
+
iPhone 14
+
Safari Mobile
+
IP: 41.82.45.123 • Dernière activité: il y a 3h
+
+
+
+
+
+
+
+
+
+
+
+
iPad Pro
+
Safari
+
IP: 197.25.78.156 • Dernière activité: il y a 1 jour
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Visibilité du Profil
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Partage des Données
+
+
+
+
+
+ Adresse email
+ Permettre aux autres membres de voir votre email
+
+
+
+
+
+
+ Numéro de téléphone
+ Afficher votre numéro dans l'annuaire
+
+
+
+
+
+
+ Activités publiques
+ Participation aux événements et formations
+
+
+
+
+
+
+ Statistiques anonymes
+ Contribuer aux statistiques générales
+
+
+
+
+
+ Information
+
+
+ Ces paramètres n'affectent pas les données nécessaires au fonctionnement de l'association.
+
+
+
+
+
+
+
+
+
+
+ Gestion des Données Personnelles
+
+
+
+
+
+
+
Exporter mes données
+
+ Téléchargez toutes vos données personnelles au format JSON
+
+
+
+
+
+
+
+
+
Actualiser le consentement
+
+ Revoir et mettre à jour vos consentements RGPD
+
+
+
+
+
+
+
+
+
Supprimer mon compte
+
+ Suppression définitive de toutes vos données
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Communications
+
+
+
+
+
Newsletter hebdomadaire
+
+
+
+
+
Notifications d'événements
+
+
+
+
+
Rappels de cotisations
+
+
+
+
+
Offres promotionnelles
+
+
+
+
+
SMS pour urgences uniquement
+
+
+
+
+
+
+
+
+
+ Affichage
+
+
+
+
+
+
+
+
Fuseau horaire
+
+
+
+
+
+
+
+
+
+
Activer les animations
+
+
+
+
+
+
+
+
+
+ Sauvegarde et Synchronisation
+
+
+
+
+
+
+
Sauvegarde automatique
+
+
+
+ Sauvegarde quotidienne de vos préférences et données
+
+
Dernière sauvegarde: il y a 2h
+
+
+
+
+
+
+
+ Synchronisation avec Google Calendar et Outlook
+
+
2 calendriers connectés
+
+
+
+
+
+
+
+ Accès limité aux fonctionnalités sans connexion
+
+
Cache: 25 MB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ API et Intégrations
+
+
+
+
+
Clé API personnelle
+
+
+
Utilisée pour les intégrations tierces
+
+ uk_1a2b3c4d5e6f7g8h9i0j...
+
+
+
+
+
+
+
+ Sécurité
+
+
+ Ne partagez jamais votre clé API. Changez-la si elle est compromise.
+
+
+
+
+
+
+
+
+
+
+ Logs d'Activité
+
+
+
+
Niveau de logging
+
+
+
+
+
+
+
+
+
Durée de conservation
+
+
+
+
+
+
+
+
+
+
Permettre le téléchargement des logs
+
+
+
+
+
+
+
+
+
+
+
+ Zone Dangereuse
+
+
+
+
+
+
Réinitialiser les préférences
+
+ Remet tous vos paramètres aux valeurs par défaut
+
+
+
+
+
+
+
+
Désactiver le compte
+
+ Suspend temporairement votre accès
+
+
+
+
+
+
+
+
Supprimer le compte
+
+ Action irréversible. Toutes vos données seront perdues
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Sauvegarder toutes les modifications
+
+ Les changements seront appliqués immédiatement à votre compte
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/personnel/preferences.xhtml b/src/main/resources/META-INF/resources/pages/secure/personnel/preferences.xhtml
index 12c23b4..838b373 100644
--- a/src/main/resources/META-INF/resources/pages/secure/personnel/preferences.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/personnel/preferences.xhtml
@@ -1,510 +1,510 @@
-
-
-
-
- Mes Préférences - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Mes Préférences
-
-
- Personnalisez votre expérience UnionFlow selon vos besoins
-
-
-
-
-
-
-
-
-
-
-
Apparence
-
Thème, couleurs, mise en page
-
-
-
-
-
-
Notifications
-
Alertes, emails, SMS
-
-
-
-
-
-
Confidentialité
-
Sécurité, permissions
-
-
-
-
-
-
-
-
-
-
-
-
-
- Apparence et Interface
-
-
-
-
-
-
-
-
-
Couleur d'accent
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Fuseau horaire
-
-
-
-
-
-
-
-
-
-
-
Format de date
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Notifications et Alertes
-
-
-
-
-
-
-
- Notifications navigateur
-
-
-
-
-
Nouveaux événements
-
-
-
-
-
-
-
Rappels cotisations
-
-
-
-
-
Mises à jour système
-
-
-
-
-
-
-
- Notifications email
-
-
-
-
-
-
-
Newsletter hebdomadaire
-
-
-
-
-
-
-
Offres promotionnelles
-
-
-
-
-
-
-
- Notifications SMS
-
-
-
-
-
Urgences uniquement
-
-
-
-
-
-
-
-
Heures autorisées
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Confidentialité et Sécurité
-
-
-
-
-
-
-
Visibilité du profil
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Paramètres de sécurité
-
-
-
-
Authentification à deux facteurs
-
-
-
-
-
Connexion HTTPS obligatoire
-
-
-
-
-
Déconnexion automatique
-
-
-
-
Durée max session
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tableau de Bord Personnel
-
-
-
-
-
-
-
Widgets à afficher
-
-
-
-
-
-
-
-
État des cotisations
-
-
-
-
-
Notifications récentes
-
-
-
-
-
-
-
-
-
-
-
Configuration d'affichage
-
-
-
Disposition
-
-
-
-
-
-
-
-
-
-
Page d'accueil
-
-
-
-
-
-
-
-
-
-
Éléments par page
-
-
-
-
-
-
-
-
-
-
-
Activer les animations
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Enregistrer les modifications
-
Vos préférences seront appliquées immédiatement
-
-
-
-
-
-
-
- Certaines modifications nécessiteront une reconnexion pour être appliquées.
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Mes Préférences - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Mes Préférences
+
+
+ Personnalisez votre expérience UnionFlow selon vos besoins
+
+
+
+
+
+
+
+
+
+
+
Apparence
+
Thème, couleurs, mise en page
+
+
+
+
+
+
Notifications
+
Alertes, emails, SMS
+
+
+
+
+
+
Confidentialité
+
Sécurité, permissions
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Apparence et Interface
+
+
+
+
+
+
+
+
+
Couleur d'accent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fuseau horaire
+
+
+
+
+
+
+
+
+
+
+
Format de date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Notifications et Alertes
+
+
+
+
+
+
+
+ Notifications navigateur
+
+
+
+
+
Nouveaux événements
+
+
+
+
+
+
+
Rappels cotisations
+
+
+
+
+
Mises à jour système
+
+
+
+
+
+
+
+ Notifications email
+
+
+
+
+
+
+
Newsletter hebdomadaire
+
+
+
+
+
+
+
Offres promotionnelles
+
+
+
+
+
+
+
+ Notifications SMS
+
+
+
+
+
Urgences uniquement
+
+
+
+
+
+
+
+
Heures autorisées
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Confidentialité et Sécurité
+
+
+
+
+
+
+
Visibilité du profil
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Paramètres de sécurité
+
+
+
+
Authentification à deux facteurs
+
+
+
+
+
Connexion HTTPS obligatoire
+
+
+
+
+
Déconnexion automatique
+
+
+
+
Durée max session
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tableau de Bord Personnel
+
+
+
+
+
+
+
Widgets à afficher
+
+
+
+
+
+
+
+
État des cotisations
+
+
+
+
+
Notifications récentes
+
+
+
+
+
+
+
+
+
+
+
Configuration d'affichage
+
+
+
Disposition
+
+
+
+
+
+
+
+
+
+
Page d'accueil
+
+
+
+
+
+
+
+
+
+
Éléments par page
+
+
+
+
+
+
+
+
+
+
+
Activer les animations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Enregistrer les modifications
+
Vos préférences seront appliquées immédiatement
+
+
+
+
+
+
+
+ Certaines modifications nécessiteront une reconnexion pour être appliquées.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/personnel/profil.xhtml b/src/main/resources/META-INF/resources/pages/secure/personnel/profil.xhtml
index 11b6b16..c31c48c 100644
--- a/src/main/resources/META-INF/resources/pages/secure/personnel/profil.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/personnel/profil.xhtml
@@ -1,301 +1,301 @@
-
-
-
-
- Mon Profil - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{personnelBean.membre != null ? personnelBean.membre.nomComplet : 'Chargement...'}
-
-
- Membre depuis le #{personnelBean.membre.dateAdhesionFormatee}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Informations Personnelles
-
-
-
-
-
-
Nom complet
-
#{personnelBean.membre.nomComplet}
-
-
-
-
-
Email
-
#{personnelBean.membre.email}
-
-
-
-
-
Téléphone
-
#{personnelBean.membre.telephone}
-
-
-
-
-
Date de naissance
-
#{personnelBean.membre.dateNaissanceFormatee}
-
-
-
-
-
Adresse
-
#{personnelBean.membre.adresse}
-
-
-
-
-
Profession
-
#{personnelBean.membre.profession}
-
-
-
-
-
-
-
-
-
-
- Adhésion et Statut
-
-
-
-
Numéro de membre
-
#{personnelBean.membre.numeroMembre}
-
-
-
-
Type d'adhésion
-
#{personnelBean.membre.typeMembre}
-
-
-
-
Date d'inscription
-
#{personnelBean.membre.dateAdhesionFormatee}
-
-
-
-
-
-
-
-
-
-
-
- Activités Récentes
-
-
-
-
-
- #{activite.titre}
- #{activite.dateHeure}
-
-
#{activite.description}
-
-
-
-
- Aucune activité récente
-
-
-
-
-
-
-
-
- Rôles et Permissions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Mon Profil - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{personnelBean.membre != null ? personnelBean.membre.nomComplet : 'Chargement...'}
+
+
+ Membre depuis le #{personnelBean.membre.dateAdhesionFormatee}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Informations Personnelles
+
+
+
+
+
+
Nom complet
+
#{personnelBean.membre.nomComplet}
+
+
+
+
+
Email
+
#{personnelBean.membre.email}
+
+
+
+
+
Téléphone
+
#{personnelBean.membre.telephone}
+
+
+
+
+
Date de naissance
+
#{personnelBean.membre.dateNaissanceFormatee}
+
+
+
+
+
Adresse
+
#{personnelBean.membre.adresse}
+
+
+
+
+
Profession
+
#{personnelBean.membre.profession}
+
+
+
+
+
+
+
+
+
+
+ Adhésion et Statut
+
+
+
+
Numéro de membre
+
#{personnelBean.membre.numeroMembre}
+
+
+
+
Type d'adhésion
+
#{personnelBean.membre.typeMembre}
+
+
+
+
Date d'inscription
+
#{personnelBean.membre.dateAdhesionFormatee}
+
+
+
+
+
+
+
+
+
+
+
+ Activités Récentes
+
+
+
+
+
+ #{activite.titre}
+ #{activite.dateHeure}
+
+
#{activite.description}
+
+
+
+
+ Aucune activité récente
+
+
+
+
+
+
+
+
+ Rôles et Permissions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/profile.xhtml b/src/main/resources/META-INF/resources/pages/secure/profile.xhtml
index 0e9b322..91d2462 100644
--- a/src/main/resources/META-INF/resources/pages/secure/profile.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/profile.xhtml
@@ -1,241 +1,241 @@
-
-
-
- Mon Profil - UnionFlow
-
-
-
-
-
-
-
-
-
- #{userSession.currentUser.initiales}
-
-
-
#{userSession.currentUser.nomComplet}
-
-
-
•
-
#{userSession.currentUser.email}
-
-
-
- #{userSession.entite.description}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
📋 Informations Personnelles
-
-
-
Nom complet
-
#{userSession.currentUser.nomComplet}
-
-
-
-
Nom d'utilisateur
-
#{userSession.currentUser.username}
-
-
-
-
Adresse email
-
#{userSession.currentUser.email}
-
-
-
-
-
-
-
-
-
-
🏢 Informations de l'Entité
-
-
-
Nom de l'entité
-
#{userSession.entite.nom}
-
-
-
-
Type d'entité
-
#{userSession.entite.type}
-
-
-
-
Localisation
-
-
- #{userSession.entite.ville}, #{userSession.entite.pays}
-
-
-
-
-
-
-
-
-
-
-
-
🔐 Rôles et Permissions
-
-
-
-
-
Permissions spéciales
-
-
-
-
-
-
-
-
-
🔒 Sécurité de la Session
-
-
-
Statut de connexion
-
-
-
-
-
Temps restant
-
-
- #{jwtTokenManager.timeUntilExpiration / 60} minutes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Mon Profil - UnionFlow
+
+
+
+
+
+
+
+
+
+ #{userSession.currentUser.initiales}
+
+
+
#{userSession.currentUser.nomComplet}
+
+
+
•
+
#{userSession.currentUser.email}
+
+
+
+ #{userSession.entite.description}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
📋 Informations Personnelles
+
+
+
Nom complet
+
#{userSession.currentUser.nomComplet}
+
+
+
+
Nom d'utilisateur
+
#{userSession.currentUser.username}
+
+
+
+
Adresse email
+
#{userSession.currentUser.email}
+
+
+
+
+
+
+
+
+
+
🏢 Informations de l'Entité
+
+
+
Nom de l'entité
+
#{userSession.entite.nom}
+
+
+
+
Type d'entité
+
#{userSession.entite.type}
+
+
+
+
Localisation
+
+
+ #{userSession.entite.ville}, #{userSession.entite.pays}
+
+
+
+
+
+
+
+
+
+
+
+
🔐 Rôles et Permissions
+
+
+
+
+
Permissions spéciales
+
+
+
+
+
+
+
+
+
🔒 Sécurité de la Session
+
+
+
Statut de connexion
+
+
+
+
+
Temps restant
+
+
+ #{jwtTokenManager.timeUntilExpiration / 60} minutes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/rapport/activites.xhtml b/src/main/resources/META-INF/resources/pages/secure/rapport/activites.xhtml
index b31eb48..4a58c30 100644
--- a/src/main/resources/META-INF/resources/pages/secure/rapport/activites.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/rapport/activites.xhtml
@@ -1,116 +1,116 @@
-
-
-
-
- Rapports Activités - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Indicateurs d'Activité
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Rapports Activités - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Indicateurs d'Activité
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/rapport/details.xhtml b/src/main/resources/META-INF/resources/pages/secure/rapport/details.xhtml
index 7a9f84f..ea70e57 100644
--- a/src/main/resources/META-INF/resources/pages/secure/rapport/details.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/rapport/details.xhtml
@@ -1,145 +1,145 @@
-
-
-
-
- Détails du Rapport - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{rapportDetailsBean.rapport.typeLibelle}
-
-
-
Généré le #{rapportDetailsBean.dateGenerationFormatee}
-
-
-
-
-
-
-
-
-
-
-
-
-
Informations Générales
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Résumé
-
-
- Ce rapport contient les données analytiques et statistiques
- pour la période sélectionnée. Les informations détaillées
- sont disponibles dans le fichier téléchargeable.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Rapport introuvable
-
Le rapport demandé n'a pas été trouvé.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Détails du Rapport - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{rapportDetailsBean.rapport.typeLibelle}
+
+
+
Généré le #{rapportDetailsBean.dateGenerationFormatee}
+
+
+
+
+
+
+
+
+
+
+
+
+
Informations Générales
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Résumé
+
+
+ Ce rapport contient les données analytiques et statistiques
+ pour la période sélectionnée. Les informations détaillées
+ sont disponibles dans le fichier téléchargeable.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Rapport introuvable
+
Le rapport demandé n'a pas été trouvé.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/rapport/export.xhtml b/src/main/resources/META-INF/resources/pages/secure/rapport/export.xhtml
index b2d7bb6..ef16584 100644
--- a/src/main/resources/META-INF/resources/pages/secure/rapport/export.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/rapport/export.xhtml
@@ -1,170 +1,170 @@
-
-
-
-
- Export de Rapports - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Nouveau Rapport
-
-
-
-
-
-
-
-
- Historique des Rapports
-
-
-
-
-
-
- #{rapport.typeLibelle}
-
-
-
-
- #{rapport.periodeCouverte}
-
-
-
- #{rapport.dateGenerationFormatee}
-
-
-
- #{rapport.generePar}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Export de Rapports - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Nouveau Rapport
+
+
+
+
+
+
+
+
+ Historique des Rapports
+
+
+
+
+
+
+ #{rapport.typeLibelle}
+
+
+
+
+ #{rapport.periodeCouverte}
+
+
+
+ #{rapport.dateGenerationFormatee}
+
+
+
+ #{rapport.generePar}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/rapport/finances.xhtml b/src/main/resources/META-INF/resources/pages/secure/rapport/finances.xhtml
index d673177..13b66c5 100644
--- a/src/main/resources/META-INF/resources/pages/secure/rapport/finances.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/rapport/finances.xhtml
@@ -1,209 +1,209 @@
-
-
-
-
- Rapports Financiers - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Période d'Analyse
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Sources de Revenus
-
-
-
-
- #{source.libelle}
-
-
-
-
- #{source.montant} FCFA
-
-
-
-
-
-
-
-
-
-
-
Indicateurs Clés de Performance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Rapports Financiers - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Période d'Analyse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Sources de Revenus
+
+
+
+
+ #{source.libelle}
+
+
+
+
+ #{source.montant} FCFA
+
+
+
+
+
+
+
+
+
+
+
Indicateurs Clés de Performance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/rapport/membres.xhtml b/src/main/resources/META-INF/resources/pages/secure/rapport/membres.xhtml
index 7ede3e7..502c4a0 100644
--- a/src/main/resources/META-INF/resources/pages/secure/rapport/membres.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/rapport/membres.xhtml
@@ -1,150 +1,150 @@
-
-
-
-
- Rapports Membres - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Répartition des Membres
-
-
-
-
-
#{repartition.libelle}
-
-
-
-
- #{repartition.nombre}
-
-
-
-
-
-
-
-
-
-
-
Objectifs
-
-
-
-
-
- #{objectif.libelle}
- #{objectif.pourcentage}%
-
-
-
- Réalisé: #{objectif.realise}
- Cible: #{objectif.cible}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Rapports Membres - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Répartition des Membres
+
+
+
+
+
#{repartition.libelle}
+
+
+
+
+ #{repartition.nombre}
+
+
+
+
+
+
+
+
+
+
+
Objectifs
+
+
+
+
+
+ #{objectif.libelle}
+ #{objectif.pourcentage}%
+
+
+
+ Réalisé: #{objectif.realise}
+ Cible: #{objectif.cible}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/rapport/tableaux-bord.xhtml b/src/main/resources/META-INF/resources/pages/secure/rapport/tableaux-bord.xhtml
index c0a5d50..ee71f03 100644
--- a/src/main/resources/META-INF/resources/pages/secure/rapport/tableaux-bord.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/rapport/tableaux-bord.xhtml
@@ -1,143 +1,143 @@
-
-
-
- Tableaux de Bord - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Activités Récentes
-
-
-
-
-
-
- #{activite.description}
-
-
- #{activite.date}
-
-
- #{activite.utilisateur}
-
-
-
-
-
-
-
-
- Événements à Venir
-
-
-
- #{evenement.titre}
-
-
- #{evenement.startDate}
-
-
- #{evenement.lieu}
-
-
- #{evenement.currentParticipants != null ? evenement.currentParticipants : 0} / #{evenement.maxParticipants != null ? evenement.maxParticipants : '∞'}
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Tableaux de Bord - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Activités Récentes
+
+
+
+
+
+
+ #{activite.description}
+
+
+ #{activite.date}
+
+
+ #{activite.utilisateur}
+
+
+
+
+
+
+
+
+ Événements à Venir
+
+
+
+ #{evenement.titre}
+
+
+ #{evenement.startDate}
+
+
+ #{evenement.lieu}
+
+
+ #{evenement.currentParticipants != null ? evenement.currentParticipants : 0} / #{evenement.maxParticipants != null ? evenement.maxParticipants : '∞'}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/secure/reports.xhtml b/src/main/resources/META-INF/resources/pages/secure/reports.xhtml
index ec79b6b..e54791c 100644
--- a/src/main/resources/META-INF/resources/pages/secure/reports.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/reports.xhtml
@@ -1,26 +1,26 @@
-
-
-
- UnionFlow - Rapports
-
-
-
-
-
-
Rapports
-
Génération et consultation de rapports
-
-
-
-
-
-
-
+
+
+
+ UnionFlow - Rapports
+
+
+
+
+
+
Rapports
+
Génération et consultation de rapports
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/souscription/dashboard.xhtml b/src/main/resources/META-INF/resources/pages/secure/souscription/dashboard.xhtml
index 5ade155..03bc7ee 100644
--- a/src/main/resources/META-INF/resources/pages/secure/souscription/dashboard.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/souscription/dashboard.xhtml
@@ -1,355 +1,355 @@
-
-
-
- Gestion de la Souscription - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{alerte.titre}
-
#{alerte.message}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Quota de Membres
-
-
-
-
-
-
-
-
-
#{souscriptionBean.souscriptionActive.pourcentageUtilisation}%
-
utilisé
-
-
-
-
- #{souscriptionBean.membresActuels} / #{souscriptionBean.quotaMaximum} membres
-
-
- #{souscriptionBean.membresRestants} membre(s) restant(s)
-
-
-
-
-
-
-
-
-
-
-
Détails de la Souscription
-
-
-
-
-
-
Notifications
-
-
Expiration de souscription
-
-
-
-
-
-
Quota de membres atteint
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Besoin de plus d'espace ?
-
Découvrez nos formules supérieures pour accueillir plus de membres
-
-
-
-
-
-
-
-
-
-
Premium
-
Jusqu'à 500 membres
-
-
-
-
4 000 FCFA/mois
-
40 000 FCFA/an (économisez 16%)
-
-
-
-
- Gestion complète
-
-
- Rapports avancés
-
-
- Support prioritaire
-
-
- Intégrations
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Cristal
-
Jusqu'à 2000 membres
-
-
-
-
5 000 FCFA/mois
-
50 000 FCFA/an (économisez 16%)
-
-
-
-
- Tout Premium +
-
-
- Personnalisation
-
-
- API complète
-
-
- Support dédié
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Gestion de la Souscription - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{alerte.titre}
+
#{alerte.message}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Quota de Membres
+
+
+
+
+
+
+
+
+
#{souscriptionBean.souscriptionActive.pourcentageUtilisation}%
+
utilisé
+
+
+
+
+ #{souscriptionBean.membresActuels} / #{souscriptionBean.quotaMaximum} membres
+
+
+ #{souscriptionBean.membresRestants} membre(s) restant(s)
+
+
+
+
+
+
+
+
+
+
+
Détails de la Souscription
+
+
+
+
+
+
Notifications
+
+
Expiration de souscription
+
+
+
+
+
+
Quota de membres atteint
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Besoin de plus d'espace ?
+
Découvrez nos formules supérieures pour accueillir plus de membres
+
+
+
+
+
+
+
+
+
+
Premium
+
Jusqu'à 500 membres
+
+
+
+
4 000 FCFA/mois
+
40 000 FCFA/an (économisez 16%)
+
+
+
+
+ Gestion complète
+
+
+ Rapports avancés
+
+
+ Support prioritaire
+
+
+ Intégrations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cristal
+
Jusqu'à 2000 membres
+
+
+
+
5 000 FCFA/mois
+
50 000 FCFA/an (économisez 16%)
+
+
+
+
+ Tout Premium +
+
+
+ Personnalisation
+
+
+ API complète
+
+
+ Support dédié
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/secure/stats.xhtml b/src/main/resources/META-INF/resources/pages/secure/stats.xhtml
index cedb565..4892165 100644
--- a/src/main/resources/META-INF/resources/pages/secure/stats.xhtml
+++ b/src/main/resources/META-INF/resources/pages/secure/stats.xhtml
@@ -1,18 +1,18 @@
-
-
-
- Statistiques - UnionFlow
-
-
-
-
-
-
-
+
+
+
+ Statistiques - UnionFlow
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/configuration.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/configuration.xhtml
index d6aaeca..eb05d92 100644
--- a/src/main/resources/META-INF/resources/pages/super-admin/configuration.xhtml
+++ b/src/main/resources/META-INF/resources/pages/super-admin/configuration.xhtml
@@ -1,777 +1,777 @@
-
-
-
- Configuration Système - UnionFlow
-
-
-
-
-
-
-
-
-
-
- Configuration Système
-
-
Paramètres globaux • Sécurité • Intégrations • Performance • #{configBean.derniereModification}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{configBean.statutSysteme}
-
Statut Système
-
-
-
-
-
-
-
-
-
-
-
-
-
#{configBean.versionApplication}
-
Version Application
-
-
-
-
-
-
-
-
-
-
-
-
-
#{configBean.utilisateursConnectes}
-
Utilisateurs En Ligne
-
-
-
-
-
-
-
-
-
-
-
-
-
#{configBean.espaceDisque}
-
Espace Utilisé
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Informations Application
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Paramètres Régionaux
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Options d'Interface
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Serveur SMTP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Configuration Email
-
-
-
-
-
-
-
-
-
-
-
-
Test de Configuration
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Politique de Mots de Passe
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Sessions et Connexions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Surveillance et Audit
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Wave Money API
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
SMS / WhatsApp
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Cache et Mémoire
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Base de Données
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Monitoring en Temps Réel
-
-
-
-
-
#{configBean.cpuUsage}%
-
Utilisation CPU
-
-
-
-
-
-
-
#{configBean.memoryUsage}%
-
Mémoire Utilisée
-
-
-
-
-
-
-
#{configBean.activeConnections}
-
Connexions Actives
-
-
-
-
-
-
#{configBean.responseTime}ms
-
Temps Réponse Moy.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Sauvegarde Automatique
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Nettoyage et Maintenance
-
-
-
-
-
-
-
-
-
-
-
-
Mode Maintenance
-
-
-
-
-
- Le mode maintenance bloque l'accès utilisateur pendant les opérations critiques.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Configuration Système - UnionFlow
+
+
+
+
+
+
+
+
+
+
+ Configuration Système
+
+
Paramètres globaux • Sécurité • Intégrations • Performance • #{configBean.derniereModification}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{configBean.statutSysteme}
+
Statut Système
+
+
+
+
+
+
+
+
+
+
+
+
+
#{configBean.versionApplication}
+
Version Application
+
+
+
+
+
+
+
+
+
+
+
+
+
#{configBean.utilisateursConnectes}
+
Utilisateurs En Ligne
+
+
+
+
+
+
+
+
+
+
+
+
+
#{configBean.espaceDisque}
+
Espace Utilisé
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Informations Application
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Paramètres Régionaux
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Options d'Interface
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Serveur SMTP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Configuration Email
+
+
+
+
+
+
+
+
+
+
+
+
Test de Configuration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Politique de Mots de Passe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Sessions et Connexions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Surveillance et Audit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Wave Money API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SMS / WhatsApp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cache et Mémoire
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Base de Données
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Monitoring en Temps Réel
+
+
+
+
+
#{configBean.cpuUsage}%
+
Utilisation CPU
+
+
+
+
+
+
+
#{configBean.memoryUsage}%
+
Mémoire Utilisée
+
+
+
+
+
+
+
#{configBean.activeConnections}
+
Connexions Actives
+
+
+
+
+
+
#{configBean.responseTime}ms
+
Temps Réponse Moy.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Sauvegarde Automatique
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Nettoyage et Maintenance
+
+
+
+
+
+
+
+
+
+
+
+
Mode Maintenance
+
+
+
+
+
+ Le mode maintenance bloque l'accès utilisateur pendant les opérations critiques.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/configuration/systeme.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/configuration/systeme.xhtml
index 8c4e18d..f65c171 100644
--- a/src/main/resources/META-INF/resources/pages/super-admin/configuration/systeme.xhtml
+++ b/src/main/resources/META-INF/resources/pages/super-admin/configuration/systeme.xhtml
@@ -1,728 +1,728 @@
-
-
-
- Configuration Système - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Configuration Générale
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sécurité et Authentification
-
-
-
-
-
-
-
Options de Sécurité Avancées
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Alertes et Notifications
-
-
-
-
-
-
-
-
-
+
+
+
+ Configuration Système - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Configuration Générale
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sécurité et Authentification
+
+
+
+
+
+
+
Options de Sécurité Avancées
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Alertes et Notifications
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/dashboard-enhanced.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/dashboard-enhanced.xhtml
index 46e0f60..2fdb768 100644
--- a/src/main/resources/META-INF/resources/pages/super-admin/dashboard-enhanced.xhtml
+++ b/src/main/resources/META-INF/resources/pages/super-admin/dashboard-enhanced.xhtml
@@ -1,375 +1,375 @@
-
-
-
- Dashboard Super-Administrateur Enhanced - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Dashboard Super-Administrateur
-
-
Vue globale de la plateforme UnionFlow - Stratégie Volume
-
-
-
#{superAdminBean.nomComplet}
-
Dernière connexion: #{superAdminBean.derniereConnexion}
-
-
-
-
-
-
-
-
-
-
-
-
#{superAdminBean.totalMembres}
-
Membres Actifs
-
-
- +12.5%
- ce mois
-
-
Moyenne: 146/organisation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{superAdminBean.totalEntites}
-
Organisations
-
-
- +8
- nouvelles
-
-
#{superAdminBean.souscriptionsActives} souscriptions actives
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{superAdminBean.revenusGlobaux}
-
Revenus Mensuels
-
-
- +23%
- vs mois dernier
-
-
Taux conversion: #{superAdminBean.tauxConversionFormat}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{superAdminBean.disponibiliteSystemeFormat}
-
Disponibilité
-
-
#{superAdminBean.tempsReponsMoyen}ms temps réponse
-
-
-
-
-
-
-
-
-
-
-
-
-
- Analyse des Souscriptions par Forfait
-
-
-
-
-
44
-
Starter
-
#{superAdminBean.revenusStarterFormat}
-
-
-
-
-
60
-
Standard
-
#{superAdminBean.revenusStandardFormat}
-
-
-
-
-
20
-
Premium
-
#{superAdminBean.revenusPremmiumFormat}
-
-
-
-
-
3
-
Cristal
-
#{superAdminBean.revenusCristalFormat}
-
-
-
-
-
-
-
-
-
- #{superAdminBean.souscriptionsExpirantSous30Jours} souscriptions expirent sous 30 jours
-
-
-
-
-
-
-
-
-
-
-
-
- Support Client
-
-
-
-
-
-
#{superAdminBean.ticketsSupportOuverts}
-
Tickets ouverts
-
-
-
-
-
#{superAdminBean.satisfactionClientFormat}
-
Satisfaction
-
-
-
-
-
-
-
Temps de résolution moyen: 2.3h
-
-
-
-
-
-
-
-
-
-
Alertes Critiques #{superAdminBean.alertesCount}
-
-
-
-
-
-
-
#{alerte.titre}
-
#{alerte.entite} - #{alerte.date}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Actions Rapides
-
-
-
-
-
-
-
-
-
-
Performance Régionale
-
-
-
-
-
-
-
-
Top Entités (Membres)
-
-
-
-
- #{status.index + 1}
-
-
-
#{entite.nom}
-
#{entite.typeEntite}
-
-
-
-
#{entite.nombreMembres}
-
membres
-
-
-
-
-
-
-
+
+
+
+ Dashboard Super-Administrateur Enhanced - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dashboard Super-Administrateur
+
+
Vue globale de la plateforme UnionFlow - Stratégie Volume
+
+
+
#{superAdminBean.nomComplet}
+
Dernière connexion: #{superAdminBean.derniereConnexion}
+
+
+
+
+
+
+
+
+
+
+
+
#{superAdminBean.totalMembres}
+
Membres Actifs
+
+
+ +12.5%
+ ce mois
+
+
Moyenne: 146/organisation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{superAdminBean.totalEntites}
+
Organisations
+
+
+ +8
+ nouvelles
+
+
#{superAdminBean.souscriptionsActives} souscriptions actives
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{superAdminBean.revenusGlobaux}
+
Revenus Mensuels
+
+
+ +23%
+ vs mois dernier
+
+
Taux conversion: #{superAdminBean.tauxConversionFormat}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{superAdminBean.disponibiliteSystemeFormat}
+
Disponibilité
+
+
#{superAdminBean.tempsReponsMoyen}ms temps réponse
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Analyse des Souscriptions par Forfait
+
+
+
+
+
44
+
Starter
+
#{superAdminBean.revenusStarterFormat}
+
+
+
+
+
60
+
Standard
+
#{superAdminBean.revenusStandardFormat}
+
+
+
+
+
20
+
Premium
+
#{superAdminBean.revenusPremmiumFormat}
+
+
+
+
+
3
+
Cristal
+
#{superAdminBean.revenusCristalFormat}
+
+
+
+
+
+
+
+
+
+ #{superAdminBean.souscriptionsExpirantSous30Jours} souscriptions expirent sous 30 jours
+
+
+
+
+
+
+
+
+
+
+
+
+ Support Client
+
+
+
+
+
+
#{superAdminBean.ticketsSupportOuverts}
+
Tickets ouverts
+
+
+
+
+
#{superAdminBean.satisfactionClientFormat}
+
Satisfaction
+
+
+
+
+
+
+
Temps de résolution moyen: 2.3h
+
+
+
+
+
+
+
+
+
+
Alertes Critiques #{superAdminBean.alertesCount}
+
+
+
+
+
+
+
#{alerte.titre}
+
#{alerte.entite} - #{alerte.date}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Actions Rapides
+
+
+
+
+
+
+
+
+
+
Performance Régionale
+
+
+
+
+
+
+
+
Top Entités (Membres)
+
+
+
+
+ #{status.index + 1}
+
+
+
#{entite.nom}
+
#{entite.typeEntite}
+
+
+
+
#{entite.nombreMembres}
+
membres
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/roles/gestion.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/roles/gestion.xhtml
index 8a978a6..fa5a777 100644
--- a/src/main/resources/META-INF/resources/pages/super-admin/roles/gestion.xhtml
+++ b/src/main/resources/META-INF/resources/pages/super-admin/roles/gestion.xhtml
@@ -1,391 +1,391 @@
-
-
-
- Rôles et Permissions - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
- Rôles et Permissions
-
-
- Gérez les rôles utilisateur et leurs permissions système
-
-
-
-
-
-
-
-
-
-
#{rolesBean.totalRoles}
-
Rôles Totaux
-
Système et personnalisés
-
-
-
-
-
#{rolesBean.rolesActifs}
-
Rôles Actifs
-
Utilisés actuellement
-
-
-
-
-
#{rolesBean.utilisateursAvecRoles}
-
Utilisateurs
-
Avec rôles assignés
-
-
-
-
-
#{rolesBean.permissionsUniques}
-
Permissions
-
Définies au total
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{role.nom}
-
#{role.description}
-
-
-
-
-
-
-
-
-
-
-
-
-
- #{role.nombreUtilisateurs}
- assignés
-
-
-
-
-
-
-
- #{role.dateModificationFormatee}
- #{role.modifiePar}
-
-
-
-
-
-
-
- Êtes-vous sûr de vouloir supprimer ce rôle ?
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{rolesBean.roleSelectionne.nom}
-
#{rolesBean.roleSelectionne.description}
-
-
-
-
-
-
-
-
Permissions Accordées
-
-
-
-
- #{perm.libelle}
-
-
-
-
-
-
Utilisateurs Assignés
-
-
-
-
- #{user.nom} #{user.prenom}
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Rôles et Permissions - UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+ Rôles et Permissions
+
+
+ Gérez les rôles utilisateur et leurs permissions système
+
+
+
+
+
+
+
+
+
+
#{rolesBean.totalRoles}
+
Rôles Totaux
+
Système et personnalisés
+
+
+
+
+
#{rolesBean.rolesActifs}
+
Rôles Actifs
+
Utilisés actuellement
+
+
+
+
+
#{rolesBean.utilisateursAvecRoles}
+
Utilisateurs
+
Avec rôles assignés
+
+
+
+
+
#{rolesBean.permissionsUniques}
+
Permissions
+
Définies au total
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{role.nom}
+
#{role.description}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{role.nombreUtilisateurs}
+ assignés
+
+
+
+
+
+
+
+ #{role.dateModificationFormatee}
+ #{role.modifiePar}
+
+
+
+
+
+
+
+ Êtes-vous sûr de vouloir supprimer ce rôle ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{rolesBean.roleSelectionne.nom}
+
#{rolesBean.roleSelectionne.description}
+
+
+
+
+
+
+
+
Permissions Accordées
+
+
+
+
+ #{perm.libelle}
+
+
+
+
+
+
Utilisateurs Assignés
+
+
+
+
+ #{user.nom} #{user.prenom}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/types/organisations.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/types/organisations.xhtml
index 97b008e..58fc94a 100644
--- a/src/main/resources/META-INF/resources/pages/super-admin/types/organisations.xhtml
+++ b/src/main/resources/META-INF/resources/pages/super-admin/types/organisations.xhtml
@@ -1,227 +1,227 @@
-
-
-
- Catalogue des Types d'Organisation
-
-
-
-
-
-
-
-
-
Catalogue des Types d'Organisation
-
- Gestion centrale des types utilisés par les organisations (Lions Club, Association, Coopérative, ...).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Supprimer définitivement ce type d'organisation ? Cette action est irréversible.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Catalogue des Types d'Organisation
+
+
+
+
+
+
+
+
+
Catalogue des Types d'Organisation
+
+ Gestion centrale des types utilisés par les organisations (Lions Club, Association, Coopérative, ...).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Supprimer définitivement ce type d'organisation ? Cette action est irréversible.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/resources/components/action-button-delete.xhtml b/src/main/resources/META-INF/resources/resources/components/action-button-delete.xhtml
index 1951c58..0ad1728 100644
--- a/src/main/resources/META-INF/resources/resources/components/action-button-delete.xhtml
+++ b/src/main/resources/META-INF/resources/resources/components/action-button-delete.xhtml
@@ -1,28 +1,28 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/resources/components/action-button-edit-nav.xhtml b/src/main/resources/META-INF/resources/resources/components/action-button-edit-nav.xhtml
index df995d9..3206c12 100644
--- a/src/main/resources/META-INF/resources/resources/components/action-button-edit-nav.xhtml
+++ b/src/main/resources/META-INF/resources/resources/components/action-button-edit-nav.xhtml
@@ -1,22 +1,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/resources/components/action-button-edit.xhtml b/src/main/resources/META-INF/resources/resources/components/action-button-edit.xhtml
index be60050..26d3ef3 100644
--- a/src/main/resources/META-INF/resources/resources/components/action-button-edit.xhtml
+++ b/src/main/resources/META-INF/resources/resources/components/action-button-edit.xhtml
@@ -1,25 +1,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/resources/components/action-button-toggle.xhtml b/src/main/resources/META-INF/resources/resources/components/action-button-toggle.xhtml
index 77fab92..a62f8b6 100644
--- a/src/main/resources/META-INF/resources/resources/components/action-button-toggle.xhtml
+++ b/src/main/resources/META-INF/resources/resources/components/action-button-toggle.xhtml
@@ -1,29 +1,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/resources/components/action-button-view.xhtml b/src/main/resources/META-INF/resources/resources/components/action-button-view.xhtml
index d001b40..c0699b6 100644
--- a/src/main/resources/META-INF/resources/resources/components/action-button-view.xhtml
+++ b/src/main/resources/META-INF/resources/resources/components/action-button-view.xhtml
@@ -1,22 +1,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/resources/css/topbar-elite.css b/src/main/resources/META-INF/resources/resources/css/topbar-elite.css
index a564057..14ea74d 100644
--- a/src/main/resources/META-INF/resources/resources/css/topbar-elite.css
+++ b/src/main/resources/META-INF/resources/resources/css/topbar-elite.css
@@ -1,1466 +1,1466 @@
-/*
- * ╔════════════════════════════════════════════════════════════╗
- * ║ UnionFlow Elite Topbar Styles (Freya Design System) ║
- * ║ Modern, Professional, Responsive ║
- * ╚════════════════════════════════════════════════════════════╝
- */
-
-/* ═══════════════════════════════════════════════════════════ */
-/* BASE TOPBAR */
-/* ═══════════════════════════════════════════════════════════ */
-
-.unionflow-elite {
- background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-600) 100%);
- box-shadow: 0 2px 12px rgba(0,0,0,0.08);
- position: relative;
- z-index: 1000;
-}
-
-.unionflow-elite::after {
- content: '';
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- height: 2px;
- background: linear-gradient(90deg,
- transparent 0%,
- var(--primary-300) 50%,
- transparent 100%);
- opacity: 0.5;
-}
-
-/* App Version Badge */
-.app-version {
- display: inline-flex;
- align-items: center;
- padding: 0.25rem 0.625rem;
- background: rgba(255,255,255,0.15);
- border-radius: 12px;
- font-size: 0.75rem;
- font-weight: 600;
- color: rgba(255,255,255,0.9);
- margin-left: 0.75rem;
- backdrop-filter: blur(10px);
- border: 1px solid rgba(255,255,255,0.2);
-}
-
-/* ═══════════════════════════════════════════════════════════ */
-/* SEARCH */
-/* ═══════════════════════════════════════════════════════════ */
-
-.search-item .topbar-icon {
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-}
-
-.search-item:hover .topbar-icon {
- transform: scale(1.1);
- color: var(--primary-100);
-}
-
-.search-dropdown {
- position: absolute;
- top: calc(100% + 0.5rem);
- right: 0;
- min-width: 400px;
- background: white;
- border-radius: 12px;
- box-shadow: 0 8px 32px rgba(0,0,0,0.12);
- padding: 1rem;
- opacity: 0;
- visibility: hidden;
- transform: translateY(-10px);
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- border: 1px solid var(--surface-border);
-}
-
-.search-item:hover .search-dropdown {
- opacity: 1;
- visibility: visible;
- transform: translateY(0);
-}
-
-.search-wrapper-elite {
- display: flex;
- align-items: center;
- gap: 0.75rem;
- background: var(--surface-50);
- border-radius: 8px;
- padding: 0.5rem 1rem;
- border: 1px solid var(--surface-border);
- transition: all 0.3s ease;
-}
-
-.search-wrapper-elite:focus-within {
- background: white;
- border-color: var(--primary-color);
- box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.1);
-}
-
-.search-wrapper-elite .pi-search {
- color: var(--text-color-secondary);
- font-size: 1rem;
-}
-
-.search-wrapper-elite .search-input {
- flex: 1;
- border: none;
- background: transparent;
- padding: 0.5rem 0;
- font-size: 0.875rem;
-}
-
-.search-wrapper-elite .search-input:focus {
- outline: none;
- box-shadow: none;
-}
-
-/* ═══════════════════════════════════════════════════════════ */
-/* NOTIFICATIONS */
-/* ═══════════════════════════════════════════════════════════ */
-
-.notifications-item {
- position: relative;
-}
-
-.badge-count {
- position: absolute;
- top: -4px;
- right: -4px;
- background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
- color: white;
- font-size: 0.625rem;
- font-weight: 700;
- padding: 0.125rem 0.375rem;
- border-radius: 10px;
- min-width: 18px;
- height: 18px;
- display: flex;
- align-items: center;
- justify-content: center;
- box-shadow: 0 2px 8px rgba(239, 68, 68, 0.4);
- animation: pulse-badge 2s infinite;
-}
-
-@keyframes pulse-badge {
- 0%, 100% { transform: scale(1); }
- 50% { transform: scale(1.1); }
-}
-
-.notifications-dropdown {
- position: absolute;
- top: calc(100% + 0.5rem);
- right: 0;
- min-width: 360px;
- max-width: 400px;
- background: white;
- border-radius: 12px;
- box-shadow: 0 8px 32px rgba(0,0,0,0.12);
- opacity: 0;
- visibility: hidden;
- transform: translateY(-10px);
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- border: 1px solid var(--surface-border);
- overflow: hidden;
-}
-
-.notifications-item:hover .notifications-dropdown {
- opacity: 1;
- visibility: visible;
- transform: translateY(0);
-}
-
-.notif-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 1rem 1.25rem;
- background: var(--surface-50);
- border-bottom: 1px solid var(--surface-border);
-}
-
-.count-label {
- font-size: 0.75rem;
- color: var(--text-color-secondary);
- background: var(--primary-color);
- color: white;
- padding: 0.25rem 0.625rem;
- border-radius: 12px;
- font-weight: 600;
-}
-
-.notif-item {
- display: flex;
- align-items: flex-start;
- gap: 0.875rem;
- padding: 0.875rem 1.25rem;
- transition: all 0.2s ease;
- cursor: pointer;
-}
-
-.notif-item:hover {
- background: var(--surface-50);
-}
-
-.notif-item i {
- font-size: 1.25rem;
- margin-top: 0.25rem;
-}
-
-.notif-title {
- font-weight: 600;
- color: var(--text-color);
- font-size: 0.875rem;
- margin-bottom: 0.25rem;
-}
-
-.notif-time {
- font-size: 0.75rem;
- color: var(--text-color-secondary);
-}
-
-.notif-footer {
- padding: 0.75rem 1.25rem;
- text-align: center;
- border-top: 1px solid var(--surface-border);
- background: var(--surface-50);
-}
-
-.notif-footer a {
- font-size: 0.875rem;
- font-weight: 600;
- text-decoration: none;
- transition: color 0.2s ease;
-}
-
-.notif-footer a:hover {
- color: var(--primary-600);
-}
-
-/* ═══════════════════════════════════════════════════════════ */
-/* USER PROFILE */
-/* ═══════════════════════════════════════════════════════════ */
-
-.elite-user .profile-trigger {
- display: flex;
- align-items: center;
- gap: 0.75rem;
- padding: 0.5rem 0.875rem;
- border-radius: 10px;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- background: rgba(255,255,255,0.1);
- backdrop-filter: blur(10px);
-}
-
-.elite-user .profile-trigger:hover {
- background: rgba(255,255,255,0.2);
- transform: translateY(-1px);
-}
-
-.avatar-container {
- position: relative;
-}
-
-.avatar {
- width: 38px;
- height: 38px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 0.875rem;
- font-weight: 700;
- color: white;
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
- border: 2px solid rgba(255,255,255,0.3);
-}
-
-.bg-gradient-primary {
- background: linear-gradient(135deg, var(--primary-400) 0%, var(--primary-600) 100%);
-}
-
-.status-dot {
- position: absolute;
- bottom: 0;
- right: 0;
- width: 10px;
- height: 10px;
- border-radius: 50%;
- border: 2px solid white;
-}
-
-.status-dot.online {
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
- box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2);
- animation: pulse-dot 2s infinite;
-}
-
-@keyframes pulse-dot {
- 0%, 100% { box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2); }
- 50% { box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.4); }
-}
-
-.user-info {
- display: flex;
- flex-direction: column;
- gap: 0.25rem;
-}
-
-.user-header {
- display: flex;
- align-items: center;
- gap: 0.5rem;
-}
-
-.user-name {
- font-size: 0.875rem;
- font-weight: 600;
- color: white;
- line-height: 1.2;
-}
-
-.role-badge {
- font-size: 0.625rem;
- padding: 0.125rem 0.5rem;
- background: rgba(255,255,255,0.25);
- border-radius: 8px;
- font-weight: 600;
- color: white;
- text-transform: uppercase;
- letter-spacing: 0.5px;
-}
-
-.session-timer {
- display: flex;
- align-items: center;
- gap: 0.375rem;
-}
-
-.icon-sm {
- font-size: 0.7rem;
-}
-
-.timer-text {
- font-size: 0.75rem;
- font-weight: 600;
- font-family: 'Courier New', monospace;
-}
-
-.arrow {
- font-size: 0.75rem;
- color: rgba(255,255,255,0.8);
- transition: transform 0.3s ease;
-}
-
-.elite-user:hover .arrow {
- transform: rotate(180deg);
-}
-
-/* ═══════════════════════════════════════════════════════════ */
-/* USER DROPDOWN MENU */
-/* ═══════════════════════════════════════════════════════════ */
-
-.elite-dropdown {
- position: absolute;
- top: calc(100% + 0.5rem);
- right: 0;
- min-width: 340px;
- background: white;
- border-radius: 16px;
- box-shadow: 0 12px 48px rgba(0,0,0,0.15);
- opacity: 0;
- visibility: hidden;
- transform: translateY(-10px) scale(0.95);
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- border: 1px solid var(--surface-border);
- overflow: hidden;
-}
-
-.elite-user:hover .elite-dropdown {
- opacity: 1;
- visibility: visible;
- transform: translateY(0) scale(1);
-}
-
-/* Dropdown Header */
-.dropdown-header {
- padding: 1.25rem;
- background: linear-gradient(135deg, var(--primary-50) 0%, var(--surface-50) 100%);
- border-bottom: 1px solid var(--surface-border);
-}
-
-.header-content {
- display: flex;
- gap: 1rem;
-}
-
-.header-avatar {
- position: relative;
-}
-
-.avatar-lg {
- width: 56px;
- height: 56px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 1.25rem;
- font-weight: 700;
- color: white;
- box-shadow: 0 6px 16px rgba(0,0,0,0.15);
-}
-
-.status-indicator {
- position: absolute;
- bottom: 2px;
- right: 2px;
- width: 14px;
- height: 14px;
- border-radius: 50%;
- border: 3px solid white;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.status-indicator.online {
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-}
-
-.status-indicator i {
- font-size: 6px;
- color: white;
-}
-
-.header-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 0.25rem;
- justify-content: center;
-}
-
-.header-info .name {
- font-size: 1rem;
- font-weight: 700;
- color: var(--text-color);
- line-height: 1.3;
-}
-
-.header-info .email {
- font-size: 0.75rem;
- color: var(--text-color-secondary);
- line-height: 1.3;
-}
-
-.role-tag {
- display: inline-flex;
- align-items: center;
- font-size: 0.625rem;
- padding: 0.25rem 0.625rem;
- background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-600) 100%);
- color: white;
- border-radius: 8px;
- font-weight: 600;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- align-self: flex-start;
- margin-top: 0.25rem;
-}
-
-/* Session Card */
-.session-card {
- padding: 1rem 1.25rem;
- background: var(--surface-50);
- border-bottom: 1px solid var(--surface-border);
-}
-
-.card-content {
- display: flex;
- flex-direction: column;
- gap: 0.625rem;
-}
-
-.info-row {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.info-row .label {
- display: flex;
- align-items: center;
- gap: 0.5rem;
- font-size: 0.75rem;
- color: var(--text-color-secondary);
- font-weight: 500;
-}
-
-.info-row .label i {
- font-size: 0.875rem;
-}
-
-.info-row .value {
- font-size: 0.875rem;
- font-weight: 600;
- color: var(--text-color);
-}
-
-/* Progress Bar */
-.progress-container {
- margin-top: 0.5rem;
-}
-
-.progress-bar {
- height: 6px;
- background: var(--surface-200);
- border-radius: 10px;
- overflow: hidden;
- position: relative;
-}
-
-.progress-fill {
- height: 100%;
- background: linear-gradient(90deg, var(--green-400) 0%, var(--green-500) 100%);
- border-radius: 10px;
- transition: width 1s ease, background 0.3s ease;
-}
-
-.progress-fill[style*="width: 0%"],
-.progress-fill[style*="width: 1%"],
-.progress-fill[style*="width: 2%"],
-.progress-fill[style*="width: 3%"],
-.progress-fill[style*="width: 4%"],
-.progress-fill[style*="width: 5%"] {
- background: linear-gradient(90deg, var(--red-400) 0%, var(--red-500) 100%);
-}
-
-.progress-label {
- font-size: 0.625rem;
- color: var(--text-color-secondary);
- margin-top: 0.375rem;
- text-align: right;
- font-weight: 500;
-}
-
-/* Menu Sections */
-.divider {
- height: 1px;
- background: var(--surface-border);
- margin: 0;
-}
-
-.menu-section {
- padding: 0.75rem 0;
-}
-
-.menu-section.compact {
- padding: 0.5rem 0;
-}
-
-.section-title {
- display: flex;
- align-items: center;
- gap: 0.5rem;
- font-size: 0.75rem;
- font-weight: 700;
- color: var(--text-color-secondary);
- text-transform: uppercase;
- letter-spacing: 0.5px;
- padding: 0.5rem 1.25rem 0.75rem;
-}
-
-.section-items {
- display: flex;
- flex-direction: column;
-}
-
-.menu-item {
- display: flex;
- align-items: center;
- gap: 0.875rem;
- padding: 0.75rem 1.25rem;
- color: var(--text-color);
- text-decoration: none;
- transition: all 0.2s ease;
- font-size: 0.875rem;
- cursor: pointer;
- border: none;
- background: transparent;
- width: 100%;
- text-align: left;
-}
-
-.menu-item:hover {
- background: var(--surface-100);
-}
-
-.menu-item i:first-child {
- font-size: 1rem;
- color: var(--text-color-secondary);
- transition: all 0.2s ease;
-}
-
-.menu-item:hover i:first-child {
- color: var(--primary-color);
- transform: translateX(2px);
-}
-
-.menu-item span {
- flex: 1;
- font-weight: 500;
-}
-
-.arrow-right {
- font-size: 0.75rem;
- color: var(--text-color-secondary);
- margin-left: auto;
- transition: transform 0.2s ease;
-}
-
-.menu-item:hover .arrow-right {
- transform: translateX(3px);
-}
-
-.item-badge {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- min-width: 20px;
- height: 20px;
- padding: 0 0.375rem;
- background: var(--primary-color);
- color: white;
- font-size: 0.625rem;
- font-weight: 700;
- border-radius: 10px;
- margin-left: auto;
-}
-
-.value-badge {
- font-size: 0.75rem;
- color: var(--text-color-secondary);
- background: var(--surface-100);
- padding: 0.25rem 0.625rem;
- border-radius: 8px;
- font-weight: 600;
- margin-left: auto;
-}
-
-/* Logout Section */
-.logout-divider {
- background: linear-gradient(90deg,
- transparent 0%,
- var(--red-200) 50%,
- transparent 100%);
- height: 2px;
-}
-
-.logout-section {
- padding: 0.75rem 0;
- background: linear-gradient(to bottom, white 0%, var(--red-50) 100%);
-}
-
-.logout-btn {
- display: flex;
- align-items: center;
- gap: 0.875rem;
- padding: 0.875rem 1.25rem;
- color: var(--red-600);
- font-weight: 600;
- font-size: 0.875rem;
- text-decoration: none;
- transition: all 0.3s ease;
- cursor: pointer;
- border: none;
- background: transparent;
- width: 100%;
- text-align: left;
-}
-
-.logout-btn:hover {
- background: var(--red-100);
- color: var(--red-700);
-}
-
-.logout-btn i:first-child {
- font-size: 1rem;
- transition: transform 0.3s ease;
-}
-
-.logout-btn:hover i:first-child {
- transform: scale(1.1) rotate(-10deg);
-}
-
-.logout-btn .pi-lock {
- font-size: 0.875rem;
-}
-
-/* ═══════════════════════════════════════════════════════════ */
-/* LOGOUT DIALOG */
-/* ═══════════════════════════════════════════════════════════ */
-
-.elite-dialog .dialog-content {
- text-align: center;
- padding: 1.5rem 1rem;
-}
-
-.icon-wrapper {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 80px;
- height: 80px;
- border-radius: 50%;
- background: linear-gradient(135deg, var(--red-50) 0%, var(--red-100) 100%);
- margin-bottom: 1.5rem;
-}
-
-.icon-lg {
- font-size: 2.5rem;
- color: var(--red-500);
-}
-
-.dialog-title {
- font-size: 1.25rem;
- font-weight: 700;
- color: var(--text-color);
- margin-bottom: 1.5rem;
- line-height: 1.4;
-}
-
-.info-box {
- background: var(--surface-50);
- border-radius: 12px;
- padding: 1rem;
- margin-bottom: 1rem;
- border: 1px solid var(--surface-border);
-}
-
-.info-item {
- display: flex;
- align-items: center;
- gap: 0.75rem;
- padding: 0.625rem;
- color: var(--text-color);
- font-size: 0.875rem;
-}
-
-.info-item i {
- color: var(--primary-color);
- font-size: 1rem;
-}
-
-.warning-text {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 0.5rem;
- font-size: 0.875rem;
- color: var(--text-color-secondary);
- margin: 0;
-}
-
-.warning-text i {
- color: var(--blue-500);
-}
-
-.dialog-footer {
- display: flex;
- gap: 0.75rem;
- justify-content: flex-end;
- padding-top: 1rem;
-}
-
-/* ═══════════════════════════════════════════════════════════ */
-/* UTILITY CLASSES */
-/* ═══════════════════════════════════════════════════════════ */
-
-.text-green-600 { color: #059669 !important; }
-.text-yellow-600 { color: #d97706 !important; }
-.text-orange-600 { color: #ea580c !important; }
-.text-red-600 { color: #dc2626 !important; }
-
-/* ═══════════════════════════════════════════════════════════ */
-/* RESPONSIVE */
-/* ═══════════════════════════════════════════════════════════ */
-
-@media (max-width: 768px) {
- .app-version { display: none; }
- .user-info { display: none; }
- .elite-dropdown { min-width: 300px; }
- .search-dropdown { min-width: 280px; }
- .org-switcher-label { display: none; }
-}
-
-/* ═══════════════════════════════════════════════════════════ */
-/* ORG SWITCHER */
-/* ═══════════════════════════════════════════════════════════ */
-
-.org-switcher-item {
- position: relative;
-}
-
-.org-switcher-trigger {
- display: flex;
- align-items: center;
- gap: 0.4rem;
- padding: 0.4rem 0.75rem;
- border-radius: 8px;
- background: rgba(var(--primary-color-rgb, 99,102,241), 0.08);
- border: 1px solid rgba(var(--primary-color-rgb, 99,102,241), 0.2);
- color: var(--text-color, #374151);
- font-size: 0.875rem;
- font-weight: 500;
- cursor: pointer;
- text-decoration: none;
- transition: background 0.2s, border-color 0.2s;
- max-width: 220px;
-}
-
-.org-switcher-trigger:hover {
- background: rgba(var(--primary-color-rgb, 99,102,241), 0.15);
- border-color: var(--primary-color, #6366f1);
- text-decoration: none;
-}
-
-.org-switcher-label {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- max-width: 160px;
-}
-
-.org-switcher-dropdown {
- display: none;
- position: absolute;
- top: calc(100% + 8px);
- left: 0;
- min-width: 280px;
- background: var(--surface-card, #fff);
- border: 1px solid var(--surface-border, #e5e7eb);
- border-radius: 12px;
- box-shadow: 0 10px 40px rgba(0,0,0,0.12);
- z-index: 1000;
- padding: 0.5rem 0;
- list-style: none;
- margin: 0;
-}
-
-.org-switcher-item:hover .org-switcher-dropdown,
-.org-switcher-item:focus-within .org-switcher-dropdown {
- display: block;
-}
-
-.org-item {
- padding: 0;
-}
-
-.org-item-link {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0.6rem 1rem;
- cursor: pointer;
- text-decoration: none;
- color: var(--text-color, #374151);
- transition: background 0.15s;
-}
-
-.org-item-link:hover {
- background: var(--surface-hover, #f9fafb);
-}
-
-.org-item-active .org-item-link {
- background: rgba(var(--primary-color-rgb, 99,102,241), 0.06);
-}
-
-.org-item-content {
- display: flex;
- flex-direction: column;
- gap: 0.2rem;
-}
-
-.org-item-name {
- font-weight: 600;
- font-size: 0.875rem;
- color: var(--text-color, #111827);
-}
-
-.org-item-meta {
- display: flex;
- gap: 0.4rem;
-}
-
-.org-type-badge {
- font-size: 0.7rem;
- background: var(--surface-ground, #f3f4f6);
- color: var(--text-color-secondary, #6b7280);
- padding: 0.1rem 0.4rem;
- border-radius: 4px;
-}
-
-.org-role-badge {
- font-size: 0.7rem;
- background: #ecfdf5;
- color: #065f46;
- padding: 0.1rem 0.4rem;
- border-radius: 4px;
-}
-
-.org-check-icon {
- color: var(--primary-color, #6366f1);
- font-size: 0.875rem;
-}
-
-/* ═══════════════════════════════════════════════════════════════════ */
-/* UNIONFLOW BRAND IDENTITY — EXHAUSTIVE DARK/LIGHT MODE SUPPORT */
-/* Charte: #0B304A (Bleu Nuit), #126A54 (Vert Forêt), */
-/* #E6C57A (Or Premium), #F4F6F8 (Fond), #E8EAEC */
-/* */
-/* Freya theme axes: */
-/* 1. topbarTheme → .layout-topbar-light | .layout-topbar-dark */
-/* 2. menuTheme → .layout-menu-light | .layout-menu-dark */
-/* 3. darkMode → layout-light.css | layout-dark.css */
-/* 4. menuMode → .layout-sidebar | .layout-static */
-/* .layout-horizontal | .layout-slim */
-/* ═══════════════════════════════════════════════════════════════════ */
-
-/* ──────────────────────────────────────────────────
- 1. BASE — Brand Composition (Logo + Text)
- Now uses .unionflow-topbar-brand (outside of
- .layout-topbar-logo to avoid Freya display:none)
- ────────────────────────────────────────────────── */
-
-.unionflow-topbar-brand,
-.unionflow-brand {
- display: flex !important;
- align-items: center;
- gap: 0.625rem;
- text-decoration: none !important;
- height: auto !important;
-}
-
-.unionflow-brand-icon {
- width: 36px;
- height: 36px;
- object-fit: contain;
- flex-shrink: 0;
- border-radius: 4px;
- transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-}
-
-.unionflow-topbar-brand:hover .unionflow-brand-icon,
-.unionflow-brand:hover .unionflow-brand-icon {
- transform: scale(1.05) rotate(-2deg);
-}
-
-.unionflow-brand-text {
- display: flex;
- flex-direction: column;
- line-height: 1;
- gap: 0.1875rem;
-}
-
-.unionflow-brand-name {
- font-size: 1.125rem;
- font-weight: 800;
- letter-spacing: 0.15em;
- text-transform: uppercase;
- font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
- transition: color 0.2s ease;
-}
-
-.unionflow-brand-slogan {
- font-size: 0.5625rem;
- font-weight: 600;
- letter-spacing: 0.12em;
- text-transform: uppercase;
- font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
- transition: color 0.2s ease;
-}
-
-/* ──────────────────────────────────────────────────
- 2. TOPBAR — Dark mode (default: gradient/dark bg)
- Classes: .layout-topbar-dark, .unionflow-elite
- ────────────────────────────────────────────────── */
-
-.layout-topbar-dark .unionflow-brand-name,
-.unionflow-elite .unionflow-brand-name {
- color: #FFFFFF;
-}
-
-.layout-topbar-dark .unionflow-brand-slogan,
-.unionflow-elite .unionflow-brand-slogan {
- color: rgba(230, 197, 122, 0.9); /* Or Premium #E6C57A */
-}
-
-/* ──────────────────────────────────────────────────
- 3. TOPBAR — Light mode (white bg)
- Class: .layout-topbar-light
- ────────────────────────────────────────────────── */
-
-.layout-topbar-light .unionflow-brand-name {
- color: #0B304A; /* Bleu Nuit */
-}
-
-.layout-topbar-light .unionflow-brand-slogan {
- color: #126A54; /* Vert Forêt */
-}
-
-/* ──────────────────────────────────────────────────
- 4. SIDEBAR BRAND — Single source of branding
- Collapsed (62px): icon only
- Expanded (230px): icon + UNIONFLOW + slogan + v1.0
- ────────────────────────────────────────────────── */
-
-/* --- Logo link container --- */
-.sidebar-logo-link {
- display: flex;
- align-items: center;
- gap: 0.5rem;
- text-decoration: none !important;
- overflow: hidden;
- flex: 1;
- min-width: 0;
-}
-
-.sidebar-logo-link:hover .unionflow-sidebar-icon {
- transform: scale(1.08);
-}
-
-/* --- Icon (always visible — 24px for visual parity with menu icons) --- */
-.unionflow-sidebar-icon {
- width: 24px !important;
- height: 24px !important;
- object-fit: contain;
- border-radius: 3px;
- border: 0 none !important;
- flex-shrink: 0;
- transition: all 0.2s ease;
-}
-
-/* Override Freya's .menu-wrapper .sidebar-logo img { width:17px; height:20px } */
-.menu-wrapper .sidebar-logo .unionflow-sidebar-icon {
- width: 24px !important;
- height: 24px !important;
-}
-
-/* --- Text block (hidden when collapsed) --- */
-.unionflow-sidebar-text {
- display: flex;
- flex-direction: column;
- line-height: 1;
- gap: 0.125rem;
- white-space: nowrap;
- overflow: hidden;
- visibility: hidden;
- opacity: 0;
- width: 0;
- transition: opacity 0.2s ease, visibility 0.2s ease;
-}
-
-.unionflow-sidebar-name {
- font-size: 0.9375rem;
- font-weight: 800;
- letter-spacing: 0.15em;
- text-transform: uppercase;
- font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
-}
-
-.unionflow-sidebar-slogan {
- font-size: 0.5rem;
- font-weight: 600;
- letter-spacing: 0.08em;
- text-transform: uppercase;
- font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
- opacity: 0.7;
-}
-
-/* --- Version badge (hidden when collapsed) --- */
-.unionflow-sidebar-version {
- display: inline-flex;
- align-items: center;
- padding: 0;
- border-radius: 8px;
- font-size: 0.625rem;
- font-weight: 600;
- white-space: nowrap;
- visibility: hidden;
- opacity: 0;
- width: 0;
- overflow: hidden;
- transition: opacity 0.2s ease, visibility 0.2s ease;
-}
-
-/* ──────────────────────────────────────────────────
- 4b. SIDEBAR EXPANDED — Show full brand
- Triggered by: layout-static, layout-sidebar-active (hover)
- ────────────────────────────────────────────────── */
-
-@media (min-width: 992px) {
- /* Expanded: icon grows slightly */
- .layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-icon,
- .menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-icon {
- width: 30px !important;
- height: 30px !important;
- }
-
- /* Expanded: show text */
- .layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-text,
- .menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-text {
- visibility: visible;
- opacity: 1;
- width: auto;
- }
-
- /* Expanded: show version badge */
- .layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-version,
- .menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-version {
- visibility: visible;
- opacity: 1;
- width: auto;
- padding: 0.125rem 0.4rem;
- }
-}
-
-/* ──────────────────────────────────────────────────
- 5. SIDEBAR — Menu Dark theme
- Class: .layout-menu-dark (menu bg = #293241)
- ────────────────────────────────────────────────── */
-
-.layout-menu-dark .unionflow-sidebar-name {
- color: #FFFFFF;
-}
-
-.layout-menu-dark .unionflow-sidebar-slogan {
- color: rgba(230, 197, 122, 0.85); /* Or Premium */
-}
-
-.layout-menu-dark .unionflow-sidebar-version {
- background: rgba(255, 255, 255, 0.15);
- color: rgba(255, 255, 255, 0.9);
-}
-
-.layout-menu-dark .sidebar-logo-link {
- color: #E9E9E9;
-}
-
-/* ──────────────────────────────────────────────────
- 6. SIDEBAR — Menu Light theme
- Class: .layout-menu-light (menu bg = white)
- ────────────────────────────────────────────────── */
-
-.layout-menu-light .unionflow-sidebar-name {
- color: #0B304A; /* Bleu Nuit */
-}
-
-.layout-menu-light .unionflow-sidebar-slogan {
- color: #126A54; /* Vert Forêt */
-}
-
-.layout-menu-light .unionflow-sidebar-version {
- background: rgba(11, 48, 74, 0.1);
- color: #0B304A;
-}
-
-.layout-menu-light .sidebar-logo-link {
- color: #0B304A;
-}
-
-/* ──────────────────────────────────────────────────
- 9. LANDING PAGE — Variant Premium Unionflow
- ────────────────────────────────────────────────── */
-
-/* App background */
-.landing-body {
- background-color: #F4F6F8 !important; /* Très léger gris/bleu pour le fond de page */
-}
-
-/* Banner (Hero section) - Deep Blue modern gradient instead of the generic mountain */
-.landing-body .landing-banner {
- background: linear-gradient(135deg, #0B304A 0%, #154B73 50%, #126A54 100%) !important;
- position: relative;
- overflow: hidden;
-}
-
-/* Add a subtle geometric overlay effect to the banner for depth */
-.landing-body .landing-banner::before {
- content: '';
- position: absolute;
- top: -50%;
- left: -50%;
- width: 200%;
- height: 200%;
- background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.03) 0%, transparent 60%);
- opacity: 0.8;
- pointer-events: none;
- animation: rotate-slow 60s linear infinite;
-}
-
-@keyframes rotate-slow {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
-}
-
-/* Typography on Banner */
-.landing-body .landing-banner .landing-banner-content .title {
- color: #FFFFFF !important;
- text-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
- font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
- font-weight: 800 !important;
- letter-spacing: -0.02em;
-}
-
-.landing-body .landing-banner .landing-banner-content h3 {
- color: rgba(255, 255, 255, 0.9) !important;
- font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
- font-weight: 400 !important;
- letter-spacing: 0;
-}
-
-/* Topbar on Landing */
-.landing-body .landing-topbar {
- background: rgba(255, 255, 255, 0.95) !important;
- backdrop-filter: blur(10px);
- border-bottom: 1px solid rgba(11, 48, 74, 0.05);
- box-shadow: 0 4px 30px rgba(0, 0, 0, 0.03);
-}
-
-/* Override Freya's tiny 16px landing logo */
-.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing {
- display: flex !important;
- align-items: center !important;
- gap: 0.75rem !important;
- text-decoration: none !important;
-}
-
-.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing img.unionflow-brand-icon {
- width: 36px !important;
- height: 36px !important;
-}
-
-.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing .unionflow-brand-name {
- font-size: 1.35rem !important;
- letter-spacing: 0.15em !important;
- color: #0B304A !important;
- font-weight: 800 !important;
- font-family: 'Inter', 'Segoe UI', Roboto, sans-serif !important;
-}
-
-.landing-body .landing-topbar .landing-menu > li > a {
- color: #0B304A !important;
- font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
- text-transform: uppercase;
- letter-spacing: 0.05em;
- font-size: 0.75rem !important;
- transition: color 0.3s ease;
-}
-
-.landing-body .landing-topbar .landing-menu > li > a:hover {
- color: #E6C57A !important; /* Premium Gold */
-}
-
-/* Topbar Secondary Button - Premium Hover */
-.landing-body .landing-topbar-right a[href*="dashboard"] {
- border: 2px solid #0B304A !important;
- color: #0B304A !important;
- transition: all 0.3s ease !important;
-}
-
-.landing-body .landing-topbar-right a[href*="dashboard"]:hover {
- background: transparent !important;
- border-color: #E6C57A !important; /* Premium Gold */
- color: #E6C57A !important;
- box-shadow: 0 4px 15px rgba(230, 197, 122, 0.2);
-}
-
-/* Banner CTA Button - Premium Gold */
-.landing-body .landing-banner-content a[href*="dashboard"] {
- background: linear-gradient(135deg, #E6C57A 0%, #D4AF37 100%) !important;
- color: #0B304A !important;
- border: none !important;
- box-shadow: 0 8px 24px rgba(230, 197, 122, 0.4) !important;
- text-transform: uppercase;
- letter-spacing: 0.05em;
-}
-
-.landing-body .landing-banner-content a[href*="dashboard"]:hover {
- transform: translateY(-4px) !important;
- box-shadow: 0 12px 30px rgba(230, 197, 122, 0.6) !important;
-}
-
-/* Feature Cards - Glassmorphism & Shadows */
-.landing-body .landing-features {
- background: transparent !important;
-}
-
-.landing-body .feature-card {
- background: #FFFFFF !important;
- border: 1px solid rgba(11, 48, 74, 0.05) !important;
- box-shadow: 0 10px 40px rgba(0, 0, 0, 0.04) !important;
- border-radius: 20px !important;
- transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.4s ease !important;
-}
-
-.landing-body .feature-card:hover {
- transform: translateY(-12px) !important; /* Increased lift */
- box-shadow: 0 25px 60px rgba(11, 48, 74, 0.12) !important;
-}
-
-.landing-body .feature-card h3 {
- color: #0B304A !important;
- font-weight: 700 !important;
-}
-
-.landing-body .feature-card h5 {
- color: rgba(11, 48, 74, 0.7) !important;
-}
-
-/* Feature Icon numbers styling */
-.landing-body .feature > span {
- color: #E6C57A !important; /* Premium Gold */
- font-weight: 800 !important;
- font-size: 28px !important;
-}
-
-/* Sub-section headings */
-.landing-body .section-header .title {
- color: #0B304A !important;
- font-weight: 800 !important;
-}
-
-.landing-body .section-header h3 {
- color: rgba(11, 48, 74, 0.7) !important;
-}
-
-/* Benefit Icons Scale-up */
-.landing-body .landing-pricing h3 + p + ul {
- margin-top: 1rem !important;
-}
-
-.landing-body .landing-pricing .pi {
- font-size: 1.5rem !important; /* Bumped from 1.25 to 1.5 for presence */
-}
-
-/* Bottom banner trust section */
-.landing-body .landing-pricing > div:last-of-type > div {
- background: linear-gradient(135deg, #0B304A 0%, #126A54 100%) !important;
- border-radius: 24px !important;
- box-shadow: 0 15px 40px rgba(11, 48, 74, 0.2) !important;
-}
-
-/* Final CTA */
-.landing-body .mt-5 > a {
- background: #0B304A !important;
- color: #FFFFFF !important;
- box-shadow: 0 4px 18px rgba(11, 48, 74, 0.3) !important;
-}
-
-.landing-body .mt-5 > a:hover {
- transform: translateY(-3px) !important;
- box-shadow: 0 10px 30px rgba(11, 48, 74, 0.4) !important;
- background: #154B73 !important;
-}
-
-/* Footer styling */
-.landing-body .layout-footer {
- border-top: 1px solid rgba(11, 48, 74, 0.05);
-}
-
-.landing-body .layout-footer .footer-menutitle {
- color: #0B304A !important;
- font-weight: 700;
-}
-
-.landing-body .layout-footer ul > li,
-.landing-body .layout-footer ul > li > a {
- color: rgba(11, 48, 74, 0.6) !important;
-}
-
-.landing-body .layout-footer ul > li > a:hover {
- color: #126A54 !important;
-}
-
-@media (max-width: 991px) {
- .unionflow-brand--landing .unionflow-brand-icon {
- width: 32px;
- height: 32px;
- }
-
- .unionflow-brand--landing .unionflow-brand-name {
- font-size: 1.1rem;
- }
-}
-
-/* ──────────────────────────────────────────────────
- 10. EXCEPTION PAGES — 404, Access Denied, Error
- ────────────────────────────────────────────────── */
-
-.exception-body .exception-topbar .unionflow-brand-icon {
- width: 38px;
- height: 38px;
-}
-
-.exception-body .exception-topbar .unionflow-brand-name {
- color: #0B304A;
-}
-
-.exception-body .exception-topbar .unionflow-brand-slogan {
- color: #126A54;
-}
-
-/* ──────────────────────────────────────────────────
- 11. RESPONSIVE BREAKPOINTS
- ────────────────────────────────────────────────── */
-
-@media (max-width: 991px) {
- /* On tablets: smaller icon, keep text */
- .unionflow-brand-icon {
- width: 30px;
- height: 30px;
- }
-
- .unionflow-brand-name {
- font-size: 1rem;
- }
-
- .unionflow-brand-slogan {
- font-size: 0.5rem;
- }
-}
-
-@media (max-width: 768px) {
- /* On small tablets: hide text, only icon */
- .unionflow-brand-text {
- display: none;
- }
-
- .unionflow-brand-icon {
- width: 30px;
- height: 30px;
- }
-}
-
-@media (max-width: 576px) {
- /* On phones: even smaller icon */
- .unionflow-brand-icon {
- width: 26px;
- height: 26px;
- }
-
- .unionflow-brand--landing .unionflow-brand-icon {
- width: 32px;
- height: 32px;
- }
-
- /* Still show name on landing for brand recognition */
- .unionflow-brand--landing .unionflow-brand-text {
- display: flex;
- }
-
- .unionflow-brand--landing .unionflow-brand-name {
- font-size: 1.1rem;
- }
-}
+/*
+ * ╔════════════════════════════════════════════════════════════╗
+ * ║ UnionFlow Elite Topbar Styles (Freya Design System) ║
+ * ║ Modern, Professional, Responsive ║
+ * ╚════════════════════════════════════════════════════════════╝
+ */
+
+/* ═══════════════════════════════════════════════════════════ */
+/* BASE TOPBAR */
+/* ═══════════════════════════════════════════════════════════ */
+
+.unionflow-elite {
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-600) 100%);
+ box-shadow: 0 2px 12px rgba(0,0,0,0.08);
+ position: relative;
+ z-index: 1000;
+}
+
+.unionflow-elite::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: linear-gradient(90deg,
+ transparent 0%,
+ var(--primary-300) 50%,
+ transparent 100%);
+ opacity: 0.5;
+}
+
+/* App Version Badge */
+.app-version {
+ display: inline-flex;
+ align-items: center;
+ padding: 0.25rem 0.625rem;
+ background: rgba(255,255,255,0.15);
+ border-radius: 12px;
+ font-size: 0.75rem;
+ font-weight: 600;
+ color: rgba(255,255,255,0.9);
+ margin-left: 0.75rem;
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255,255,255,0.2);
+}
+
+/* ═══════════════════════════════════════════════════════════ */
+/* SEARCH */
+/* ═══════════════════════════════════════════════════════════ */
+
+.search-item .topbar-icon {
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.search-item:hover .topbar-icon {
+ transform: scale(1.1);
+ color: var(--primary-100);
+}
+
+.search-dropdown {
+ position: absolute;
+ top: calc(100% + 0.5rem);
+ right: 0;
+ min-width: 400px;
+ background: white;
+ border-radius: 12px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.12);
+ padding: 1rem;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(-10px);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ border: 1px solid var(--surface-border);
+}
+
+.search-item:hover .search-dropdown {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.search-wrapper-elite {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ background: var(--surface-50);
+ border-radius: 8px;
+ padding: 0.5rem 1rem;
+ border: 1px solid var(--surface-border);
+ transition: all 0.3s ease;
+}
+
+.search-wrapper-elite:focus-within {
+ background: white;
+ border-color: var(--primary-color);
+ box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.1);
+}
+
+.search-wrapper-elite .pi-search {
+ color: var(--text-color-secondary);
+ font-size: 1rem;
+}
+
+.search-wrapper-elite .search-input {
+ flex: 1;
+ border: none;
+ background: transparent;
+ padding: 0.5rem 0;
+ font-size: 0.875rem;
+}
+
+.search-wrapper-elite .search-input:focus {
+ outline: none;
+ box-shadow: none;
+}
+
+/* ═══════════════════════════════════════════════════════════ */
+/* NOTIFICATIONS */
+/* ═══════════════════════════════════════════════════════════ */
+
+.notifications-item {
+ position: relative;
+}
+
+.badge-count {
+ position: absolute;
+ top: -4px;
+ right: -4px;
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
+ color: white;
+ font-size: 0.625rem;
+ font-weight: 700;
+ padding: 0.125rem 0.375rem;
+ border-radius: 10px;
+ min-width: 18px;
+ height: 18px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 2px 8px rgba(239, 68, 68, 0.4);
+ animation: pulse-badge 2s infinite;
+}
+
+@keyframes pulse-badge {
+ 0%, 100% { transform: scale(1); }
+ 50% { transform: scale(1.1); }
+}
+
+.notifications-dropdown {
+ position: absolute;
+ top: calc(100% + 0.5rem);
+ right: 0;
+ min-width: 360px;
+ max-width: 400px;
+ background: white;
+ border-radius: 12px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.12);
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(-10px);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ border: 1px solid var(--surface-border);
+ overflow: hidden;
+}
+
+.notifications-item:hover .notifications-dropdown {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.notif-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 1rem 1.25rem;
+ background: var(--surface-50);
+ border-bottom: 1px solid var(--surface-border);
+}
+
+.count-label {
+ font-size: 0.75rem;
+ color: var(--text-color-secondary);
+ background: var(--primary-color);
+ color: white;
+ padding: 0.25rem 0.625rem;
+ border-radius: 12px;
+ font-weight: 600;
+}
+
+.notif-item {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.875rem;
+ padding: 0.875rem 1.25rem;
+ transition: all 0.2s ease;
+ cursor: pointer;
+}
+
+.notif-item:hover {
+ background: var(--surface-50);
+}
+
+.notif-item i {
+ font-size: 1.25rem;
+ margin-top: 0.25rem;
+}
+
+.notif-title {
+ font-weight: 600;
+ color: var(--text-color);
+ font-size: 0.875rem;
+ margin-bottom: 0.25rem;
+}
+
+.notif-time {
+ font-size: 0.75rem;
+ color: var(--text-color-secondary);
+}
+
+.notif-footer {
+ padding: 0.75rem 1.25rem;
+ text-align: center;
+ border-top: 1px solid var(--surface-border);
+ background: var(--surface-50);
+}
+
+.notif-footer a {
+ font-size: 0.875rem;
+ font-weight: 600;
+ text-decoration: none;
+ transition: color 0.2s ease;
+}
+
+.notif-footer a:hover {
+ color: var(--primary-600);
+}
+
+/* ═══════════════════════════════════════════════════════════ */
+/* USER PROFILE */
+/* ═══════════════════════════════════════════════════════════ */
+
+.elite-user .profile-trigger {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.5rem 0.875rem;
+ border-radius: 10px;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ background: rgba(255,255,255,0.1);
+ backdrop-filter: blur(10px);
+}
+
+.elite-user .profile-trigger:hover {
+ background: rgba(255,255,255,0.2);
+ transform: translateY(-1px);
+}
+
+.avatar-container {
+ position: relative;
+}
+
+.avatar {
+ width: 38px;
+ height: 38px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 0.875rem;
+ font-weight: 700;
+ color: white;
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
+ border: 2px solid rgba(255,255,255,0.3);
+}
+
+.bg-gradient-primary {
+ background: linear-gradient(135deg, var(--primary-400) 0%, var(--primary-600) 100%);
+}
+
+.status-dot {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ border: 2px solid white;
+}
+
+.status-dot.online {
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
+ box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2);
+ animation: pulse-dot 2s infinite;
+}
+
+@keyframes pulse-dot {
+ 0%, 100% { box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2); }
+ 50% { box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.4); }
+}
+
+.user-info {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+}
+
+.user-header {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.user-name {
+ font-size: 0.875rem;
+ font-weight: 600;
+ color: white;
+ line-height: 1.2;
+}
+
+.role-badge {
+ font-size: 0.625rem;
+ padding: 0.125rem 0.5rem;
+ background: rgba(255,255,255,0.25);
+ border-radius: 8px;
+ font-weight: 600;
+ color: white;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.session-timer {
+ display: flex;
+ align-items: center;
+ gap: 0.375rem;
+}
+
+.icon-sm {
+ font-size: 0.7rem;
+}
+
+.timer-text {
+ font-size: 0.75rem;
+ font-weight: 600;
+ font-family: 'Courier New', monospace;
+}
+
+.arrow {
+ font-size: 0.75rem;
+ color: rgba(255,255,255,0.8);
+ transition: transform 0.3s ease;
+}
+
+.elite-user:hover .arrow {
+ transform: rotate(180deg);
+}
+
+/* ═══════════════════════════════════════════════════════════ */
+/* USER DROPDOWN MENU */
+/* ═══════════════════════════════════════════════════════════ */
+
+.elite-dropdown {
+ position: absolute;
+ top: calc(100% + 0.5rem);
+ right: 0;
+ min-width: 340px;
+ background: white;
+ border-radius: 16px;
+ box-shadow: 0 12px 48px rgba(0,0,0,0.15);
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(-10px) scale(0.95);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ border: 1px solid var(--surface-border);
+ overflow: hidden;
+}
+
+.elite-user:hover .elite-dropdown {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0) scale(1);
+}
+
+/* Dropdown Header */
+.dropdown-header {
+ padding: 1.25rem;
+ background: linear-gradient(135deg, var(--primary-50) 0%, var(--surface-50) 100%);
+ border-bottom: 1px solid var(--surface-border);
+}
+
+.header-content {
+ display: flex;
+ gap: 1rem;
+}
+
+.header-avatar {
+ position: relative;
+}
+
+.avatar-lg {
+ width: 56px;
+ height: 56px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.25rem;
+ font-weight: 700;
+ color: white;
+ box-shadow: 0 6px 16px rgba(0,0,0,0.15);
+}
+
+.status-indicator {
+ position: absolute;
+ bottom: 2px;
+ right: 2px;
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ border: 3px solid white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.status-indicator.online {
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
+}
+
+.status-indicator i {
+ font-size: 6px;
+ color: white;
+}
+
+.header-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+ justify-content: center;
+}
+
+.header-info .name {
+ font-size: 1rem;
+ font-weight: 700;
+ color: var(--text-color);
+ line-height: 1.3;
+}
+
+.header-info .email {
+ font-size: 0.75rem;
+ color: var(--text-color-secondary);
+ line-height: 1.3;
+}
+
+.role-tag {
+ display: inline-flex;
+ align-items: center;
+ font-size: 0.625rem;
+ padding: 0.25rem 0.625rem;
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-600) 100%);
+ color: white;
+ border-radius: 8px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ align-self: flex-start;
+ margin-top: 0.25rem;
+}
+
+/* Session Card */
+.session-card {
+ padding: 1rem 1.25rem;
+ background: var(--surface-50);
+ border-bottom: 1px solid var(--surface-border);
+}
+
+.card-content {
+ display: flex;
+ flex-direction: column;
+ gap: 0.625rem;
+}
+
+.info-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.info-row .label {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 0.75rem;
+ color: var(--text-color-secondary);
+ font-weight: 500;
+}
+
+.info-row .label i {
+ font-size: 0.875rem;
+}
+
+.info-row .value {
+ font-size: 0.875rem;
+ font-weight: 600;
+ color: var(--text-color);
+}
+
+/* Progress Bar */
+.progress-container {
+ margin-top: 0.5rem;
+}
+
+.progress-bar {
+ height: 6px;
+ background: var(--surface-200);
+ border-radius: 10px;
+ overflow: hidden;
+ position: relative;
+}
+
+.progress-fill {
+ height: 100%;
+ background: linear-gradient(90deg, var(--green-400) 0%, var(--green-500) 100%);
+ border-radius: 10px;
+ transition: width 1s ease, background 0.3s ease;
+}
+
+.progress-fill[style*="width: 0%"],
+.progress-fill[style*="width: 1%"],
+.progress-fill[style*="width: 2%"],
+.progress-fill[style*="width: 3%"],
+.progress-fill[style*="width: 4%"],
+.progress-fill[style*="width: 5%"] {
+ background: linear-gradient(90deg, var(--red-400) 0%, var(--red-500) 100%);
+}
+
+.progress-label {
+ font-size: 0.625rem;
+ color: var(--text-color-secondary);
+ margin-top: 0.375rem;
+ text-align: right;
+ font-weight: 500;
+}
+
+/* Menu Sections */
+.divider {
+ height: 1px;
+ background: var(--surface-border);
+ margin: 0;
+}
+
+.menu-section {
+ padding: 0.75rem 0;
+}
+
+.menu-section.compact {
+ padding: 0.5rem 0;
+}
+
+.section-title {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 0.75rem;
+ font-weight: 700;
+ color: var(--text-color-secondary);
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ padding: 0.5rem 1.25rem 0.75rem;
+}
+
+.section-items {
+ display: flex;
+ flex-direction: column;
+}
+
+.menu-item {
+ display: flex;
+ align-items: center;
+ gap: 0.875rem;
+ padding: 0.75rem 1.25rem;
+ color: var(--text-color);
+ text-decoration: none;
+ transition: all 0.2s ease;
+ font-size: 0.875rem;
+ cursor: pointer;
+ border: none;
+ background: transparent;
+ width: 100%;
+ text-align: left;
+}
+
+.menu-item:hover {
+ background: var(--surface-100);
+}
+
+.menu-item i:first-child {
+ font-size: 1rem;
+ color: var(--text-color-secondary);
+ transition: all 0.2s ease;
+}
+
+.menu-item:hover i:first-child {
+ color: var(--primary-color);
+ transform: translateX(2px);
+}
+
+.menu-item span {
+ flex: 1;
+ font-weight: 500;
+}
+
+.arrow-right {
+ font-size: 0.75rem;
+ color: var(--text-color-secondary);
+ margin-left: auto;
+ transition: transform 0.2s ease;
+}
+
+.menu-item:hover .arrow-right {
+ transform: translateX(3px);
+}
+
+.item-badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 20px;
+ height: 20px;
+ padding: 0 0.375rem;
+ background: var(--primary-color);
+ color: white;
+ font-size: 0.625rem;
+ font-weight: 700;
+ border-radius: 10px;
+ margin-left: auto;
+}
+
+.value-badge {
+ font-size: 0.75rem;
+ color: var(--text-color-secondary);
+ background: var(--surface-100);
+ padding: 0.25rem 0.625rem;
+ border-radius: 8px;
+ font-weight: 600;
+ margin-left: auto;
+}
+
+/* Logout Section */
+.logout-divider {
+ background: linear-gradient(90deg,
+ transparent 0%,
+ var(--red-200) 50%,
+ transparent 100%);
+ height: 2px;
+}
+
+.logout-section {
+ padding: 0.75rem 0;
+ background: linear-gradient(to bottom, white 0%, var(--red-50) 100%);
+}
+
+.logout-btn {
+ display: flex;
+ align-items: center;
+ gap: 0.875rem;
+ padding: 0.875rem 1.25rem;
+ color: var(--red-600);
+ font-weight: 600;
+ font-size: 0.875rem;
+ text-decoration: none;
+ transition: all 0.3s ease;
+ cursor: pointer;
+ border: none;
+ background: transparent;
+ width: 100%;
+ text-align: left;
+}
+
+.logout-btn:hover {
+ background: var(--red-100);
+ color: var(--red-700);
+}
+
+.logout-btn i:first-child {
+ font-size: 1rem;
+ transition: transform 0.3s ease;
+}
+
+.logout-btn:hover i:first-child {
+ transform: scale(1.1) rotate(-10deg);
+}
+
+.logout-btn .pi-lock {
+ font-size: 0.875rem;
+}
+
+/* ═══════════════════════════════════════════════════════════ */
+/* LOGOUT DIALOG */
+/* ═══════════════════════════════════════════════════════════ */
+
+.elite-dialog .dialog-content {
+ text-align: center;
+ padding: 1.5rem 1rem;
+}
+
+.icon-wrapper {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 80px;
+ height: 80px;
+ border-radius: 50%;
+ background: linear-gradient(135deg, var(--red-50) 0%, var(--red-100) 100%);
+ margin-bottom: 1.5rem;
+}
+
+.icon-lg {
+ font-size: 2.5rem;
+ color: var(--red-500);
+}
+
+.dialog-title {
+ font-size: 1.25rem;
+ font-weight: 700;
+ color: var(--text-color);
+ margin-bottom: 1.5rem;
+ line-height: 1.4;
+}
+
+.info-box {
+ background: var(--surface-50);
+ border-radius: 12px;
+ padding: 1rem;
+ margin-bottom: 1rem;
+ border: 1px solid var(--surface-border);
+}
+
+.info-item {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.625rem;
+ color: var(--text-color);
+ font-size: 0.875rem;
+}
+
+.info-item i {
+ color: var(--primary-color);
+ font-size: 1rem;
+}
+
+.warning-text {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ font-size: 0.875rem;
+ color: var(--text-color-secondary);
+ margin: 0;
+}
+
+.warning-text i {
+ color: var(--blue-500);
+}
+
+.dialog-footer {
+ display: flex;
+ gap: 0.75rem;
+ justify-content: flex-end;
+ padding-top: 1rem;
+}
+
+/* ═══════════════════════════════════════════════════════════ */
+/* UTILITY CLASSES */
+/* ═══════════════════════════════════════════════════════════ */
+
+.text-green-600 { color: #059669 !important; }
+.text-yellow-600 { color: #d97706 !important; }
+.text-orange-600 { color: #ea580c !important; }
+.text-red-600 { color: #dc2626 !important; }
+
+/* ═══════════════════════════════════════════════════════════ */
+/* RESPONSIVE */
+/* ═══════════════════════════════════════════════════════════ */
+
+@media (max-width: 768px) {
+ .app-version { display: none; }
+ .user-info { display: none; }
+ .elite-dropdown { min-width: 300px; }
+ .search-dropdown { min-width: 280px; }
+ .org-switcher-label { display: none; }
+}
+
+/* ═══════════════════════════════════════════════════════════ */
+/* ORG SWITCHER */
+/* ═══════════════════════════════════════════════════════════ */
+
+.org-switcher-item {
+ position: relative;
+}
+
+.org-switcher-trigger {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.4rem 0.75rem;
+ border-radius: 8px;
+ background: rgba(var(--primary-color-rgb, 99,102,241), 0.08);
+ border: 1px solid rgba(var(--primary-color-rgb, 99,102,241), 0.2);
+ color: var(--text-color, #374151);
+ font-size: 0.875rem;
+ font-weight: 500;
+ cursor: pointer;
+ text-decoration: none;
+ transition: background 0.2s, border-color 0.2s;
+ max-width: 220px;
+}
+
+.org-switcher-trigger:hover {
+ background: rgba(var(--primary-color-rgb, 99,102,241), 0.15);
+ border-color: var(--primary-color, #6366f1);
+ text-decoration: none;
+}
+
+.org-switcher-label {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ max-width: 160px;
+}
+
+.org-switcher-dropdown {
+ display: none;
+ position: absolute;
+ top: calc(100% + 8px);
+ left: 0;
+ min-width: 280px;
+ background: var(--surface-card, #fff);
+ border: 1px solid var(--surface-border, #e5e7eb);
+ border-radius: 12px;
+ box-shadow: 0 10px 40px rgba(0,0,0,0.12);
+ z-index: 1000;
+ padding: 0.5rem 0;
+ list-style: none;
+ margin: 0;
+}
+
+.org-switcher-item:hover .org-switcher-dropdown,
+.org-switcher-item:focus-within .org-switcher-dropdown {
+ display: block;
+}
+
+.org-item {
+ padding: 0;
+}
+
+.org-item-link {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.6rem 1rem;
+ cursor: pointer;
+ text-decoration: none;
+ color: var(--text-color, #374151);
+ transition: background 0.15s;
+}
+
+.org-item-link:hover {
+ background: var(--surface-hover, #f9fafb);
+}
+
+.org-item-active .org-item-link {
+ background: rgba(var(--primary-color-rgb, 99,102,241), 0.06);
+}
+
+.org-item-content {
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
+}
+
+.org-item-name {
+ font-weight: 600;
+ font-size: 0.875rem;
+ color: var(--text-color, #111827);
+}
+
+.org-item-meta {
+ display: flex;
+ gap: 0.4rem;
+}
+
+.org-type-badge {
+ font-size: 0.7rem;
+ background: var(--surface-ground, #f3f4f6);
+ color: var(--text-color-secondary, #6b7280);
+ padding: 0.1rem 0.4rem;
+ border-radius: 4px;
+}
+
+.org-role-badge {
+ font-size: 0.7rem;
+ background: #ecfdf5;
+ color: #065f46;
+ padding: 0.1rem 0.4rem;
+ border-radius: 4px;
+}
+
+.org-check-icon {
+ color: var(--primary-color, #6366f1);
+ font-size: 0.875rem;
+}
+
+/* ═══════════════════════════════════════════════════════════════════ */
+/* UNIONFLOW BRAND IDENTITY — EXHAUSTIVE DARK/LIGHT MODE SUPPORT */
+/* Charte: #0B304A (Bleu Nuit), #126A54 (Vert Forêt), */
+/* #E6C57A (Or Premium), #F4F6F8 (Fond), #E8EAEC */
+/* */
+/* Freya theme axes: */
+/* 1. topbarTheme → .layout-topbar-light | .layout-topbar-dark */
+/* 2. menuTheme → .layout-menu-light | .layout-menu-dark */
+/* 3. darkMode → layout-light.css | layout-dark.css */
+/* 4. menuMode → .layout-sidebar | .layout-static */
+/* .layout-horizontal | .layout-slim */
+/* ═══════════════════════════════════════════════════════════════════ */
+
+/* ──────────────────────────────────────────────────
+ 1. BASE — Brand Composition (Logo + Text)
+ Now uses .unionflow-topbar-brand (outside of
+ .layout-topbar-logo to avoid Freya display:none)
+ ────────────────────────────────────────────────── */
+
+.unionflow-topbar-brand,
+.unionflow-brand {
+ display: flex !important;
+ align-items: center;
+ gap: 0.625rem;
+ text-decoration: none !important;
+ height: auto !important;
+}
+
+.unionflow-brand-icon {
+ width: 36px;
+ height: 36px;
+ object-fit: contain;
+ flex-shrink: 0;
+ border-radius: 4px;
+ transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.unionflow-topbar-brand:hover .unionflow-brand-icon,
+.unionflow-brand:hover .unionflow-brand-icon {
+ transform: scale(1.05) rotate(-2deg);
+}
+
+.unionflow-brand-text {
+ display: flex;
+ flex-direction: column;
+ line-height: 1;
+ gap: 0.1875rem;
+}
+
+.unionflow-brand-name {
+ font-size: 1.125rem;
+ font-weight: 800;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
+ transition: color 0.2s ease;
+}
+
+.unionflow-brand-slogan {
+ font-size: 0.5625rem;
+ font-weight: 600;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
+ transition: color 0.2s ease;
+}
+
+/* ──────────────────────────────────────────────────
+ 2. TOPBAR — Dark mode (default: gradient/dark bg)
+ Classes: .layout-topbar-dark, .unionflow-elite
+ ────────────────────────────────────────────────── */
+
+.layout-topbar-dark .unionflow-brand-name,
+.unionflow-elite .unionflow-brand-name {
+ color: #FFFFFF;
+}
+
+.layout-topbar-dark .unionflow-brand-slogan,
+.unionflow-elite .unionflow-brand-slogan {
+ color: rgba(230, 197, 122, 0.9); /* Or Premium #E6C57A */
+}
+
+/* ──────────────────────────────────────────────────
+ 3. TOPBAR — Light mode (white bg)
+ Class: .layout-topbar-light
+ ────────────────────────────────────────────────── */
+
+.layout-topbar-light .unionflow-brand-name {
+ color: #0B304A; /* Bleu Nuit */
+}
+
+.layout-topbar-light .unionflow-brand-slogan {
+ color: #126A54; /* Vert Forêt */
+}
+
+/* ──────────────────────────────────────────────────
+ 4. SIDEBAR BRAND — Single source of branding
+ Collapsed (62px): icon only
+ Expanded (230px): icon + UNIONFLOW + slogan + v1.0
+ ────────────────────────────────────────────────── */
+
+/* --- Logo link container --- */
+.sidebar-logo-link {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ text-decoration: none !important;
+ overflow: hidden;
+ flex: 1;
+ min-width: 0;
+}
+
+.sidebar-logo-link:hover .unionflow-sidebar-icon {
+ transform: scale(1.08);
+}
+
+/* --- Icon (always visible — 24px for visual parity with menu icons) --- */
+.unionflow-sidebar-icon {
+ width: 24px !important;
+ height: 24px !important;
+ object-fit: contain;
+ border-radius: 3px;
+ border: 0 none !important;
+ flex-shrink: 0;
+ transition: all 0.2s ease;
+}
+
+/* Override Freya's .menu-wrapper .sidebar-logo img { width:17px; height:20px } */
+.menu-wrapper .sidebar-logo .unionflow-sidebar-icon {
+ width: 24px !important;
+ height: 24px !important;
+}
+
+/* --- Text block (hidden when collapsed) --- */
+.unionflow-sidebar-text {
+ display: flex;
+ flex-direction: column;
+ line-height: 1;
+ gap: 0.125rem;
+ white-space: nowrap;
+ overflow: hidden;
+ visibility: hidden;
+ opacity: 0;
+ width: 0;
+ transition: opacity 0.2s ease, visibility 0.2s ease;
+}
+
+.unionflow-sidebar-name {
+ font-size: 0.9375rem;
+ font-weight: 800;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
+}
+
+.unionflow-sidebar-slogan {
+ font-size: 0.5rem;
+ font-weight: 600;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
+ opacity: 0.7;
+}
+
+/* --- Version badge (hidden when collapsed) --- */
+.unionflow-sidebar-version {
+ display: inline-flex;
+ align-items: center;
+ padding: 0;
+ border-radius: 8px;
+ font-size: 0.625rem;
+ font-weight: 600;
+ white-space: nowrap;
+ visibility: hidden;
+ opacity: 0;
+ width: 0;
+ overflow: hidden;
+ transition: opacity 0.2s ease, visibility 0.2s ease;
+}
+
+/* ──────────────────────────────────────────────────
+ 4b. SIDEBAR EXPANDED — Show full brand
+ Triggered by: layout-static, layout-sidebar-active (hover)
+ ────────────────────────────────────────────────── */
+
+@media (min-width: 992px) {
+ /* Expanded: icon grows slightly */
+ .layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-icon,
+ .menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-icon {
+ width: 30px !important;
+ height: 30px !important;
+ }
+
+ /* Expanded: show text */
+ .layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-text,
+ .menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-text {
+ visibility: visible;
+ opacity: 1;
+ width: auto;
+ }
+
+ /* Expanded: show version badge */
+ .layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-version,
+ .menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-version {
+ visibility: visible;
+ opacity: 1;
+ width: auto;
+ padding: 0.125rem 0.4rem;
+ }
+}
+
+/* ──────────────────────────────────────────────────
+ 5. SIDEBAR — Menu Dark theme
+ Class: .layout-menu-dark (menu bg = #293241)
+ ────────────────────────────────────────────────── */
+
+.layout-menu-dark .unionflow-sidebar-name {
+ color: #FFFFFF;
+}
+
+.layout-menu-dark .unionflow-sidebar-slogan {
+ color: rgba(230, 197, 122, 0.85); /* Or Premium */
+}
+
+.layout-menu-dark .unionflow-sidebar-version {
+ background: rgba(255, 255, 255, 0.15);
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.layout-menu-dark .sidebar-logo-link {
+ color: #E9E9E9;
+}
+
+/* ──────────────────────────────────────────────────
+ 6. SIDEBAR — Menu Light theme
+ Class: .layout-menu-light (menu bg = white)
+ ────────────────────────────────────────────────── */
+
+.layout-menu-light .unionflow-sidebar-name {
+ color: #0B304A; /* Bleu Nuit */
+}
+
+.layout-menu-light .unionflow-sidebar-slogan {
+ color: #126A54; /* Vert Forêt */
+}
+
+.layout-menu-light .unionflow-sidebar-version {
+ background: rgba(11, 48, 74, 0.1);
+ color: #0B304A;
+}
+
+.layout-menu-light .sidebar-logo-link {
+ color: #0B304A;
+}
+
+/* ──────────────────────────────────────────────────
+ 9. LANDING PAGE — Variant Premium Unionflow
+ ────────────────────────────────────────────────── */
+
+/* App background */
+.landing-body {
+ background-color: #F4F6F8 !important; /* Très léger gris/bleu pour le fond de page */
+}
+
+/* Banner (Hero section) - Deep Blue modern gradient instead of the generic mountain */
+.landing-body .landing-banner {
+ background: linear-gradient(135deg, #0B304A 0%, #154B73 50%, #126A54 100%) !important;
+ position: relative;
+ overflow: hidden;
+}
+
+/* Add a subtle geometric overlay effect to the banner for depth */
+.landing-body .landing-banner::before {
+ content: '';
+ position: absolute;
+ top: -50%;
+ left: -50%;
+ width: 200%;
+ height: 200%;
+ background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.03) 0%, transparent 60%);
+ opacity: 0.8;
+ pointer-events: none;
+ animation: rotate-slow 60s linear infinite;
+}
+
+@keyframes rotate-slow {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+}
+
+/* Typography on Banner */
+.landing-body .landing-banner .landing-banner-content .title {
+ color: #FFFFFF !important;
+ text-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
+ font-weight: 800 !important;
+ letter-spacing: -0.02em;
+}
+
+.landing-body .landing-banner .landing-banner-content h3 {
+ color: rgba(255, 255, 255, 0.9) !important;
+ font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
+ font-weight: 400 !important;
+ letter-spacing: 0;
+}
+
+/* Topbar on Landing */
+.landing-body .landing-topbar {
+ background: rgba(255, 255, 255, 0.95) !important;
+ backdrop-filter: blur(10px);
+ border-bottom: 1px solid rgba(11, 48, 74, 0.05);
+ box-shadow: 0 4px 30px rgba(0, 0, 0, 0.03);
+}
+
+/* Override Freya's tiny 16px landing logo */
+.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing {
+ display: flex !important;
+ align-items: center !important;
+ gap: 0.75rem !important;
+ text-decoration: none !important;
+}
+
+.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing img.unionflow-brand-icon {
+ width: 36px !important;
+ height: 36px !important;
+}
+
+.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing .unionflow-brand-name {
+ font-size: 1.35rem !important;
+ letter-spacing: 0.15em !important;
+ color: #0B304A !important;
+ font-weight: 800 !important;
+ font-family: 'Inter', 'Segoe UI', Roboto, sans-serif !important;
+}
+
+.landing-body .landing-topbar .landing-menu > li > a {
+ color: #0B304A !important;
+ font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ font-size: 0.75rem !important;
+ transition: color 0.3s ease;
+}
+
+.landing-body .landing-topbar .landing-menu > li > a:hover {
+ color: #E6C57A !important; /* Premium Gold */
+}
+
+/* Topbar Secondary Button - Premium Hover */
+.landing-body .landing-topbar-right a[href*="dashboard"] {
+ border: 2px solid #0B304A !important;
+ color: #0B304A !important;
+ transition: all 0.3s ease !important;
+}
+
+.landing-body .landing-topbar-right a[href*="dashboard"]:hover {
+ background: transparent !important;
+ border-color: #E6C57A !important; /* Premium Gold */
+ color: #E6C57A !important;
+ box-shadow: 0 4px 15px rgba(230, 197, 122, 0.2);
+}
+
+/* Banner CTA Button - Premium Gold */
+.landing-body .landing-banner-content a[href*="dashboard"] {
+ background: linear-gradient(135deg, #E6C57A 0%, #D4AF37 100%) !important;
+ color: #0B304A !important;
+ border: none !important;
+ box-shadow: 0 8px 24px rgba(230, 197, 122, 0.4) !important;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.landing-body .landing-banner-content a[href*="dashboard"]:hover {
+ transform: translateY(-4px) !important;
+ box-shadow: 0 12px 30px rgba(230, 197, 122, 0.6) !important;
+}
+
+/* Feature Cards - Glassmorphism & Shadows */
+.landing-body .landing-features {
+ background: transparent !important;
+}
+
+.landing-body .feature-card {
+ background: #FFFFFF !important;
+ border: 1px solid rgba(11, 48, 74, 0.05) !important;
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.04) !important;
+ border-radius: 20px !important;
+ transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.4s ease !important;
+}
+
+.landing-body .feature-card:hover {
+ transform: translateY(-12px) !important; /* Increased lift */
+ box-shadow: 0 25px 60px rgba(11, 48, 74, 0.12) !important;
+}
+
+.landing-body .feature-card h3 {
+ color: #0B304A !important;
+ font-weight: 700 !important;
+}
+
+.landing-body .feature-card h5 {
+ color: rgba(11, 48, 74, 0.7) !important;
+}
+
+/* Feature Icon numbers styling */
+.landing-body .feature > span {
+ color: #E6C57A !important; /* Premium Gold */
+ font-weight: 800 !important;
+ font-size: 28px !important;
+}
+
+/* Sub-section headings */
+.landing-body .section-header .title {
+ color: #0B304A !important;
+ font-weight: 800 !important;
+}
+
+.landing-body .section-header h3 {
+ color: rgba(11, 48, 74, 0.7) !important;
+}
+
+/* Benefit Icons Scale-up */
+.landing-body .landing-pricing h3 + p + ul {
+ margin-top: 1rem !important;
+}
+
+.landing-body .landing-pricing .pi {
+ font-size: 1.5rem !important; /* Bumped from 1.25 to 1.5 for presence */
+}
+
+/* Bottom banner trust section */
+.landing-body .landing-pricing > div:last-of-type > div {
+ background: linear-gradient(135deg, #0B304A 0%, #126A54 100%) !important;
+ border-radius: 24px !important;
+ box-shadow: 0 15px 40px rgba(11, 48, 74, 0.2) !important;
+}
+
+/* Final CTA */
+.landing-body .mt-5 > a {
+ background: #0B304A !important;
+ color: #FFFFFF !important;
+ box-shadow: 0 4px 18px rgba(11, 48, 74, 0.3) !important;
+}
+
+.landing-body .mt-5 > a:hover {
+ transform: translateY(-3px) !important;
+ box-shadow: 0 10px 30px rgba(11, 48, 74, 0.4) !important;
+ background: #154B73 !important;
+}
+
+/* Footer styling */
+.landing-body .layout-footer {
+ border-top: 1px solid rgba(11, 48, 74, 0.05);
+}
+
+.landing-body .layout-footer .footer-menutitle {
+ color: #0B304A !important;
+ font-weight: 700;
+}
+
+.landing-body .layout-footer ul > li,
+.landing-body .layout-footer ul > li > a {
+ color: rgba(11, 48, 74, 0.6) !important;
+}
+
+.landing-body .layout-footer ul > li > a:hover {
+ color: #126A54 !important;
+}
+
+@media (max-width: 991px) {
+ .unionflow-brand--landing .unionflow-brand-icon {
+ width: 32px;
+ height: 32px;
+ }
+
+ .unionflow-brand--landing .unionflow-brand-name {
+ font-size: 1.1rem;
+ }
+}
+
+/* ──────────────────────────────────────────────────
+ 10. EXCEPTION PAGES — 404, Access Denied, Error
+ ────────────────────────────────────────────────── */
+
+.exception-body .exception-topbar .unionflow-brand-icon {
+ width: 38px;
+ height: 38px;
+}
+
+.exception-body .exception-topbar .unionflow-brand-name {
+ color: #0B304A;
+}
+
+.exception-body .exception-topbar .unionflow-brand-slogan {
+ color: #126A54;
+}
+
+/* ──────────────────────────────────────────────────
+ 11. RESPONSIVE BREAKPOINTS
+ ────────────────────────────────────────────────── */
+
+@media (max-width: 991px) {
+ /* On tablets: smaller icon, keep text */
+ .unionflow-brand-icon {
+ width: 30px;
+ height: 30px;
+ }
+
+ .unionflow-brand-name {
+ font-size: 1rem;
+ }
+
+ .unionflow-brand-slogan {
+ font-size: 0.5rem;
+ }
+}
+
+@media (max-width: 768px) {
+ /* On small tablets: hide text, only icon */
+ .unionflow-brand-text {
+ display: none;
+ }
+
+ .unionflow-brand-icon {
+ width: 30px;
+ height: 30px;
+ }
+}
+
+@media (max-width: 576px) {
+ /* On phones: even smaller icon */
+ .unionflow-brand-icon {
+ width: 26px;
+ height: 26px;
+ }
+
+ .unionflow-brand--landing .unionflow-brand-icon {
+ width: 32px;
+ height: 32px;
+ }
+
+ /* Still show name on landing for brand recognition */
+ .unionflow-brand--landing .unionflow-brand-text {
+ display: flex;
+ }
+
+ .unionflow-brand--landing .unionflow-brand-name {
+ font-size: 1.1rem;
+ }
+}
diff --git a/src/main/resources/META-INF/resources/templates/components/buttons/action-button-view.xhtml b/src/main/resources/META-INF/resources/templates/components/buttons/action-button-view.xhtml
index dba9ad8..7564073 100644
--- a/src/main/resources/META-INF/resources/templates/components/buttons/action-button-view.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/buttons/action-button-view.xhtml
@@ -1,22 +1,22 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/buttons/button-form-submit.xhtml b/src/main/resources/META-INF/resources/templates/components/buttons/button-form-submit.xhtml
index 15d38bb..78978d1 100644
--- a/src/main/resources/META-INF/resources/templates/components/buttons/button-form-submit.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/buttons/button-form-submit.xhtml
@@ -1,33 +1,33 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/buttons/button-secondary.xhtml b/src/main/resources/META-INF/resources/templates/components/buttons/button-secondary.xhtml
index 6a36cd4..9f7ab54 100644
--- a/src/main/resources/META-INF/resources/templates/components/buttons/button-secondary.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/buttons/button-secondary.xhtml
@@ -1,65 +1,65 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/buttons/button-success.xhtml b/src/main/resources/META-INF/resources/templates/components/buttons/button-success.xhtml
index bb8ba6c..a16c5a4 100644
--- a/src/main/resources/META-INF/resources/templates/components/buttons/button-success.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/buttons/button-success.xhtml
@@ -1,54 +1,54 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/cards/card-header.xhtml b/src/main/resources/META-INF/resources/templates/components/cards/card-header.xhtml
index ca70d69..3852f86 100644
--- a/src/main/resources/META-INF/resources/templates/components/cards/card-header.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/cards/card-header.xhtml
@@ -1,47 +1,47 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/cards/card-simple.xhtml b/src/main/resources/META-INF/resources/templates/components/cards/card-simple.xhtml
index 313a434..5c4bcf0 100644
--- a/src/main/resources/META-INF/resources/templates/components/cards/card-simple.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/cards/card-simple.xhtml
@@ -1,29 +1,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/cards/filter-bar.xhtml b/src/main/resources/META-INF/resources/templates/components/cards/filter-bar.xhtml
index 8bb1c43..2724e08 100644
--- a/src/main/resources/META-INF/resources/templates/components/cards/filter-bar.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/cards/filter-bar.xhtml
@@ -1,38 +1,38 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/cards/kpi-card.xhtml b/src/main/resources/META-INF/resources/templates/components/cards/kpi-card.xhtml
index 57f2537..0f09ec7 100644
--- a/src/main/resources/META-INF/resources/templates/components/cards/kpi-card.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/cards/kpi-card.xhtml
@@ -1,150 +1,150 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{value}
-
-
-
-
-
-
-
-
#{statusLabel}
-
#{statusValue}
-
-
- Aucun utilisateur actif
-
-
-
-
-
-
-
-
-
- +#{growthValue}
- #{growthLabel}
-
-
- #{noDataLabel}
-
-
-
-
-
-
- +#{growthValue}%
- #{growthLabel}
-
-
- #{noDataLabel}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#{value}
+
+
+
+
+
+
+
+
#{statusLabel}
+
#{statusValue}
+
+
+ Aucun utilisateur actif
+
+
+
+
+
+
+
+
+
+ +#{growthValue}
+ #{growthLabel}
+
+
+ #{noDataLabel}
+
+
+
+
+
+
+ +#{growthValue}%
+ #{growthLabel}
+
+
+ #{noDataLabel}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/cards/stat-card.xhtml b/src/main/resources/META-INF/resources/templates/components/cards/stat-card.xhtml
index d8ab7e3..a601750 100644
--- a/src/main/resources/META-INF/resources/templates/components/cards/stat-card.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/cards/stat-card.xhtml
@@ -1,40 +1,40 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/columns/column-actions.xhtml b/src/main/resources/META-INF/resources/templates/components/columns/column-actions.xhtml
index d769d43..dfaee35 100644
--- a/src/main/resources/META-INF/resources/templates/components/columns/column-actions.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/columns/column-actions.xhtml
@@ -1,25 +1,25 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/columns/column-logo.xhtml b/src/main/resources/META-INF/resources/templates/components/columns/column-logo.xhtml
index ba47b1b..9e84f95 100644
--- a/src/main/resources/META-INF/resources/templates/components/columns/column-logo.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/columns/column-logo.xhtml
@@ -1,25 +1,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/columns/column-name-with-subtitle.xhtml b/src/main/resources/META-INF/resources/templates/components/columns/column-name-with-subtitle.xhtml
index 77bd86c..376648c 100644
--- a/src/main/resources/META-INF/resources/templates/components/columns/column-name-with-subtitle.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/columns/column-name-with-subtitle.xhtml
@@ -1,28 +1,28 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/columns/column-tag.xhtml b/src/main/resources/META-INF/resources/templates/components/columns/column-tag.xhtml
index 9ebf9b0..60e112d 100644
--- a/src/main/resources/META-INF/resources/templates/components/columns/column-tag.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/columns/column-tag.xhtml
@@ -1,28 +1,28 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/columns/column-text-with-icon.xhtml b/src/main/resources/META-INF/resources/templates/components/columns/column-text-with-icon.xhtml
index 0c523d0..a94ce2d 100644
--- a/src/main/resources/META-INF/resources/templates/components/columns/column-text-with-icon.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/columns/column-text-with-icon.xhtml
@@ -1,24 +1,24 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/templates/components/dialogs/confirm-dialog.xhtml b/src/main/resources/META-INF/resources/templates/components/dialogs/confirm-dialog.xhtml
index 7a027c0..57181ea 100644
--- a/src/main/resources/META-INF/resources/templates/components/dialogs/confirm-dialog.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/dialogs/confirm-dialog.xhtml
@@ -1,58 +1,58 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/dialogs/form-dialog.xhtml b/src/main/resources/META-INF/resources/templates/components/dialogs/form-dialog.xhtml
index 423fae9..8cc9015 100644
--- a/src/main/resources/META-INF/resources/templates/components/dialogs/form-dialog.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/dialogs/form-dialog.xhtml
@@ -1,87 +1,87 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/detail-field-row.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/detail-field-row.xhtml
index 3687332..b1371f2 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/detail-field-row.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/detail-field-row.xhtml
@@ -1,26 +1,26 @@
-
-
-
-
-
-
#{label}:
-
- #{value}
- #{suffix}
-
-
-
-
+
+
+
+
+
+
#{label}:
+
+ #{value}
+ #{suffix}
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/detail-field.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/detail-field.xhtml
index 482a116..88a49cc 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/detail-field.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/detail-field.xhtml
@@ -1,29 +1,29 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-autocomplete.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-autocomplete.xhtml
index 30c3201..0dee052 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-autocomplete.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-autocomplete.xhtml
@@ -1,31 +1,31 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-boolean.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-boolean.xhtml
index 2decd31..a488182 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-boolean.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-boolean.xhtml
@@ -1,24 +1,24 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-calendar.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-calendar.xhtml
index a911b5b..5eb507e 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-calendar.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-calendar.xhtml
@@ -1,33 +1,33 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-checkbox-menu.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-checkbox-menu.xhtml
index 92aff32..e381b61 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-checkbox-menu.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-checkbox-menu.xhtml
@@ -1,32 +1,32 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-group.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-group.xhtml
index 9838e9e..14d1400 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-group.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-group.xhtml
@@ -1,21 +1,21 @@
-
-
-
-
-
-
- #{content}
-
-
-
-
-
+
+
+
+
+
+
+ #{content}
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-number.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-number.xhtml
index 15e29a1..bf11eb4 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-number.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-number.xhtml
@@ -1,34 +1,34 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-search-text.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-search-text.xhtml
index 2cb5ff9..82409e8 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-search-text.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-search-text.xhtml
@@ -1,31 +1,31 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-select.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-select.xhtml
index 84d46e2..edbc98a 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-select.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-select.xhtml
@@ -1,51 +1,51 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-text.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-text.xhtml
index 3a83883..4813770 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-text.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-text.xhtml
@@ -1,28 +1,28 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-textarea.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-textarea.xhtml
index 745552c..43f2f52 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-textarea.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-textarea.xhtml
@@ -1,28 +1,28 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-field-wrapper.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-field-wrapper.xhtml
index 5a39d0f..efd7485 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-field-wrapper.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-field-wrapper.xhtml
@@ -1,24 +1,24 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/forms/form-section.xhtml b/src/main/resources/META-INF/resources/templates/components/forms/form-section.xhtml
index 93e4018..bb80164 100644
--- a/src/main/resources/META-INF/resources/templates/components/forms/form-section.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/forms/form-section.xhtml
@@ -1,26 +1,26 @@
-
-
-
-
-
-
- #{title}
-
-
-
-
-
-
+
+
+
+
+
+
+ #{title}
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/layout/config.xhtml b/src/main/resources/META-INF/resources/templates/components/layout/config.xhtml
index ff3460f..9b2e781 100644
--- a/src/main/resources/META-INF/resources/templates/components/layout/config.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/layout/config.xhtml
@@ -1,93 +1,93 @@
-
-
-
-
-
-
-
-
- Type de Menu
-
-
-
-
-
-
-
-
-
- Schéma de Couleur
-
-
-
-
-
-
-
-
- Mode Barre Supérieure et Menu
-
-
-
-
-
-
-
-
-
- Mode Barre Supérieure
-
-
-
-
-
-
-
-
-
- Mode Menu
-
-
-
-
-
-
-
-
-
- Style d'Entrée
-
-
-
-
-
-
-
-
- Couleurs de Thème
-
-
-
+
+
+
+
+
+
+
+
+ Type de Menu
+
+
+
+
+
+
+
+
+
+ Schéma de Couleur
+
+
+
+
+
+
+
+
+ Mode Barre Supérieure et Menu
+
+
+
+
+
+
+
+
+
+ Mode Barre Supérieure
+
+
+
+
+
+
+
+
+
+ Mode Menu
+
+
+
+
+
+
+
+
+
+ Style d'Entrée
+
+
+
+
+
+
+
+
+ Couleurs de Thème
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/templates/components/layout/footer.xhtml b/src/main/resources/META-INF/resources/templates/components/layout/footer.xhtml
index 0520490..d4626f5 100644
--- a/src/main/resources/META-INF/resources/templates/components/layout/footer.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/layout/footer.xhtml
@@ -1,12 +1,12 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/layout/organisation-logo.xhtml b/src/main/resources/META-INF/resources/templates/components/layout/organisation-logo.xhtml
index f8bfde2..7b47742 100644
--- a/src/main/resources/META-INF/resources/templates/components/layout/organisation-logo.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/layout/organisation-logo.xhtml
@@ -1,29 +1,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/layout/page-header.xhtml b/src/main/resources/META-INF/resources/templates/components/layout/page-header.xhtml
index 99c4295..6bde125 100644
--- a/src/main/resources/META-INF/resources/templates/components/layout/page-header.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/layout/page-header.xhtml
@@ -1,38 +1,38 @@
-
-
-
-
-
-
-
-
-
-
-
- #{title}
-
-
#{description}
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ #{title}
+
+
#{description}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/layout/rightpanel.xhtml b/src/main/resources/META-INF/resources/templates/components/layout/rightpanel.xhtml
index cc66f44..702e7b4 100644
--- a/src/main/resources/META-INF/resources/templates/components/layout/rightpanel.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/layout/rightpanel.xhtml
@@ -1,192 +1,192 @@
-
-
-
-
-
-
-
-
-
-
Dakar, #{currentDate}
- 28º
-
-
-
-
-
-
-
-
-
Traiter les demandes d'adhésion en attente
- -Vérifier les dossiers
- -Valider les documents
-
-
-
-
-
Préparer le rapport mensuel
- Statistiques des membres actifs
-
-
-
-
-
Relancer les cotisations en retard
-
-
-
-
-
-
Organiser la réunion mensuelle
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
Vous
-
-
Bonjour, j'ai besoin de votre validation pour les nouvelles adhésions.
-
Il y a 10 min
-
-
-
Merci de vérifier les dossiers 🙏
-
Il y a 5 min
-
-
-
-
Admin
-
-
Parfait, je m'en occupe dans l'heure qui suit.
-
Il y a 2 min
-
-
-
-
Vous
-
-
Excellent, merci beaucoup !
-
Il y a 1 min
-
-
-
-
-
-
-
-
-
-
-
-
-
Aucun message de l'équipe support
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
Dakar, #{currentDate}
+ 28º
+
+
+
+
+
+
+
+
+
Traiter les demandes d'adhésion en attente
+ -Vérifier les dossiers
+ -Valider les documents
+
+
+
+
+
Préparer le rapport mensuel
+ Statistiques des membres actifs
+
+
+
+
+
Relancer les cotisations en retard
+
+
+
+
+
+
Organiser la réunion mensuelle
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
Vous
+
+
Bonjour, j'ai besoin de votre validation pour les nouvelles adhésions.
+
Il y a 10 min
+
+
+
Merci de vérifier les dossiers 🙏
+
Il y a 5 min
+
+
+
+
Admin
+
+
Parfait, je m'en occupe dans l'heure qui suit.
+
Il y a 2 min
+
+
+
+
Vous
+
+
Excellent, merci beaucoup !
+
Il y a 1 min
+
+
+
+
+
+
+
+
+
+
+
+
+
Aucun message de l'équipe support
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/templates/components/layout/topbar.xhtml b/src/main/resources/META-INF/resources/templates/components/layout/topbar.xhtml
index e37f176..8a48c47 100644
--- a/src/main/resources/META-INF/resources/templates/components/layout/topbar.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/layout/topbar.xhtml
@@ -1,368 +1,368 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Êtes-vous sûr de vouloir vous déconnecter ?
-
-
-
-
- #{userSession.currentUser.nomComplet}
-
-
-
- Session: #{sessionMonitor.formattedRemainingTime}
-
-
-
-
-
- Vous devrez vous reconnecter pour accéder à l'application.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Êtes-vous sûr de vouloir vous déconnecter ?
+
+
+
+
+ #{userSession.currentUser.nomComplet}
+
+
+
+ Session: #{sessionMonitor.formattedRemainingTime}
+
+
+
+
+
+ Vous devrez vous reconnecter pour accéder à l'application.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/profile-photo.xhtml b/src/main/resources/META-INF/resources/templates/components/profile-photo.xhtml
index ea75695..3ea5a6b 100644
--- a/src/main/resources/META-INF/resources/templates/components/profile-photo.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/profile-photo.xhtml
@@ -1,41 +1,41 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/security/page-access-control.xhtml b/src/main/resources/META-INF/resources/templates/components/security/page-access-control.xhtml
index e01fa52..c7b6c5e 100644
--- a/src/main/resources/META-INF/resources/templates/components/security/page-access-control.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/security/page-access-control.xhtml
@@ -1,35 +1,35 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/components/tables/data-table.xhtml b/src/main/resources/META-INF/resources/templates/components/tables/data-table.xhtml
index 8550751..a1d4cfe 100644
--- a/src/main/resources/META-INF/resources/templates/components/tables/data-table.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/tables/data-table.xhtml
@@ -1,53 +1,53 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/templates/main-template.xhtml b/src/main/resources/META-INF/resources/templates/main-template.xhtml
index 2905845..e1c60eb 100644
--- a/src/main/resources/META-INF/resources/templates/main-template.xhtml
+++ b/src/main/resources/META-INF/resources/templates/main-template.xhtml
@@ -1,59 +1,59 @@
-
-
-
-
-
-
-
-
-
-
-
-
- UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/templates/public-template.xhtml b/src/main/resources/META-INF/resources/templates/public-template.xhtml
index 5072539..f027d5d 100644
--- a/src/main/resources/META-INF/resources/templates/public-template.xhtml
+++ b/src/main/resources/META-INF/resources/templates/public-template.xhtml
@@ -1,46 +1,46 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UnionFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/ui/includes/membre-dialog-contact.xhtml b/src/main/resources/META-INF/resources/ui/includes/membre-dialog-contact.xhtml
index 0a7cf12..e22112b 100644
--- a/src/main/resources/META-INF/resources/ui/includes/membre-dialog-contact.xhtml
+++ b/src/main/resources/META-INF/resources/ui/includes/membre-dialog-contact.xhtml
@@ -1,40 +1,40 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/ui/includes/membre-dialog-filtres-avances.xhtml b/src/main/resources/META-INF/resources/ui/includes/membre-dialog-filtres-avances.xhtml
index b000c84..4b81045 100644
--- a/src/main/resources/META-INF/resources/ui/includes/membre-dialog-filtres-avances.xhtml
+++ b/src/main/resources/META-INF/resources/ui/includes/membre-dialog-filtres-avances.xhtml
@@ -1,109 +1,109 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/ui/includes/membre-dialog-import-export.xhtml b/src/main/resources/META-INF/resources/ui/includes/membre-dialog-import-export.xhtml
index 2cce65f..accdf69 100644
--- a/src/main/resources/META-INF/resources/ui/includes/membre-dialog-import-export.xhtml
+++ b/src/main/resources/META-INF/resources/ui/includes/membre-dialog-import-export.xhtml
@@ -1,69 +1,69 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/ui/includes/membre-dialog-message-groupe.xhtml b/src/main/resources/META-INF/resources/ui/includes/membre-dialog-message-groupe.xhtml
index 5943619..7628a4c 100644
--- a/src/main/resources/META-INF/resources/ui/includes/membre-dialog-message-groupe.xhtml
+++ b/src/main/resources/META-INF/resources/ui/includes/membre-dialog-message-groupe.xhtml
@@ -1,46 +1,46 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/ui/includes/membre-form.xhtml b/src/main/resources/META-INF/resources/ui/includes/membre-form.xhtml
index 1aaaffe..569dd20 100644
--- a/src/main/resources/META-INF/resources/ui/includes/membre-form.xhtml
+++ b/src/main/resources/META-INF/resources/ui/includes/membre-form.xhtml
@@ -1,174 +1,174 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/ui/includes/organisation-form.xhtml b/src/main/resources/META-INF/resources/ui/includes/organisation-form.xhtml
index 26aeeaa..0b8bd42 100644
--- a/src/main/resources/META-INF/resources/ui/includes/organisation-form.xhtml
+++ b/src/main/resources/META-INF/resources/ui/includes/organisation-form.xhtml
@@ -1,762 +1,762 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/unionflow/calendar.xhtml b/src/main/resources/META-INF/resources/unionflow/calendar.xhtml
index 0015e08..d7c6f7e 100644
--- a/src/main/resources/META-INF/resources/unionflow/calendar.xhtml
+++ b/src/main/resources/META-INF/resources/unionflow/calendar.xhtml
@@ -1,47 +1,47 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/unionflow/inputText.xhtml b/src/main/resources/META-INF/resources/unionflow/inputText.xhtml
index b0edee2..b066002 100644
--- a/src/main/resources/META-INF/resources/unionflow/inputText.xhtml
+++ b/src/main/resources/META-INF/resources/unionflow/inputText.xhtml
@@ -1,40 +1,40 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/resources/unionflow/inputTextarea.xhtml b/src/main/resources/META-INF/resources/unionflow/inputTextarea.xhtml
index aefb06d..e2d9455 100644
--- a/src/main/resources/META-INF/resources/unionflow/inputTextarea.xhtml
+++ b/src/main/resources/META-INF/resources/unionflow/inputTextarea.xhtml
@@ -1,43 +1,43 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/META-INF/unionflow.taglib.xml b/src/main/resources/META-INF/unionflow.taglib.xml
index 2b6331f..0594efa 100644
--- a/src/main/resources/META-INF/unionflow.taglib.xml
+++ b/src/main/resources/META-INF/unionflow.taglib.xml
@@ -1,9 +1,9 @@
-
-
- http://unionflow.lions.dev/jsf
- unionflow
-
+
+
+ http://unionflow.lions.dev/jsf
+ unionflow
+
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 8236e94..eabb483 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -1,38 +1,38 @@
-# Configuration UnionFlow Client - Profil Développement
-# Ce fichier est chargé automatiquement quand le profil 'dev' est actif
-
-# Configuration logging pour développement
-quarkus.log.category."dev.lions.unionflow".level=DEBUG
-
-# Hot reload
-quarkus.live-reload.instrumentation=true
-
-# Configuration Keycloak pour développement LOCAL
-%dev.quarkus.oidc.enabled=true
-
-# Configuration pour Keycloak local sur http://localhost:8180
-%dev.quarkus.oidc.auth-server-url=http://localhost:8180/realms/unionflow
-%dev.quarkus.oidc.client-id=unionflow-client
-
-# SÉCURITÉ: TLS verification désactivée UNIQUEMENT pour Keycloak local HTTP
-# En production, toujours utiliser HTTPS avec tls.verification=required
-%dev.quarkus.oidc.tls.verification=none
-
-%dev.quarkus.oidc.authentication.redirect-path=/auth/callback
-%dev.quarkus.oidc.authentication.restore-path-after-redirect=true
-%dev.quarkus.oidc.authentication.scopes=openid,profile,email,roles
-%dev.quarkus.oidc.token.issuer=any
-
-# Secret Keycloak pour développement
-# SÉCURITÉ: En dev local, on peut utiliser un secret par défaut pour faciliter le développement
-# En production, utilisez TOUJOURS une variable d'environnement
-%dev.quarkus.oidc.credentials.secret=P18Mw0uNVzSPeI4P0fymD18r2oxiejw4
-
-# Configuration Backend pour dev local
-%dev.unionflow.backend.url=http://localhost:8085
-
-# Logging OIDC pour debug
-# INFO pour éviter de bloquer l'event-loop (écritures console DEBUG sur Windows)
-%dev.quarkus.log.category."io.quarkus.oidc".level=INFO
-%dev.quarkus.log.category."io.vertx.ext.auth.oidc".level=INFO
-%dev.quarkus.log.category."io.quarkus.security".level=INFO
+# Configuration UnionFlow Client - Profil Développement
+# Ce fichier est chargé automatiquement quand le profil 'dev' est actif
+
+# Configuration logging pour développement
+quarkus.log.category."dev.lions.unionflow".level=DEBUG
+
+# Hot reload
+quarkus.live-reload.instrumentation=true
+
+# Configuration Keycloak pour développement LOCAL
+%dev.quarkus.oidc.enabled=true
+
+# Configuration pour Keycloak local sur http://localhost:8180
+%dev.quarkus.oidc.auth-server-url=http://localhost:8180/realms/unionflow
+%dev.quarkus.oidc.client-id=unionflow-client
+
+# SÉCURITÉ: TLS verification désactivée UNIQUEMENT pour Keycloak local HTTP
+# En production, toujours utiliser HTTPS avec tls.verification=required
+%dev.quarkus.oidc.tls.verification=none
+
+%dev.quarkus.oidc.authentication.redirect-path=/auth/callback
+%dev.quarkus.oidc.authentication.restore-path-after-redirect=true
+%dev.quarkus.oidc.authentication.scopes=openid,profile,email,roles
+%dev.quarkus.oidc.token.issuer=any
+
+# Secret Keycloak pour développement
+# SÉCURITÉ: En dev local, on peut utiliser un secret par défaut pour faciliter le développement
+# En production, utilisez TOUJOURS une variable d'environnement
+%dev.quarkus.oidc.credentials.secret=P18Mw0uNVzSPeI4P0fymD18r2oxiejw4
+
+# Configuration Backend pour dev local
+%dev.unionflow.backend.url=http://localhost:8085
+
+# Logging OIDC pour debug
+# INFO pour éviter de bloquer l'event-loop (écritures console DEBUG sur Windows)
+%dev.quarkus.log.category."io.quarkus.oidc".level=INFO
+%dev.quarkus.log.category."io.vertx.ext.auth.oidc".level=INFO
+%dev.quarkus.log.category."io.quarkus.security".level=INFO
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index 9145634..6435f72 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -46,7 +46,7 @@ quarkus.http.enable-compression=true
quarkus.http.compression-level=6
# Configuration logging - Production
-quarkus.log.console.enable=true
+quarkus.log.console.enabled=true
quarkus.log.console.level=INFO
quarkus.log.console.format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{2.}] (%t) %s%e%n
quarkus.log.category."dev.lions.unionflow".level=INFO
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 93f51a2..67d56ca 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -11,7 +11,7 @@ quarkus.http.tcp-quick-ack=true
quarkus.http.tcp-cork=true
# Configuration logging
-quarkus.log.console.enable=true
+quarkus.log.console.enabled=true
quarkus.log.console.level=INFO
quarkus.log.console.format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{2.}] (%t) %s%e%n
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index 400a61d..03365ed 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -1,227 +1,227 @@
-
-
-
-
- index.xhtml
- index.html
-
-
-
-
- 60
-
- true
- false
-
- COOKIE
-
-
-
-
- jakarta.faces.STATE_SAVING_METHOD
- server
-
-
- jakarta.faces.PROJECT_STAGE
- Production
-
-
-
-
- org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION
- 50
-
-
- org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION
- 10
-
-
- org.apache.myfaces.SERIALIZE_STATE_IN_SESSION
- false
-
-
- org.apache.myfaces.CLIENT_VIEW_STATE_TIMEOUT
- 3600000
-
-
- org.apache.myfaces.VIEW_EXPIRED_EXCEPTION_HANDLER_REDIRECT_PAGE
- /
-
-
- org.apache.myfaces.CHECK_ID_PRODUCTION_MODE
- false
-
-
- org.apache.myfaces.STRICT_XHTML_LINKS
- false
-
-
- org.apache.myfaces.REFRESH_TRANSIENT_BUILD_ON_PSS
- true
-
-
- org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES
- 604800000
-
-
- org.apache.myfaces.RESOURCE_BUFFER_SIZE
- 2048
-
-
- org.apache.myfaces.AUTOMATIC_EXTENSIONLESS_MAPPING
- false
-
-
-
-
- primefaces.THEME
- none
-
-
- primefaces.FONT_AWESOME
- true
-
-
- primefaces.CLIENT_SIDE_VALIDATION
- true
-
-
- primefaces.MOVE_SCRIPTS_TO_BOTTOM
- true
-
-
- primefaces.CSP
- false
-
-
- primefaces.UPLOADER
- commons
-
-
- primefaces.AUTO_UPDATE
- false
-
-
- primefaces.CACHE_PROVIDER
- org.primefaces.cache.DefaultCacheProvider
-
-
- primefaces.RESOURCE_HANDLER
- org.primefaces.application.resource.PrimeResourceHandler
-
-
- primefaces.LEGACY_WIDGET_NAMESPACE
- false
-
-
-
-
- org.omnifaces.CDN_RESOURCE_HANDLER_DISABLED
- true
-
-
- org.omnifaces.COMBINED_RESOURCE_HANDLER_DISABLED
- false
-
-
-
-
- jakarta.faces.FACELETS_LIBRARIES
- /WEB-INF/primefaces-freya.taglib.xml
-
-
-
-
-
-
- CSP Nonce Filter
- dev.lions.unionflow.client.security.CSPNonceFilter
-
-
- CSP Nonce Filter
- /*
-
-
-
-
-
-
- Faces Servlet
- jakarta.faces.webapp.FacesServlet
- 1
-
-
- Faces Servlet
- *.jsf
-
-
- Faces Servlet
- *.xhtml
-
-
-
-
- ttf
- application/font-sfnt
-
-
- woff
- application/font-woff
-
-
- woff2
- application/font-woff2
-
-
- eot
- application/vnd.ms-fontobject
-
-
- eot?#iefix
- application/vnd.ms-fontobject
-
-
- svg
- image/svg+xml
-
-
- svg#exosemibold
- image/svg+xml
-
-
- svg#exobolditalic
- image/svg+xml
-
-
- svg#exomedium
- image/svg+xml
-
-
- svg#exoregular
- image/svg+xml
-
-
- svg#fontawesomeregular
- image/svg+xml
-
-
+
+
+
+
+ index.xhtml
+ index.html
+
+
+
+
+ 60
+
+ true
+ false
+
+ COOKIE
+
+
+
+
+ jakarta.faces.STATE_SAVING_METHOD
+ server
+
+
+ jakarta.faces.PROJECT_STAGE
+ Production
+
+
+
+
+ org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION
+ 50
+
+
+ org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION
+ 10
+
+
+ org.apache.myfaces.SERIALIZE_STATE_IN_SESSION
+ false
+
+
+ org.apache.myfaces.CLIENT_VIEW_STATE_TIMEOUT
+ 3600000
+
+
+ org.apache.myfaces.VIEW_EXPIRED_EXCEPTION_HANDLER_REDIRECT_PAGE
+ /
+
+
+ org.apache.myfaces.CHECK_ID_PRODUCTION_MODE
+ false
+
+
+ org.apache.myfaces.STRICT_XHTML_LINKS
+ false
+
+
+ org.apache.myfaces.REFRESH_TRANSIENT_BUILD_ON_PSS
+ true
+
+
+ org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES
+ 604800000
+
+
+ org.apache.myfaces.RESOURCE_BUFFER_SIZE
+ 2048
+
+
+ org.apache.myfaces.AUTOMATIC_EXTENSIONLESS_MAPPING
+ false
+
+
+
+
+ primefaces.THEME
+ none
+
+
+ primefaces.FONT_AWESOME
+ true
+
+
+ primefaces.CLIENT_SIDE_VALIDATION
+ true
+
+
+ primefaces.MOVE_SCRIPTS_TO_BOTTOM
+ true
+
+
+ primefaces.CSP
+ false
+
+
+ primefaces.UPLOADER
+ commons
+
+
+ primefaces.AUTO_UPDATE
+ false
+
+
+ primefaces.CACHE_PROVIDER
+ org.primefaces.cache.DefaultCacheProvider
+
+
+ primefaces.RESOURCE_HANDLER
+ org.primefaces.application.resource.PrimeResourceHandler
+
+
+ primefaces.LEGACY_WIDGET_NAMESPACE
+ false
+
+
+
+
+ org.omnifaces.CDN_RESOURCE_HANDLER_DISABLED
+ true
+
+
+ org.omnifaces.COMBINED_RESOURCE_HANDLER_DISABLED
+ false
+
+
+
+
+ jakarta.faces.FACELETS_LIBRARIES
+ /WEB-INF/primefaces-freya.taglib.xml
+
+
+
+
+
+
+ CSP Nonce Filter
+ dev.lions.unionflow.client.security.CSPNonceFilter
+
+
+ CSP Nonce Filter
+ /*
+
+
+
+
+
+
+ Faces Servlet
+ jakarta.faces.webapp.FacesServlet
+ 1
+
+
+ Faces Servlet
+ *.jsf
+
+
+ Faces Servlet
+ *.xhtml
+
+
+
+
+ ttf
+ application/font-sfnt
+
+
+ woff
+ application/font-woff
+
+
+ woff2
+ application/font-woff2
+
+
+ eot
+ application/vnd.ms-fontobject
+
+
+ eot?#iefix
+ application/vnd.ms-fontobject
+
+
+ svg
+ image/svg+xml
+
+
+ svg#exosemibold
+ image/svg+xml
+
+
+ svg#exobolditalic
+ image/svg+xml
+
+
+ svg#exomedium
+ image/svg+xml
+
+
+ svg#exoregular
+ image/svg+xml
+
+
+ svg#fontawesomeregular
+ image/svg+xml
+
+
diff --git a/src/test/java/dev/lions/unionflow/client/validation/MemberNumberValidatorTest.java b/src/test/java/dev/lions/unionflow/client/validation/MemberNumberValidatorTest.java
index c32b426..95e77d1 100644
--- a/src/test/java/dev/lions/unionflow/client/validation/MemberNumberValidatorTest.java
+++ b/src/test/java/dev/lions/unionflow/client/validation/MemberNumberValidatorTest.java
@@ -1,145 +1,145 @@
-package dev.lions.unionflow.client.validation;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.DisplayName;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * Tests unitaires pour MemberNumberValidator
- *
- * Couverture: 100%
- * @author UnionFlow Team
- * @version 1.0
- */
-@DisplayName("MemberNumberValidator Tests")
-class MemberNumberValidatorTest {
-
- private MemberNumberValidator validator;
-
- @BeforeEach
- void setUp() {
- validator = new MemberNumberValidator();
- }
-
- @Test
- @DisplayName("Should accept valid member number with current year")
- void shouldAcceptValidMemberNumberCurrentYear() {
- String validNumber = "M2025123456";
- assertTrue(validator.isValid(validNumber, null),
- "Valid member number with current year should be accepted");
- }
-
- @Test
- @DisplayName("Should accept valid member number with year 2020")
- void shouldAcceptValidMemberNumberYear2020() {
- String validNumber = "M2020123456";
- assertTrue(validator.isValid(validNumber, null),
- "Valid member number from 2020 should be accepted");
- }
-
- @Test
- @DisplayName("Should accept valid member number with next year")
- void shouldAcceptValidMemberNumberNextYear() {
- int nextYear = java.time.LocalDate.now().getYear() + 1;
- String validNumber = "M" + nextYear + "123456";
- assertTrue(validator.isValid(validNumber, null),
- "Valid member number with next year should be accepted");
- }
-
- @Test
- @DisplayName("Should reject null member number")
- void shouldRejectNullMemberNumber() {
- assertFalse(validator.isValid(null, null),
- "Null member number should be rejected");
- }
-
- @Test
- @DisplayName("Should reject empty member number")
- void shouldRejectEmptyMemberNumber() {
- assertFalse(validator.isValid("", null),
- "Empty member number should be rejected");
- }
-
- @Test
- @DisplayName("Should reject member number with invalid prefix")
- void shouldRejectInvalidPrefix() {
- String invalidNumber = "A2025123456";
- assertFalse(validator.isValid(invalidNumber, null),
- "Member number must start with 'M'");
- }
-
- @Test
- @DisplayName("Should reject member number with year before 2020")
- void shouldRejectYearBefore2020() {
- String invalidNumber = "M2019123456";
- assertFalse(validator.isValid(invalidNumber, null),
- "Member number with year before 2020 should be rejected");
- }
-
- @Test
- @DisplayName("Should reject member number with year too far in future")
- void shouldRejectYearTooFarInFuture() {
- int futureYear = java.time.LocalDate.now().getYear() + 5;
- String invalidNumber = "M" + futureYear + "123456";
- assertFalse(validator.isValid(invalidNumber, null),
- "Member number with year too far in future should be rejected");
- }
-
- @Test
- @DisplayName("Should reject member number with too few digits")
- void shouldRejectTooFewDigits() {
- String invalidNumber = "M202512"; // Moins de 3 chiffres après l'année
- assertFalse(validator.isValid(invalidNumber, null),
- "Member number must have at least 3 digits after year");
- }
-
- @Test
- @DisplayName("Should reject member number with too many digits")
- void shouldRejectTooManyDigits() {
- String invalidNumber = "M20251234567"; // Plus de 6 chiffres après l'année
- assertFalse(validator.isValid(invalidNumber, null),
- "Member number must have at most 6 digits after year");
- }
-
- @Test
- @DisplayName("Should reject member number with letters after year")
- void shouldRejectLettersAfterYear() {
- String invalidNumber = "M2025ABC456";
- assertFalse(validator.isValid(invalidNumber, null),
- "Member number cannot contain letters after year");
- }
-
- @Test
- @DisplayName("Should reject member number with special characters")
- void shouldRejectSpecialCharacters() {
- String invalidNumber = "M2025-12-3456";
- assertFalse(validator.isValid(invalidNumber, null),
- "Member number cannot contain special characters");
- }
-
- @Test
- @DisplayName("Should accept member number with minimum digits")
- void shouldAcceptMinimumDigits() {
- String validNumber = "M2025123"; // Exactement 3 chiffres
- assertTrue(validator.isValid(validNumber, null),
- "Member number with 3 digits should be accepted");
- }
-
- @Test
- @DisplayName("Should accept member number with maximum digits")
- void shouldAcceptMaximumDigits() {
- String validNumber = "M2025123456"; // Exactement 6 chiffres
- assertTrue(validator.isValid(validNumber, null),
- "Member number with 6 digits should be accepted");
- }
-
- @Test
- @DisplayName("Should be case sensitive for prefix")
- void shouldBeCaseSensitiveForPrefix() {
- String lowerCaseNumber = "m2025123456";
- assertFalse(validator.isValid(lowerCaseNumber, null),
- "Member number prefix must be uppercase 'M'");
- }
-}
+package dev.lions.unionflow.client.validation;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.DisplayName;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests unitaires pour MemberNumberValidator
+ *
+ * Couverture: 100%
+ * @author UnionFlow Team
+ * @version 1.0
+ */
+@DisplayName("MemberNumberValidator Tests")
+class MemberNumberValidatorTest {
+
+ private MemberNumberValidator validator;
+
+ @BeforeEach
+ void setUp() {
+ validator = new MemberNumberValidator();
+ }
+
+ @Test
+ @DisplayName("Should accept valid member number with current year")
+ void shouldAcceptValidMemberNumberCurrentYear() {
+ String validNumber = "M2025123456";
+ assertTrue(validator.isValid(validNumber, null),
+ "Valid member number with current year should be accepted");
+ }
+
+ @Test
+ @DisplayName("Should accept valid member number with year 2020")
+ void shouldAcceptValidMemberNumberYear2020() {
+ String validNumber = "M2020123456";
+ assertTrue(validator.isValid(validNumber, null),
+ "Valid member number from 2020 should be accepted");
+ }
+
+ @Test
+ @DisplayName("Should accept valid member number with next year")
+ void shouldAcceptValidMemberNumberNextYear() {
+ int nextYear = java.time.LocalDate.now().getYear() + 1;
+ String validNumber = "M" + nextYear + "123456";
+ assertTrue(validator.isValid(validNumber, null),
+ "Valid member number with next year should be accepted");
+ }
+
+ @Test
+ @DisplayName("Should reject null member number")
+ void shouldRejectNullMemberNumber() {
+ assertFalse(validator.isValid(null, null),
+ "Null member number should be rejected");
+ }
+
+ @Test
+ @DisplayName("Should reject empty member number")
+ void shouldRejectEmptyMemberNumber() {
+ assertFalse(validator.isValid("", null),
+ "Empty member number should be rejected");
+ }
+
+ @Test
+ @DisplayName("Should reject member number with invalid prefix")
+ void shouldRejectInvalidPrefix() {
+ String invalidNumber = "A2025123456";
+ assertFalse(validator.isValid(invalidNumber, null),
+ "Member number must start with 'M'");
+ }
+
+ @Test
+ @DisplayName("Should reject member number with year before 2020")
+ void shouldRejectYearBefore2020() {
+ String invalidNumber = "M2019123456";
+ assertFalse(validator.isValid(invalidNumber, null),
+ "Member number with year before 2020 should be rejected");
+ }
+
+ @Test
+ @DisplayName("Should reject member number with year too far in future")
+ void shouldRejectYearTooFarInFuture() {
+ int futureYear = java.time.LocalDate.now().getYear() + 5;
+ String invalidNumber = "M" + futureYear + "123456";
+ assertFalse(validator.isValid(invalidNumber, null),
+ "Member number with year too far in future should be rejected");
+ }
+
+ @Test
+ @DisplayName("Should reject member number with too few digits")
+ void shouldRejectTooFewDigits() {
+ String invalidNumber = "M202512"; // Moins de 3 chiffres après l'année
+ assertFalse(validator.isValid(invalidNumber, null),
+ "Member number must have at least 3 digits after year");
+ }
+
+ @Test
+ @DisplayName("Should reject member number with too many digits")
+ void shouldRejectTooManyDigits() {
+ String invalidNumber = "M20251234567"; // Plus de 6 chiffres après l'année
+ assertFalse(validator.isValid(invalidNumber, null),
+ "Member number must have at most 6 digits after year");
+ }
+
+ @Test
+ @DisplayName("Should reject member number with letters after year")
+ void shouldRejectLettersAfterYear() {
+ String invalidNumber = "M2025ABC456";
+ assertFalse(validator.isValid(invalidNumber, null),
+ "Member number cannot contain letters after year");
+ }
+
+ @Test
+ @DisplayName("Should reject member number with special characters")
+ void shouldRejectSpecialCharacters() {
+ String invalidNumber = "M2025-12-3456";
+ assertFalse(validator.isValid(invalidNumber, null),
+ "Member number cannot contain special characters");
+ }
+
+ @Test
+ @DisplayName("Should accept member number with minimum digits")
+ void shouldAcceptMinimumDigits() {
+ String validNumber = "M2025123"; // Exactement 3 chiffres
+ assertTrue(validator.isValid(validNumber, null),
+ "Member number with 3 digits should be accepted");
+ }
+
+ @Test
+ @DisplayName("Should accept member number with maximum digits")
+ void shouldAcceptMaximumDigits() {
+ String validNumber = "M2025123456"; // Exactement 6 chiffres
+ assertTrue(validator.isValid(validNumber, null),
+ "Member number with 6 digits should be accepted");
+ }
+
+ @Test
+ @DisplayName("Should be case sensitive for prefix")
+ void shouldBeCaseSensitiveForPrefix() {
+ String lowerCaseNumber = "m2025123456";
+ assertFalse(validator.isValid(lowerCaseNumber, null),
+ "Member number prefix must be uppercase 'M'");
+ }
+}
diff --git a/start-local.bat b/start-local.bat
index ea2dff8..62d415b 100644
--- a/start-local.bat
+++ b/start-local.bat
@@ -1,97 +1,97 @@
-@echo off
-REM Script de démarrage pour UnionFlow Client - Développement Local (Windows)
-REM Usage: start-local.bat
-
-echo.
-echo ========================================================
-echo 🚀 Démarrage de UnionFlow Client en mode développement
-echo ========================================================
-echo.
-
-REM Vérification Java
-echo 📋 Vérification des prérequis...
-java -version >nul 2>&1
-if errorlevel 1 (
- echo ❌ Java n'est pas installé. Veuillez installer Java 17+
- pause
- exit /b 1
-)
-echo ✅ Java détecté
-
-REM Vérification Maven
-mvn --version >nul 2>&1
-if errorlevel 1 (
- echo ❌ Maven n'est pas installé. Veuillez installer Maven 3.8+
- pause
- exit /b 1
-)
-echo ✅ Maven détecté
-
-REM Vérifier Keycloak
-echo.
-echo 🔍 Vérification de Keycloak sur http://localhost:8180...
-curl -s http://localhost:8180 >nul 2>&1
-if errorlevel 1 (
- echo ⚠️ Keycloak ne répond pas sur http://localhost:8180
- echo Assurez-vous que Keycloak est démarré avant de continuer.
- echo.
- set /p CONTINUE=" Voulez-vous continuer quand même? (y/N) "
- if /i not "%CONTINUE%"=="y" exit /b 1
-) else (
- echo ✅ Keycloak est accessible
-)
-
-REM Vérifier le backend
-echo.
-echo 🔍 Vérification du backend sur http://localhost:8085...
-curl -s http://localhost:8085 >nul 2>&1
-if errorlevel 1 (
- echo ⚠️ Backend ne répond pas sur http://localhost:8085
- echo L'application fonctionnera mais les appels API échoueront.
-) else (
- echo ✅ Backend est accessible
-)
-
-REM Charger .env si présent
-if exist .env (
- echo.
- echo 📄 Chargement des variables d'environnement depuis .env...
- for /f "tokens=*" %%a in (.env) do (
- set "line=%%a"
- setlocal enabledelayedexpansion
- if not "!line:~0,1!"=="#" (
- set "%%a"
- )
- endlocal
- )
- echo ✅ Variables chargées
-) else (
- echo.
- echo ⚠️ Fichier .env non trouvé
- echo Créez un fichier .env depuis .env.example si nécessaire
-)
-
-REM Afficher la configuration
-echo.
-echo ⚙️ Configuration actuelle:
-echo - Port application: 8086
-echo - Keycloak: http://localhost:8180
-echo - Backend: %UNIONFLOW_BACKEND_URL%
-if defined KEYCLOAK_CLIENT_SECRET (
- echo - Client Secret: [défini]
-) else (
- echo - Client Secret: [non défini, utilise valeur par défaut]
-)
-
-REM Démarrer l'application
-echo.
-echo 🚀 Démarrage de l'application...
-echo.
-echo ========================================================
-echo Une fois démarré, accédez à: http://localhost:8086
-echo Pour arrêter: Ctrl+C
-echo ========================================================
-echo.
-
-REM Démarrer avec Quarkus dev mode
-mvnw.cmd quarkus:dev
+@echo off
+REM Script de démarrage pour UnionFlow Client - Développement Local (Windows)
+REM Usage: start-local.bat
+
+echo.
+echo ========================================================
+echo 🚀 Démarrage de UnionFlow Client en mode développement
+echo ========================================================
+echo.
+
+REM Vérification Java
+echo 📋 Vérification des prérequis...
+java -version >nul 2>&1
+if errorlevel 1 (
+ echo ❌ Java n'est pas installé. Veuillez installer Java 17+
+ pause
+ exit /b 1
+)
+echo ✅ Java détecté
+
+REM Vérification Maven
+mvn --version >nul 2>&1
+if errorlevel 1 (
+ echo ❌ Maven n'est pas installé. Veuillez installer Maven 3.8+
+ pause
+ exit /b 1
+)
+echo ✅ Maven détecté
+
+REM Vérifier Keycloak
+echo.
+echo 🔍 Vérification de Keycloak sur http://localhost:8180...
+curl -s http://localhost:8180 >nul 2>&1
+if errorlevel 1 (
+ echo ⚠️ Keycloak ne répond pas sur http://localhost:8180
+ echo Assurez-vous que Keycloak est démarré avant de continuer.
+ echo.
+ set /p CONTINUE=" Voulez-vous continuer quand même? (y/N) "
+ if /i not "%CONTINUE%"=="y" exit /b 1
+) else (
+ echo ✅ Keycloak est accessible
+)
+
+REM Vérifier le backend
+echo.
+echo 🔍 Vérification du backend sur http://localhost:8085...
+curl -s http://localhost:8085 >nul 2>&1
+if errorlevel 1 (
+ echo ⚠️ Backend ne répond pas sur http://localhost:8085
+ echo L'application fonctionnera mais les appels API échoueront.
+) else (
+ echo ✅ Backend est accessible
+)
+
+REM Charger .env si présent
+if exist .env (
+ echo.
+ echo 📄 Chargement des variables d'environnement depuis .env...
+ for /f "tokens=*" %%a in (.env) do (
+ set "line=%%a"
+ setlocal enabledelayedexpansion
+ if not "!line:~0,1!"=="#" (
+ set "%%a"
+ )
+ endlocal
+ )
+ echo ✅ Variables chargées
+) else (
+ echo.
+ echo ⚠️ Fichier .env non trouvé
+ echo Créez un fichier .env depuis .env.example si nécessaire
+)
+
+REM Afficher la configuration
+echo.
+echo ⚙️ Configuration actuelle:
+echo - Port application: 8086
+echo - Keycloak: http://localhost:8180
+echo - Backend: %UNIONFLOW_BACKEND_URL%
+if defined KEYCLOAK_CLIENT_SECRET (
+ echo - Client Secret: [défini]
+) else (
+ echo - Client Secret: [non défini, utilise valeur par défaut]
+)
+
+REM Démarrer l'application
+echo.
+echo 🚀 Démarrage de l'application...
+echo.
+echo ========================================================
+echo Une fois démarré, accédez à: http://localhost:8086
+echo Pour arrêter: Ctrl+C
+echo ========================================================
+echo.
+
+REM Démarrer avec Quarkus dev mode
+mvnw.cmd quarkus:dev
diff --git a/start-local.sh b/start-local.sh
index 99fbca6..04710e4 100644
--- a/start-local.sh
+++ b/start-local.sh
@@ -1,89 +1,89 @@
-#!/bin/bash
-
-# Script de démarrage pour UnionFlow Client - Développement Local
-# Usage: ./start-local.sh
-
-echo "🚀 Démarrage de UnionFlow Client en mode développement local"
-echo "============================================================"
-echo ""
-
-# Vérification des prérequis
-echo "📋 Vérification des prérequis..."
-
-# Vérifier Java
-if ! command -v java &> /dev/null; then
- echo "❌ Java n'est pas installé. Veuillez installer Java 17+"
- exit 1
-fi
-
-JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | cut -d'.' -f1)
-if [ "$JAVA_VERSION" -lt 17 ]; then
- echo "❌ Java 17+ requis. Version actuelle: $JAVA_VERSION"
- exit 1
-fi
-echo "✅ Java $JAVA_VERSION détecté"
-
-# Vérifier Maven
-if ! command -v mvn &> /dev/null; then
- echo "❌ Maven n'est pas installé. Veuillez installer Maven 3.8+"
- exit 1
-fi
-echo "✅ Maven détecté"
-
-# Vérifier Keycloak
-echo ""
-echo "🔍 Vérification de Keycloak sur http://localhost:8180..."
-if curl -s http://localhost:8180 > /dev/null; then
- echo "✅ Keycloak est accessible"
-else
- echo "⚠️ Keycloak ne répond pas sur http://localhost:8180"
- echo " Assurez-vous que Keycloak est démarré avant de continuer."
- read -p " Voulez-vous continuer quand même? (y/N) " -n 1 -r
- echo
- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
- exit 1
- fi
-fi
-
-# Vérifier le backend (optionnel)
-echo ""
-echo "🔍 Vérification du backend sur http://localhost:8085..."
-if curl -s http://localhost:8085 > /dev/null; then
- echo "✅ Backend est accessible"
-else
- echo "⚠️ Backend ne répond pas sur http://localhost:8085"
- echo " L'application fonctionnera mais les appels API échoueront."
-fi
-
-# Charger les variables d'environnement depuis .env si présent
-if [ -f .env ]; then
- echo ""
- echo "📄 Chargement des variables d'environnement depuis .env..."
- export $(cat .env | grep -v '^#' | xargs)
- echo "✅ Variables chargées"
-else
- echo ""
- echo "⚠️ Fichier .env non trouvé"
- echo " Créez un fichier .env depuis .env.example si nécessaire"
-fi
-
-# Afficher la configuration
-echo ""
-echo "⚙️ Configuration actuelle:"
-echo " - Port application: 8086"
-echo " - Keycloak: http://localhost:8180"
-echo " - Backend: ${UNIONFLOW_BACKEND_URL:-http://localhost:8085}"
-echo " - Client Secret: ${KEYCLOAK_CLIENT_SECRET:-[non défini, utilise valeur par défaut]}"
-
-# Démarrer l'application
-echo ""
-echo "🚀 Démarrage de l'application..."
-echo ""
-echo "============================================================"
-echo "Une fois démarré, accédez à: http://localhost:8086"
-echo "Pour arrêter: Ctrl+C"
-echo "============================================================"
-echo ""
-
-# Démarrer avec Quarkus dev mode
-./mvnw quarkus:dev
+#!/bin/bash
+
+# Script de démarrage pour UnionFlow Client - Développement Local
+# Usage: ./start-local.sh
+
+echo "🚀 Démarrage de UnionFlow Client en mode développement local"
+echo "============================================================"
+echo ""
+
+# Vérification des prérequis
+echo "📋 Vérification des prérequis..."
+
+# Vérifier Java
+if ! command -v java &> /dev/null; then
+ echo "❌ Java n'est pas installé. Veuillez installer Java 17+"
+ exit 1
+fi
+
+JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | cut -d'.' -f1)
+if [ "$JAVA_VERSION" -lt 17 ]; then
+ echo "❌ Java 17+ requis. Version actuelle: $JAVA_VERSION"
+ exit 1
+fi
+echo "✅ Java $JAVA_VERSION détecté"
+
+# Vérifier Maven
+if ! command -v mvn &> /dev/null; then
+ echo "❌ Maven n'est pas installé. Veuillez installer Maven 3.8+"
+ exit 1
+fi
+echo "✅ Maven détecté"
+
+# Vérifier Keycloak
+echo ""
+echo "🔍 Vérification de Keycloak sur http://localhost:8180..."
+if curl -s http://localhost:8180 > /dev/null; then
+ echo "✅ Keycloak est accessible"
+else
+ echo "⚠️ Keycloak ne répond pas sur http://localhost:8180"
+ echo " Assurez-vous que Keycloak est démarré avant de continuer."
+ read -p " Voulez-vous continuer quand même? (y/N) " -n 1 -r
+ echo
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ exit 1
+ fi
+fi
+
+# Vérifier le backend (optionnel)
+echo ""
+echo "🔍 Vérification du backend sur http://localhost:8085..."
+if curl -s http://localhost:8085 > /dev/null; then
+ echo "✅ Backend est accessible"
+else
+ echo "⚠️ Backend ne répond pas sur http://localhost:8085"
+ echo " L'application fonctionnera mais les appels API échoueront."
+fi
+
+# Charger les variables d'environnement depuis .env si présent
+if [ -f .env ]; then
+ echo ""
+ echo "📄 Chargement des variables d'environnement depuis .env..."
+ export $(cat .env | grep -v '^#' | xargs)
+ echo "✅ Variables chargées"
+else
+ echo ""
+ echo "⚠️ Fichier .env non trouvé"
+ echo " Créez un fichier .env depuis .env.example si nécessaire"
+fi
+
+# Afficher la configuration
+echo ""
+echo "⚙️ Configuration actuelle:"
+echo " - Port application: 8086"
+echo " - Keycloak: http://localhost:8180"
+echo " - Backend: ${UNIONFLOW_BACKEND_URL:-http://localhost:8085}"
+echo " - Client Secret: ${KEYCLOAK_CLIENT_SECRET:-[non défini, utilise valeur par défaut]}"
+
+# Démarrer l'application
+echo ""
+echo "🚀 Démarrage de l'application..."
+echo ""
+echo "============================================================"
+echo "Une fois démarré, accédez à: http://localhost:8086"
+echo "Pour arrêter: Ctrl+C"
+echo "============================================================"
+echo ""
+
+# Démarrer avec Quarkus dev mode
+./mvnw quarkus:dev