Refactoring
This commit is contained in:
@@ -53,12 +53,18 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="landing-topbar-right">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Accéder" />
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="outcome" value="/pages/secure/dashboard" />
|
||||
<ui:param name="styleClass" value="landing-button" />
|
||||
</ui:include>
|
||||
<a href="#{request.contextPath}/pages/secure/dashboard.xhtml"
|
||||
style="display:inline-flex;align-items:center;gap:.45rem;
|
||||
padding:.5rem 1.25rem;border-radius:6px;
|
||||
border:2px solid rgba(255,255,255,.75);
|
||||
color:#fff;font-size:.875rem;font-weight:700;
|
||||
text-decoration:none;letter-spacing:.02em;
|
||||
transition:background .2s,border-color .2s;"
|
||||
onmouseover="this.style.background='rgba(255,255,255,.18)';this.style.borderColor='#fff'"
|
||||
onmouseout="this.style.background='transparent';this.style.borderColor='rgba(255,255,255,.75)'">
|
||||
Accéder
|
||||
<i class="pi pi-arrow-right" style="font-size:.78rem;"></i>
|
||||
</a>
|
||||
<a href="#" id="landing-menu-button">
|
||||
<i class="pi pi-bars"> </i>
|
||||
</a>
|
||||
@@ -71,12 +77,20 @@
|
||||
<span class="title">UnionFlow</span>
|
||||
<h3>Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs<br/>
|
||||
Simplifiez la gestion de votre organisation avec une solution complète et moderne</h3>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Accéder à la plateforme" />
|
||||
<ui:param name="icon" value="pi pi-sign-in" />
|
||||
<ui:param name="outcome" value="/pages/secure/dashboard" />
|
||||
<ui:param name="styleClass" value="landing-button" />
|
||||
</ui:include>
|
||||
<a href="#{request.contextPath}/pages/secure/dashboard.xhtml"
|
||||
style="display:inline-flex;align-items:center;gap:.6rem;
|
||||
padding:1rem 2.5rem;border-radius:8px;
|
||||
background:#fff;
|
||||
color:#1e1e2e;
|
||||
font-size:1.05rem;font-weight:800;
|
||||
text-decoration:none;letter-spacing:.01em;
|
||||
box-shadow:0 6px 24px rgba(0,0,0,.25);
|
||||
transition:transform .25s,box-shadow .25s;"
|
||||
onmouseover="this.style.transform='translateY(-3px)';this.style.boxShadow='0 12px 36px rgba(0,0,0,.3)'"
|
||||
onmouseout="this.style.transform='translateY(0)';this.style.boxShadow='0 6px 24px rgba(0,0,0,.25)'">
|
||||
<i class="pi pi-sign-in" style="font-size:.95rem;"></i>
|
||||
Accéder à la plateforme
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -175,57 +189,246 @@
|
||||
<div id="benefits" class="landing-pricing">
|
||||
<div class="section-header">
|
||||
<span class="title">Pourquoi choisir UnionFlow ?</span>
|
||||
<h3>Une solution pensée pour les mutuelles, associations, clubs et organisations similaires avec sécurité avancée, multi-plateforme et synchronisation temps réel.</h3>
|
||||
<h3>Une plateforme robuste et moderne bâtie pour les organisations du monde entier —<br/>
|
||||
avec une sensibilité particulière pour les réalités africaines.</h3>
|
||||
</div>
|
||||
|
||||
<!-- Grille des avantages -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="pricing-card">
|
||||
<h2>Sécurité</h2>
|
||||
<span class="price">100%</span>
|
||||
<span class="time">Sécurisé</span>
|
||||
<ul>
|
||||
<li>Connexion sécurisée et centralisée</li>
|
||||
<li>Contrôle d'accès basé sur les rôles</li>
|
||||
<li>Protection des données sensibles</li>
|
||||
<li>Chiffrement des communications</li>
|
||||
|
||||
<!-- Sécurité de niveau entreprise -->
|
||||
<div class="col-12 md:col-6 lg:col-4 flex">
|
||||
<div style="background:var(--surface-0);border:1px solid var(--surface-200);border-radius:14px;padding:2rem;box-shadow:0 2px 10px rgba(0,0,0,.06);transition:box-shadow .25s,transform .25s;width:100%;"
|
||||
onmouseover="this.style.boxShadow='0 10px 30px rgba(0,0,0,.12)';this.style.transform='translateY(-3px)'"
|
||||
onmouseout="this.style.boxShadow='0 2px 10px rgba(0,0,0,.06)';this.style.transform='translateY(0)'">
|
||||
<div style="width:3rem;height:3rem;border-radius:10px;display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem;background:var(--blue-50);">
|
||||
<i class="pi pi-shield" style="color:var(--blue-600);font-size:1.25rem;"></i>
|
||||
</div>
|
||||
<h3 style="color:var(--text-color);font-size:1.1rem;font-weight:700;margin:0 0 .75rem 0;">
|
||||
Sécurité de niveau entreprise
|
||||
</h3>
|
||||
<p style="color:var(--text-color-secondary);line-height:1.7;margin:0 0 1.25rem 0;font-size:.9rem;">
|
||||
Authentification centralisée SSO, gestion des accès par rôle et traçabilité
|
||||
complète de toutes les actions sur la plateforme.
|
||||
</p>
|
||||
<ul style="list-style:none;padding:0;margin:0;">
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
OpenID Connect via Keycloak
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Contrôle d'accès granulaire par rôle
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Chiffrement de bout en bout
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-4 preferred">
|
||||
<div class="pricing-card pro">
|
||||
<span class="preferred-tag">RECOMMANDÉ</span>
|
||||
<h2>Multi-Plateforme</h2>
|
||||
<span class="price">24/7</span>
|
||||
<span class="time">Disponible</span>
|
||||
<ul>
|
||||
<li>Application web responsive</li>
|
||||
<li>Application mobile Flutter</li>
|
||||
<li>iOS et Android</li>
|
||||
<li>Accès depuis n'importe où</li>
|
||||
|
||||
<!-- Multi-plateforme -->
|
||||
<div class="col-12 md:col-6 lg:col-4 flex">
|
||||
<div style="background:var(--surface-0);border:1px solid var(--surface-200);border-radius:14px;padding:2rem;box-shadow:0 2px 10px rgba(0,0,0,.06);transition:box-shadow .25s,transform .25s;width:100%;"
|
||||
onmouseover="this.style.boxShadow='0 10px 30px rgba(0,0,0,.12)';this.style.transform='translateY(-3px)'"
|
||||
onmouseout="this.style.boxShadow='0 2px 10px rgba(0,0,0,.06)';this.style.transform='translateY(0)'">
|
||||
<div style="width:3rem;height:3rem;border-radius:10px;display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem;background:var(--green-50);">
|
||||
<i class="pi pi-mobile" style="color:var(--green-600);font-size:1.25rem;"></i>
|
||||
</div>
|
||||
<h3 style="color:var(--text-color);font-size:1.1rem;font-weight:700;margin:0 0 .75rem 0;">
|
||||
Accessible partout, tout le temps
|
||||
</h3>
|
||||
<p style="color:var(--text-color-secondary);line-height:1.7;margin:0 0 1.25rem 0;font-size:.9rem;">
|
||||
Une application web responsive et une application mobile native pour
|
||||
que vos gestionnaires et membres restent connectés en toutes circonstances.
|
||||
</p>
|
||||
<ul style="list-style:none;padding:0;margin:0;">
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Web responsive (tous navigateurs)
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Application mobile iOS & Android
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Disponible 24h/24, 7j/7
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="pricing-card enterprise">
|
||||
<h2>Cloud</h2>
|
||||
<span class="price">Cloud</span>
|
||||
<span class="time">Moderne</span>
|
||||
<ul>
|
||||
<li>Architecture cloud-native</li>
|
||||
<li>Synchronisation temps réel</li>
|
||||
<li>Sauvegarde automatique</li>
|
||||
<li>Scalabilité illimitée</li>
|
||||
|
||||
<!-- Cloud-Native -->
|
||||
<div class="col-12 md:col-6 lg:col-4 flex">
|
||||
<div style="background:var(--surface-0);border:1px solid var(--surface-200);border-radius:14px;padding:2rem;box-shadow:0 2px 10px rgba(0,0,0,.06);transition:box-shadow .25s,transform .25s;width:100%;"
|
||||
onmouseover="this.style.boxShadow='0 10px 30px rgba(0,0,0,.12)';this.style.transform='translateY(-3px)'"
|
||||
onmouseout="this.style.boxShadow='0 2px 10px rgba(0,0,0,.06)';this.style.transform='translateY(0)'">
|
||||
<div style="width:3rem;height:3rem;border-radius:10px;display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem;background:var(--purple-50);">
|
||||
<i class="pi pi-server" style="color:var(--purple-600);font-size:1.25rem;"></i>
|
||||
</div>
|
||||
<h3 style="color:var(--text-color);font-size:1.1rem;font-weight:700;margin:0 0 .75rem 0;">
|
||||
Architecture cloud-native
|
||||
</h3>
|
||||
<p style="color:var(--text-color-secondary);line-height:1.7;margin:0 0 1.25rem 0;font-size:.9rem;">
|
||||
Bâtie sur Quarkus et une architecture microservices, la plateforme monte en
|
||||
charge automatiquement et garantit une haute disponibilité.
|
||||
</p>
|
||||
<ul style="list-style:none;padding:0;margin:0;">
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Microservices Quarkus haute performance
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Scalabilité élastique
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Sauvegardes automatisées
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pilotage par la donnée -->
|
||||
<div class="col-12 md:col-6 lg:col-4 flex">
|
||||
<div style="background:var(--surface-0);border:1px solid var(--surface-200);border-radius:14px;padding:2rem;box-shadow:0 2px 10px rgba(0,0,0,.06);transition:box-shadow .25s,transform .25s;width:100%;"
|
||||
onmouseover="this.style.boxShadow='0 10px 30px rgba(0,0,0,.12)';this.style.transform='translateY(-3px)'"
|
||||
onmouseout="this.style.boxShadow='0 2px 10px rgba(0,0,0,.06)';this.style.transform='translateY(0)'">
|
||||
<div style="width:3rem;height:3rem;border-radius:10px;display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem;background:var(--orange-50);">
|
||||
<i class="pi pi-chart-bar" style="color:var(--orange-600);font-size:1.25rem;"></i>
|
||||
</div>
|
||||
<h3 style="color:var(--text-color);font-size:1.1rem;font-weight:700;margin:0 0 .75rem 0;">
|
||||
Pilotage par la donnée
|
||||
</h3>
|
||||
<p style="color:var(--text-color-secondary);line-height:1.7;margin:0 0 1.25rem 0;font-size:.9rem;">
|
||||
Des tableaux de bord interactifs et des KPIs en temps réel pour prendre
|
||||
les bonnes décisions au bon moment.
|
||||
</p>
|
||||
<ul style="list-style:none;padding:0;margin:0;">
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Dashboards et KPIs temps réel
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Rapports exportables (PDF, Excel)
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Analyse des tendances et historiques
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Adapté à votre contexte — carte mise en avant -->
|
||||
<div class="col-12 md:col-6 lg:col-4 flex">
|
||||
<div style="background:linear-gradient(135deg,var(--primary-600) 0%,var(--primary-800) 100%);border-radius:14px;padding:2rem;box-shadow:0 8px 24px rgba(0,0,0,.18);transition:box-shadow .25s,transform .25s;width:100%;position:relative;overflow:hidden;"
|
||||
onmouseover="this.style.transform='translateY(-3px)'"
|
||||
onmouseout="this.style.transform='translateY(0)'">
|
||||
<div style="position:absolute;top:-20px;right:-20px;width:100px;height:100px;border-radius:50%;background:rgba(255,255,255,.07);"></div>
|
||||
<div style="position:absolute;bottom:-30px;right:20px;width:60px;height:60px;border-radius:50%;background:rgba(255,255,255,.05);"></div>
|
||||
<div style="width:3rem;height:3rem;border-radius:10px;display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem;background:rgba(255,255,255,.15);">
|
||||
<i class="pi pi-globe" style="color:#fff;font-size:1.25rem;"></i>
|
||||
</div>
|
||||
<h3 style="color:#fff;font-size:1.1rem;font-weight:700;margin:0 0 .75rem 0;">
|
||||
Conçu pour les organisations du monde
|
||||
</h3>
|
||||
<p style="color:rgba(255,255,255,.82);line-height:1.7;margin:0 0 1.25rem 0;font-size:.9rem;">
|
||||
Mutuelles, clubs Lions, associations sportives, fédérations professionnelles —
|
||||
UnionFlow s'adapte à toute structure, sur tous les continents.
|
||||
</p>
|
||||
<ul style="list-style:none;padding:0;margin:0;">
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:rgba(255,255,255,.82);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:rgba(255,255,255,.9);"></i>
|
||||
Mutuelles & caisses de solidarité
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:rgba(255,255,255,.82);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:rgba(255,255,255,.9);"></i>
|
||||
Clubs Lions, Rotary, associations civiques
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:rgba(255,255,255,.82);font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:rgba(255,255,255,.9);"></i>
|
||||
Fédérations & réseaux multi-niveaux
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Déploiement flexible -->
|
||||
<div class="col-12 md:col-6 lg:col-4 flex">
|
||||
<div style="background:var(--surface-0);border:1px solid var(--surface-200);border-radius:14px;padding:2rem;box-shadow:0 2px 10px rgba(0,0,0,.06);transition:box-shadow .25s,transform .25s;width:100%;"
|
||||
onmouseover="this.style.boxShadow='0 10px 30px rgba(0,0,0,.12)';this.style.transform='translateY(-3px)'"
|
||||
onmouseout="this.style.boxShadow='0 2px 10px rgba(0,0,0,.06)';this.style.transform='translateY(0)'">
|
||||
<div style="width:3rem;height:3rem;border-radius:10px;display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem;background:var(--indigo-50);">
|
||||
<i class="pi pi-cog" style="color:var(--indigo-600);font-size:1.25rem;"></i>
|
||||
</div>
|
||||
<h3 style="color:var(--text-color);font-size:1.1rem;font-weight:700;margin:0 0 .75rem 0;">
|
||||
Déploiement selon vos contraintes
|
||||
</h3>
|
||||
<p style="color:var(--text-color-secondary);line-height:1.7;margin:0 0 1.25rem 0;font-size:.9rem;">
|
||||
Hébergez la plateforme chez vous ou laissez-nous la gérer. L'API ouverte
|
||||
s'intègre facilement à vos outils existants.
|
||||
</p>
|
||||
<ul style="list-style:none;padding:0;margin:0;">
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
SaaS cloud géré ou on-premise
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
API REST ouverte & documentée
|
||||
</li>
|
||||
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);font-size:.85rem;">
|
||||
<i class="pi pi-check" style="color:var(--green-500);"></i>
|
||||
Évolutions et support continus
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Bande de chiffres clés -->
|
||||
<div style="background:linear-gradient(135deg,var(--primary-700),var(--primary-900));border-radius:16px;padding:2.5rem 2rem;margin-top:3rem;">
|
||||
<div class="grid text-center" style="color:#fff;">
|
||||
<div class="col-6 md:col-3" style="padding:1rem;">
|
||||
<div style="font-size:2.5rem;font-weight:800;line-height:1;">6+</div>
|
||||
<div style="font-size:.85rem;opacity:.8;margin-top:.5rem;line-height:1.4;">Types d'organisations<br/>supportés</div>
|
||||
</div>
|
||||
<div class="col-6 md:col-3" style="padding:1rem;">
|
||||
<div style="font-size:2.5rem;font-weight:800;line-height:1;">100%</div>
|
||||
<div style="font-size:.85rem;opacity:.8;margin-top:.5rem;line-height:1.4;">Données sécurisées<br/>et chiffrées</div>
|
||||
</div>
|
||||
<div class="col-6 md:col-3" style="padding:1rem;">
|
||||
<div style="font-size:2.5rem;font-weight:800;line-height:1;">24/7</div>
|
||||
<div style="font-size:.85rem;opacity:.8;margin-top:.5rem;line-height:1.4;">Disponibilité<br/>garantie</div>
|
||||
</div>
|
||||
<div class="col-6 md:col-3" style="padding:1rem;">
|
||||
<div style="font-size:2.5rem;font-weight:800;line-height:1;">∞</div>
|
||||
<div style="font-size:.85rem;opacity:.8;margin-top:.5rem;line-height:1.4;">Scalabilité<br/>cloud-native</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-5">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Découvrir toutes les fonctionnalités" />
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="outcome" value="/pages/secure/dashboard" />
|
||||
<ui:param name="styleClass" value="landing-button" />
|
||||
</ui:include>
|
||||
<a href="#{request.contextPath}/pages/secure/dashboard.xhtml"
|
||||
style="display:inline-flex;align-items:center;gap:.6rem;
|
||||
padding:.95rem 2.25rem;border-radius:8px;
|
||||
background:var(--primary-color,#6366f1);
|
||||
color:var(--primary-color-text,#fff);
|
||||
font-size:1rem;font-weight:700;
|
||||
text-decoration:none;letter-spacing:.02em;
|
||||
box-shadow:0 4px 18px rgba(99,102,241,.35);
|
||||
transition:transform .25s,box-shadow .25s,opacity .2s;"
|
||||
onmouseover="this.style.transform='translateY(-3px)';this.style.boxShadow='0 10px 30px rgba(99,102,241,.5)'"
|
||||
onmouseout="this.style.transform='translateY(0)';this.style.boxShadow='0 4px 18px rgba(99,102,241,.35)'">
|
||||
Accéder à la plateforme
|
||||
<i class="pi pi-arrow-right" style="font-size:.9rem;"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -240,16 +443,16 @@
|
||||
<li><a href="#home">Accueil</a></li>
|
||||
<li><a href="#features">Fonctionnalités</a></li>
|
||||
<li><a href="#benefits">Avantages</a></li>
|
||||
<li><a href="/pages/secure/dashboard">Tableau de Bord</a></li>
|
||||
<li><a href="/pages/secure/dashboard.xhtml">Tableau de Bord</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<span class="footer-menutitle">FONCTIONNALITÉS</span>
|
||||
<ul>
|
||||
<li><a href="/pages/secure/membre/liste">Membres</a></li>
|
||||
<li><a href="/pages/secure/cotisation/historique">Cotisations</a></li>
|
||||
<li><a href="/pages/secure/evenement/calendrier">Événements</a></li>
|
||||
<li><a href="/pages/secure/aide/documentation">Aide</a></li>
|
||||
<li><a href="/pages/secure/membre/liste.xhtml">Membres</a></li>
|
||||
<li><a href="/pages/secure/cotisation/historique.xhtml">Cotisations</a></li>
|
||||
<li><a href="/pages/secure/evenement/calendrier.xhtml">Événements</a></li>
|
||||
<li><a href="/pages/secure/aide/documentation.xhtml">Aide</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -258,22 +461,34 @@
|
||||
<span class="footer-menutitle">CONTACT</span>
|
||||
<ul>
|
||||
<li>support@unionflow.dev</li>
|
||||
<li>Abidjan, Côte d'Ivoire</li>
|
||||
<li>Afrique & International</li>
|
||||
<li>Plateforme de Gestion Intégrée</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 md:col-6 lg:col-5">
|
||||
<span class="footer-menutitle">NEWSLETTER</span>
|
||||
<span class="footer-subtitle">Rejoignez notre newsletter pour être informé des nouvelles fonctionnalités.</span>
|
||||
<h:form>
|
||||
<div class="newsletter-input">
|
||||
<p:inputText placeholder="adresse email" />
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="S'abonner" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
<div class="newsletter-input">
|
||||
<input type="email"
|
||||
placeholder="adresse email"
|
||||
style="flex:1;padding:.6rem 1rem;border-radius:6px;
|
||||
border:1px solid rgba(255,255,255,.25);
|
||||
background:rgba(255,255,255,.1);
|
||||
color:#fff;font-size:.875rem;outline:none;"
|
||||
onfocus="this.style.borderColor='rgba(255,255,255,.6)'"
|
||||
onblur="this.style.borderColor='rgba(255,255,255,.25)'" />
|
||||
<button type="button"
|
||||
style="display:inline-flex;align-items:center;gap:.4rem;
|
||||
padding:.6rem 1.25rem;border-radius:6px;
|
||||
background:#fff;color:#1e1e2e;
|
||||
font-size:.875rem;font-weight:700;
|
||||
border:none;cursor:pointer;white-space:nowrap;
|
||||
transition:opacity .2s;"
|
||||
onmouseover="this.style.opacity='.88'"
|
||||
onmouseout="this.style.opacity='1'">
|
||||
S'abonner
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="footer-bottom">
|
||||
|
||||
@@ -1,398 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:define name="title">Gestion des Utilisateurs - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
<!-- En-tête avec disposition Freya stricte -->
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-4">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-8">
|
||||
<h2 class="text-primary font-bold mb-2">
|
||||
<i class="pi pi-users text-blue-500 mr-2"></i>
|
||||
Gestion des Utilisateurs
|
||||
</h2>
|
||||
<p class="text-600 mt-0">Administration des comptes et permissions utilisateurs</p>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-4 text-right">
|
||||
<h:form id="formActionsEntete">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:commandButton value="Nouvel Utilisateur"
|
||||
icon="pi pi-user-plus"
|
||||
styleClass="ui-button-success ui-button-sm w-full"
|
||||
onclick="PF('dlgNouvelUtilisateur').show();" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:commandButton value="Importer"
|
||||
icon="pi pi-upload"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm w-full"
|
||||
onclick="PF('dlgImporterUtilisateurs').show();" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:commandButton value="Exporter"
|
||||
icon="pi pi-download"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm w-full"
|
||||
action="#{utilisateursBean.exporterUtilisateurs}" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques utilisateurs avec Freya stricte -->
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-4" style="min-height: 9rem;">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<span class="block text-600 font-medium text-sm">Total Utilisateurs</span>
|
||||
<div class="flex align-items-center justify-content-center surface-100 border-round-lg"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi pi-users text-blue-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{utilisateursBean.statistiques.totalUtilisateurs}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<div class="bg-blue-500 border-circle mr-2" style="width: 8px; height: 8px;"></div>
|
||||
<span class="text-500 text-xs">Comptes actifs</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-4" style="min-height: 9rem;">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<span class="block text-600 font-medium text-sm">Connectés</span>
|
||||
<div class="flex align-items-center justify-content-center surface-100 border-round-lg"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi pi-circle-fill text-green-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{utilisateursBean.statistiques.utilisateursConnectes}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<div class="bg-green-500 border-circle mr-2" style="width: 8px; height: 8px;"></div>
|
||||
<span class="text-500 text-xs">En ligne maintenant</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-4" style="min-height: 9rem;">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<span class="block text-600 font-medium text-sm">Administrateurs</span>
|
||||
<div class="flex align-items-center justify-content-center surface-100 border-round-lg"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi pi-shield text-orange-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{utilisateursBean.statistiques.administrateurs}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<div class="bg-orange-500 border-circle mr-2" style="width: 8px; height: 8px;"></div>
|
||||
<span class="text-500 text-xs">Privilèges élevés</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-4" style="min-height: 9rem;">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<span class="block text-600 font-medium text-sm">Désactivés</span>
|
||||
<div class="flex align-items-center justify-content-center surface-100 border-round-lg"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi pi-ban text-red-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{utilisateursBean.statistiques.utilisateursDesactives}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<div class="bg-red-500 border-circle mr-2" style="width: 8px; height: 8px;"></div>
|
||||
<span class="text-500 text-xs">Comptes suspendus</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et recherche avec Freya stricte -->
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-4">
|
||||
<h5 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-search text-blue-500 mr-2"></i>
|
||||
Recherche et Filtres
|
||||
</h5>
|
||||
<h:form id="formFiltres">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:outputLabel for="searchNom" value="Nom ou Email" />
|
||||
<p:inputText id="searchNom" value="#{utilisateursBean.filtres.recherche}"
|
||||
placeholder="Rechercher par nom ou email...">
|
||||
<p:ajax event="keyup" update="dtUtilisateurs" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="filterRole" value="Rôle" />
|
||||
<p:selectOneMenu id="filterRole" value="#{utilisateursBean.filtres.role}">
|
||||
<f:selectItem itemLabel="Tous les rôles" itemValue="" />
|
||||
<f:selectItem itemLabel="Super Admin" itemValue="SUPER_ADMIN" />
|
||||
<f:selectItem itemLabel="Admin" itemValue="ADMIN" />
|
||||
<f:selectItem itemLabel="Gestionnaire" itemValue="GESTIONNAIRE" />
|
||||
<f:selectItem itemLabel="Utilisateur" itemValue="USER" />
|
||||
<p:ajax update="dtUtilisateurs" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="filterStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filterStatut" value="#{utilisateursBean.filtres.statut}">
|
||||
<f:selectItem itemLabel="Tous statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Inactif" itemValue="INACTIF" />
|
||||
<f:selectItem itemLabel="Suspendu" itemValue="SUSPENDU" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="ATTENTE" />
|
||||
<p:ajax update="dtUtilisateurs" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="filterConnexion" value="Dernière connexion" />
|
||||
<p:selectOneMenu id="filterConnexion" value="#{utilisateursBean.filtres.connexion}">
|
||||
<f:selectItem itemLabel="Toutes" itemValue="" />
|
||||
<f:selectItem itemLabel="Aujourd'hui" itemValue="AUJOURD_HUI" />
|
||||
<f:selectItem itemLabel="Cette semaine" itemValue="SEMAINE" />
|
||||
<f:selectItem itemLabel="Ce mois" itemValue="MOIS" />
|
||||
<f:selectItem itemLabel="Plus de 30 jours" itemValue="PLUS_30_JOURS" />
|
||||
<p:ajax update="dtUtilisateurs" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="filterOrganisation" value="Organisation" />
|
||||
<p:selectOneMenu id="filterOrganisation" value="#{utilisateursBean.filtres.organisation}">
|
||||
<f:selectItem itemLabel="Toutes" itemValue="" />
|
||||
<f:selectItems value="#{utilisateursBean.organisationsDisponibles}"
|
||||
var="org"
|
||||
itemLabel="#{org.nom}"
|
||||
itemValue="#{org.id}" />
|
||||
<p:ajax update="dtUtilisateurs" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Rechercher"
|
||||
icon="pi pi-search"
|
||||
styleClass="ui-button-primary ui-button-sm"
|
||||
action="#{utilisateursBean.rechercher}"
|
||||
update="dtUtilisateurs" />
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm"
|
||||
action="#{utilisateursBean.reinitialiserFiltres}"
|
||||
update="@form dtUtilisateurs" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des utilisateurs avec Freya stricte -->
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<h5 class="text-900 font-bold m-0">
|
||||
<i class="pi pi-users text-blue-500 mr-2"></i>
|
||||
Utilisateurs (#{utilisateursBean.utilisateursFiltres.size()})
|
||||
</h5>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<h:form id="formActionsGroupees">
|
||||
<p:commandButton value="Actions groupées"
|
||||
icon="pi pi-cog"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
onclick="PF('dlgActionsGroupees').show();"
|
||||
disabled="#{empty utilisateursBean.utilisateursSelectionnes}" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p:dataTable id="dtUtilisateurs"
|
||||
value="#{utilisateursBean.utilisateursFiltres}"
|
||||
var="utilisateur"
|
||||
selection="#{utilisateursBean.utilisateursSelectionnes}"
|
||||
rowKey="#{utilisateur.id}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorPosition="both"
|
||||
sortMode="single"
|
||||
styleClass="p-datatable-sm"
|
||||
emptyMessage="Aucun utilisateur trouvé">
|
||||
|
||||
<p:column selectionMode="multiple" width="40" />
|
||||
|
||||
<p:column headerText="Utilisateur" sortBy="#{utilisateur.nom}" width="300">
|
||||
<div class="flex align-items-center">
|
||||
<div class="surface-200 border-circle flex align-items-center justify-content-center mr-3"
|
||||
style="width: 40px; height: 40px;">
|
||||
<i class="pi pi-user text-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{utilisateur.nomComplet}</div>
|
||||
<div class="text-600 text-sm">#{utilisateur.email}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Rôle" sortBy="#{utilisateur.role}" width="120">
|
||||
<p:tag value="#{utilisateur.roleLibelle}" severity="#{utilisateur.roleSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{utilisateur.organisation}" width="150">
|
||||
<span class="text-900">#{utilisateur.organisationNom}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{utilisateur.statut}" width="100">
|
||||
<p:tag value="#{utilisateur.statutLibelle}" severity="#{utilisateur.statutSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Dernière connexion" sortBy="#{utilisateur.derniereConnexion}" width="140">
|
||||
<div class="text-900 text-sm">#{utilisateur.derniereConnexionFormatee}</div>
|
||||
<div class="text-600 text-xs">#{utilisateur.derniereConnexionRelative}</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date création" sortBy="#{utilisateur.dateCreation}" width="120">
|
||||
<span class="text-900 text-sm">#{utilisateur.dateCreationFormatee}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" width="150">
|
||||
<h:form id="formActions#{utilisateur.id}">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
title="Voir profil"
|
||||
onclick="PF('dlgVoirUtilisateur').show();">
|
||||
<f:setPropertyActionListener target="#{utilisateursBean.utilisateurSelectionne}" value="#{utilisateur}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
title="Modifier"
|
||||
onclick="PF('dlgModifierUtilisateur').show();">
|
||||
<f:setPropertyActionListener target="#{utilisateursBean.utilisateurSelectionne}" value="#{utilisateur}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-key"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
title="Gérer permissions"
|
||||
onclick="PF('dlgPermissions').show();">
|
||||
<f:setPropertyActionListener target="#{utilisateursBean.utilisateurSelectionne}" value="#{utilisateur}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-ban"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
title="Désactiver"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir désactiver cet utilisateur ?');"
|
||||
action="#{utilisateursBean.desactiverUtilisateur(utilisateur)}"
|
||||
rendered="#{utilisateur.statut != 'INACTIF'}" />
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
title="Activer"
|
||||
action="#{utilisateursBean.activerUtilisateur(utilisateur)}"
|
||||
rendered="#{utilisateur.statut == 'INACTIF'}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvel Utilisateur avec Freya stricte -->
|
||||
<p:dialog header="Nouvel Utilisateur" widgetVar="dlgNouvelUtilisateur" modal="true" width="600">
|
||||
<h:form id="formNouvelUtilisateur">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newNom" value="Nom" />
|
||||
<p:inputText id="newNom" value="#{utilisateursBean.nouvelUtilisateur.nom}"
|
||||
required="true" placeholder="Nom de famille" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newPrenom" value="Prénom" />
|
||||
<p:inputText id="newPrenom" value="#{utilisateursBean.nouvelUtilisateur.prenom}"
|
||||
required="true" placeholder="Prénom" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newEmail" value="Email" />
|
||||
<p:inputText id="newEmail" value="#{utilisateursBean.nouvelUtilisateur.email}"
|
||||
required="true" placeholder="adresse@email.com" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newTelephone" value="Téléphone" />
|
||||
<p:inputText id="newTelephone" value="#{utilisateursBean.nouvelUtilisateur.telephone}"
|
||||
placeholder="+225 XX XX XX XX" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newRole" value="Rôle" />
|
||||
<p:selectOneMenu id="newRole" value="#{utilisateursBean.nouvelUtilisateur.role}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="👤 Utilisateur" itemValue="USER" />
|
||||
<f:selectItem itemLabel="⚙️ Gestionnaire" itemValue="GESTIONNAIRE" />
|
||||
<f:selectItem itemLabel="🛠️ Administrateur" itemValue="ADMIN" />
|
||||
<f:selectItem itemLabel="🛡️ Super Admin" itemValue="SUPER_ADMIN" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newOrganisation" value="Organisation" />
|
||||
<p:selectOneMenu id="newOrganisation" value="#{utilisateursBean.nouvelUtilisateur.organisationId}">
|
||||
<f:selectItem itemLabel="Aucune organisation" itemValue="" />
|
||||
<f:selectItems value="#{utilisateursBean.organisationsDisponibles}"
|
||||
var="org"
|
||||
itemLabel="#{org.nom}"
|
||||
itemValue="#{org.id}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="newMotDePasse" value="Mot de passe temporaire" />
|
||||
<p:password id="newMotDePasse" value="#{utilisateursBean.nouvelUtilisateur.motDePasse}"
|
||||
required="true" placeholder="Mot de passe temporaire" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<div class="flex align-items-center">
|
||||
<p:selectBooleanCheckbox id="newEnvoyerEmail" value="#{utilisateursBean.nouvelUtilisateur.envoyerEmail}" />
|
||||
<p:outputLabel for="newEnvoyerEmail" value="Envoyer les informations de connexion par email" styleClass="ml-2" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Créer l'utilisateur" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{utilisateursBean.creerUtilisateur}"
|
||||
update="@form dtUtilisateurs"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgNouvelUtilisateur').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgNouvelUtilisateur').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -209,13 +209,16 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="montantPaye" value="Montant à payer (FCFA)" />
|
||||
<p:inputNumber id="montantPaye"
|
||||
value="#{adhesionsBean.adhesionSelectionnee.montantPaye}"
|
||||
<p:outputLabel for="montantPaiementPartiel" value="Montant à payer (FCFA)" />
|
||||
<p:inputNumber id="montantPaiementPartiel"
|
||||
value="#{adhesionsBean.montantPaiementPartiel}"
|
||||
symbol=""
|
||||
minValue="0"
|
||||
maxValue="#{adhesionsBean.adhesionSelectionnee.fraisAdhesion}"
|
||||
styleClass="w-full" />
|
||||
maxValue="#{adhesionsBean.adhesionSelectionnee.montantRestant}"
|
||||
styleClass="w-full"
|
||||
required="true"
|
||||
requiredMessage="Veuillez saisir le montant du paiement partiel" />
|
||||
<p:message for="montantPaiementPartiel" />
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
@@ -248,7 +251,7 @@
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.enregistrerPaiement(adhesionsBean.adhesionSelectionnee.montantPaye, adhesionsBean.adhesionSelectionnee.methodePaiement, adhesionsBean.adhesionSelectionnee.referencePaiement)}" />
|
||||
<ui:param name="action" value="#{adhesionsBean.enregistrerPaiementPartiel}" />
|
||||
<ui:param name="update" value="@form :formPaiements" />
|
||||
<ui:param name="oncomplete" value="PF('dlgPaiementPartiel').hide();" />
|
||||
</ui:include>
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
<p:column headerText="Date" sortBy="#{sauvegarde.date}">
|
||||
<h:outputText value="#{sauvegarde.date}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy HH:mm"/>
|
||||
<f:convertDateTime pattern="dd/MM/yyyy HH:mm" type="localDateTime"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
<p:column headerText="Date approbation" sortBy="#{demande.dateDemande}">
|
||||
<h:outputText value="#{demande.dateDemande}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
|
||||
<p:column headerText="Date" sortBy="#{demande.dateDemande}">
|
||||
<h:outputText value="#{demande.dateDemande}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
<p:column headerText="Date" sortBy="#{demande.dateDemande}">
|
||||
<h:outputText value="#{demande.dateDemande}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:param name="page" value="#{suggestionBean}"/>
|
||||
<ui:define name="title">Suggestions et Feedback - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
@@ -30,7 +30,8 @@
|
||||
<p:commandButton value="Nouvelle Suggestion"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-plus"
|
||||
onclick="PF('nouvelleSuggestionDialog').show()" />
|
||||
action="#{suggestionBean.ouvrirDialogNouvelleSuggestion}"
|
||||
update="@form" />
|
||||
<p:commandButton value="Mes Suggestions"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-user" />
|
||||
@@ -41,28 +42,28 @@
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">247</div>
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">#{suggestionBean.totalSuggestions}</div>
|
||||
<div class="text-900 font-semibold mb-1">Suggestions</div>
|
||||
<div class="text-600 text-sm">Soumises</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">43</div>
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">#{suggestionBean.suggestionsImplementees}</div>
|
||||
<div class="text-900 font-semibold mb-1">Implémentées</div>
|
||||
<div class="text-600 text-sm">Dans la v2.0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">1,523</div>
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">#{suggestionBean.totalVotes}</div>
|
||||
<div class="text-900 font-semibold mb-1">Votes</div>
|
||||
<div class="text-600 text-sm">Ce mois-ci</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">156</div>
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">#{suggestionBean.contributeursActifs}</div>
|
||||
<div class="text-900 font-semibold mb-1">Contributeurs</div>
|
||||
<div class="text-600 text-sm">Actifs</div>
|
||||
</div>
|
||||
@@ -388,41 +389,48 @@
|
||||
header="Soumettre une Nouvelle Suggestion"
|
||||
modal="true"
|
||||
width="800"
|
||||
styleClass="surface-0">
|
||||
styleClass="surface-0"
|
||||
visible="#{suggestionBean.afficherDialogNouvelleSuggestion}">
|
||||
<h:form id="nouvelleSuggestionForm">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="categorieSugg" class="block text-900 font-semibold mb-2">Catégorie *</label>
|
||||
<p:selectOneMenu id="categorieSugg" styleClass="w-full">
|
||||
<p:selectOneMenu id="categorieSugg"
|
||||
value="#{suggestionBean.nouvelleSuggestion.categorie}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionnez une catégorie" itemValue="" />
|
||||
<f:selectItem itemLabel="Interface Utilisateur" itemValue="ui" />
|
||||
<f:selectItem itemLabel="Nouvelle Fonctionnalité" itemValue="feature" />
|
||||
<f:selectItem itemLabel="Amélioration Performance" itemValue="performance" />
|
||||
<f:selectItem itemLabel="Sécurité" itemValue="securite" />
|
||||
<f:selectItem itemLabel="Intégration Externe" itemValue="integration" />
|
||||
<f:selectItem itemLabel="Application Mobile" itemValue="mobile" />
|
||||
<f:selectItem itemLabel="Rapports et Analytics" itemValue="reporting" />
|
||||
<f:selectItem itemLabel="Interface Utilisateur" itemValue="UI" />
|
||||
<f:selectItem itemLabel="Nouvelle Fonctionnalité" itemValue="FEATURE" />
|
||||
<f:selectItem itemLabel="Amélioration Performance" itemValue="PERFORMANCE" />
|
||||
<f:selectItem itemLabel="Sécurité" itemValue="SECURITE" />
|
||||
<f:selectItem itemLabel="Intégration Externe" itemValue="INTEGRATION" />
|
||||
<f:selectItem itemLabel="Application Mobile" itemValue="MOBILE" />
|
||||
<f:selectItem itemLabel="Rapports et Analytics" itemValue="REPORTING" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="prioriteSugg" class="block text-900 font-semibold mb-2">Priorité estimée</label>
|
||||
<p:selectOneMenu id="prioriteSugg" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Basse" itemValue="basse" />
|
||||
<f:selectItem itemLabel="Moyenne" itemValue="moyenne" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="haute" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="critique" />
|
||||
<p:selectOneMenu id="prioriteSugg"
|
||||
value="#{suggestionBean.nouvelleSuggestion.prioriteEstimee}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Basse" itemValue="BASSE" />
|
||||
<f:selectItem itemLabel="Moyenne" itemValue="MOYENNE" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="titreSugg" class="block text-900 font-semibold mb-2">Titre de votre suggestion *</label>
|
||||
<p:inputText id="titreSugg"
|
||||
value="#{suggestionBean.nouvelleSuggestion.titre}"
|
||||
placeholder="Résumez votre idée en une phrase claire"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="descriptionSugg" class="block text-900 font-semibold mb-2">Description détaillée *</label>
|
||||
<p:inputTextarea id="descriptionSugg"
|
||||
value="#{suggestionBean.nouvelleSuggestion.description}"
|
||||
rows="6"
|
||||
placeholder="Décrivez votre suggestion : problème rencontré, solution proposée, bénéfices attendus..."
|
||||
styleClass="w-full" />
|
||||
@@ -430,6 +438,7 @@
|
||||
<div class="field col-12">
|
||||
<label for="justificationSugg" class="block text-900 font-semibold mb-2">Justification métier</label>
|
||||
<p:inputTextarea id="justificationSugg"
|
||||
value="#{suggestionBean.nouvelleSuggestion.justification}"
|
||||
rows="3"
|
||||
placeholder="Expliquez pourquoi cette fonctionnalité serait utile et pour quels utilisateurs..."
|
||||
styleClass="w-full" />
|
||||
@@ -447,11 +456,14 @@
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('nouvelleSuggestionDialog').hide()"
|
||||
action="#{suggestionBean.fermerDialogNouvelleSuggestion}"
|
||||
update="@form"
|
||||
type="button" />
|
||||
<p:commandButton value="Soumettre la Suggestion"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-send" />
|
||||
icon="pi pi-send"
|
||||
action="#{suggestionBean.creerSuggestion}"
|
||||
update="@form" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:param name="page" value="#{ticketBean}"/>
|
||||
<ui:define name="title">Mes Tickets Support - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
@@ -30,7 +30,8 @@
|
||||
<p:commandButton value="Nouveau Ticket"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-plus"
|
||||
onclick="PF('nouveauTicketDialog').show()" />
|
||||
action="#{ticketBean.ouvrirDialogNouveauTicket}"
|
||||
update="@form" />
|
||||
<p:commandButton value="FAQ"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-question-circle" />
|
||||
@@ -41,28 +42,28 @@
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">12</div>
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">#{ticketBean.totalTickets}</div>
|
||||
<div class="text-900 font-semibold mb-1">Tickets Créés</div>
|
||||
<div class="text-600 text-sm">Au total</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">3</div>
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">#{ticketBean.ticketsEnAttente}</div>
|
||||
<div class="text-900 font-semibold mb-1">En Attente</div>
|
||||
<div class="text-600 text-sm">Réponse support</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">8</div>
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">#{ticketBean.ticketsResolus}</div>
|
||||
<div class="text-900 font-semibold mb-1">Résolus</div>
|
||||
<div class="text-600 text-sm">Avec succès</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-red-500 mb-2">1</div>
|
||||
<div class="text-2xl font-bold text-red-500 mb-2">#{ticketBean.ticketsFermes}</div>
|
||||
<div class="text-900 font-semibold mb-1">Fermé</div>
|
||||
<div class="text-600 text-sm">Sans résolution</div>
|
||||
</div>
|
||||
@@ -130,191 +131,84 @@
|
||||
Historique de vos Tickets
|
||||
</h4>
|
||||
|
||||
<!-- Ticket 1 - En cours -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200">
|
||||
<ui:repeat value="#{ticketBean.tickets}" var="ticket">
|
||||
<!-- Ticket dynamique -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200 #{ticket.statut == 'FERME' ? 'opacity-70' : ''}">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-orange-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-clock text-orange-600 text-xl"></i>
|
||||
<div class="w-3rem h-3rem border-circle #{ticket.statut == 'RESOLU' ? 'bg-green-100' : (ticket.statut == 'EN_ATTENTE' ? 'bg-blue-100' : (ticket.statut == 'FERME' ? 'bg-red-100' : 'bg-orange-100'))} flex align-items-center justify-content-center">
|
||||
<i class="pi #{ticket.statut == 'RESOLU' ? 'pi-check' : (ticket.statut == 'EN_ATTENTE' ? 'pi-pause' : (ticket.statut == 'FERME' ? 'pi-times' : 'pi-clock'))} #{ticket.statut == 'RESOLU' ? 'text-green-600' : (ticket.statut == 'EN_ATTENTE' ? 'text-blue-600' : (ticket.statut == 'FERME' ? 'text-red-600' : 'text-orange-600'))} text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#TK-2024-0157 - Problème d'export Excel</h6>
|
||||
<h6 class="text-900 font-semibold mb-1">#{ticket.numeroTicket} - #{ticket.sujet}</h6>
|
||||
<div class="flex align-items-center gap-2 mb-1">
|
||||
<p:tag value="EN COURS" severity="warning" styleClass="text-xs" />
|
||||
<p:tag value="HAUTE" severity="danger" styleClass="text-xs" />
|
||||
<p:tag value="TECHNIQUE" severity="info" styleClass="text-xs" />
|
||||
<p:tag value="#{ticket.statut}"
|
||||
severity="#{ticket.statut == 'RESOLU' ? 'success' : (ticket.statut == 'FERME' ? 'danger' : (ticket.statut == 'EN_ATTENTE' ? 'info' : 'warning'))}"
|
||||
styleClass="text-xs" />
|
||||
<p:tag value="#{ticket.priorite}"
|
||||
severity="#{ticket.priorite == 'URGENTE' or ticket.priorite == 'HAUTE' ? 'danger' : (ticket.priorite == 'NORMALE' ? 'success' : 'secondary')}"
|
||||
styleClass="text-xs" />
|
||||
<p:tag value="#{ticket.categorie}"
|
||||
severity="info"
|
||||
styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">Créé le 15 janvier 2024 • Dernière réponse il y a 2h</p>
|
||||
<p class="text-600 text-sm mb-0">
|
||||
Créé le #{ticket.dateCreation != null ? ticket.dateCreation : 'N/A'}
|
||||
#{ticket.dateDerniereReponse != null ? ' • Dernière réponse ' + ticket.dateDerniereReponse : ''}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-600 text-sm mb-2">Agent: Marie Dubois</div>
|
||||
#{ticket.agentNom != null ? '<div class="text-600 text-sm mb-2">Agent: ' + ticket.agentNom + '</div>' : ''}
|
||||
<p:commandButton value="Voir Détails"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-eye" />
|
||||
icon="pi pi-eye"
|
||||
action="#{ticketBean.voirDetails}"
|
||||
update="@form">
|
||||
<f:setPropertyActionListener target="#{ticketBean.ticketSelectionne}" value="#{ticket}" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Impossible d'exporter la liste des membres en format Excel. Le fichier généré est corrompu
|
||||
et ne s'ouvre pas dans Excel. Cela concerne tous les exports depuis la version 2.1.
|
||||
#{ticket.description != null ? ticket.description : 'Aucune description'}
|
||||
</p>
|
||||
#{ticket.resolution != null ? '<div class="surface-green-50 border-left-3 border-green-500 p-3 mb-3"><p class="text-green-700 text-sm mb-0"><i class="pi pi-check-circle mr-2"></i><strong>Résolution:</strong> ' + ticket.resolution + '</p></div>' : ''}
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-comments text-blue-500"></i>
|
||||
<span class="text-600 text-sm">5 messages</span>
|
||||
<i class="pi pi-paperclip text-600 ml-3"></i>
|
||||
<span class="text-600 text-sm">2 fichiers</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-clock text-600"></i>
|
||||
<span class="text-600 text-sm">SLA: 4h restantes</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ticket 2 - En attente -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-blue-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-pause text-blue-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#TK-2024-0143 - Demande de formation personnalisée</h6>
|
||||
<div class="flex align-items-center gap-2 mb-1">
|
||||
<p:tag value="EN ATTENTE" severity="info" styleClass="text-xs" />
|
||||
<p:tag value="NORMALE" severity="success" styleClass="text-xs" />
|
||||
<p:tag value="FONCTIONNALITÉ" severity="help" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">Créé le 12 janvier 2024 • En attente de votre réponse</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-600 text-sm mb-2">Agent: Thomas Martin</div>
|
||||
<p:commandButton value="Répondre"
|
||||
styleClass="p-button-primary p-button-sm"
|
||||
icon="pi pi-reply" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Souhaitons organiser une formation sur mesure pour notre équipe administrative.
|
||||
Besoin de devis pour 15 personnes sur 2 jours.
|
||||
</p>
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-3 mb-3">
|
||||
<p class="text-blue-700 text-sm mb-0">
|
||||
<i class="pi pi-info-circle mr-2"></i>
|
||||
<strong>Action requise:</strong> Merci de préciser vos disponibilités pour les dates proposées.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-comments text-blue-500"></i>
|
||||
<span class="text-600 text-sm">3 messages</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-exclamation-triangle text-orange-500"></i>
|
||||
<span class="text-orange-600 text-sm">Réponse attendue depuis 3 jours</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ticket 3 - Résolu -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-green-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-check text-green-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#TK-2024-0128 - Problème de connexion mobile</h6>
|
||||
<div class="flex align-items-center gap-2 mb-1">
|
||||
<p:tag value="RÉSOLU" severity="success" styleClass="text-xs" />
|
||||
<p:tag value="BASSE" severity="secondary" styleClass="text-xs" />
|
||||
<p:tag value="TECHNIQUE" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">Créé le 8 janvier 2024 • Résolu le 10 janvier 2024</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-600 text-sm mb-2">Agent: Sophie Leroy</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Noter"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-star" />
|
||||
<p:commandButton value="Détails"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-eye" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Application ne se charge pas sur smartphone Android. Écran blanc après connexion.
|
||||
</p>
|
||||
<div class="surface-green-50 border-left-3 border-green-500 p-3 mb-3">
|
||||
<p class="text-green-700 text-sm mb-0">
|
||||
<i class="pi pi-check-circle mr-2"></i>
|
||||
<strong>Résolution:</strong> Problème résolu en vidant le cache de l'application mobile.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-comments text-blue-500"></i>
|
||||
<span class="text-600 text-sm">6 messages</span>
|
||||
<i class="pi pi-clock text-600 ml-3"></i>
|
||||
<span class="text-600 text-sm">Résolu en 2 jours</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-400"></i>
|
||||
<span class="text-600 text-sm">Note: 5/5</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ticket 4 - Fermé -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200 opacity-70">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-red-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-times text-red-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#TK-2024-0095 - Demande modification base</h6>
|
||||
<div class="flex align-items-center gap-2 mb-1">
|
||||
<p:tag value="FERMÉ" severity="danger" styleClass="text-xs" />
|
||||
<p:tag value="HAUTE" severity="danger" styleClass="text-xs" />
|
||||
<p:tag value="FONCTIONNALITÉ" severity="help" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">Créé le 28 décembre 2023 • Fermé le 5 janvier 2024</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-600 text-sm mb-2">Agent: Marc Durand</div>
|
||||
<p:commandButton value="Rouvrir"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-replay" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Demande de modification des champs de la base de données membres pour ajouter
|
||||
des informations métier spécifiques.
|
||||
</p>
|
||||
<div class="surface-red-50 border-left-3 border-red-500 p-3 mb-3">
|
||||
<p class="text-red-700 text-sm mb-0">
|
||||
<i class="pi pi-times-circle mr-2"></i>
|
||||
<strong>Fermé:</strong> Demande non compatible avec l'architecture actuelle.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-comments text-blue-500"></i>
|
||||
<span class="text-600 text-sm">8 messages</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-ban text-red-500"></i>
|
||||
<span class="text-red-600 text-sm">Non résolu</span>
|
||||
<span class="text-600 text-sm">#{ticket.nbMessages != null ? ticket.nbMessages : 0} message#{ticket.nbMessages != null and ticket.nbMessages > 1 ? 's' : ''}</span>
|
||||
#{ticket.nbFichiers != null and ticket.nbFichiers > 0 ? '<i class="pi pi-paperclip text-600 ml-3"></i><span class="text-600 text-sm">' + ticket.nbFichiers + ' fichier' + (ticket.nbFichiers > 1 ? 's' : '') + '</span>' : ''}
|
||||
</div>
|
||||
#{ticket.noteSatisfaction != null ? '<div class="flex align-items-center gap-1"><i class="pi pi-star-fill text-yellow-400"></i><span class="text-600 text-sm">Note: ' + ticket.noteSatisfaction + '/5</span></div>' : ''}
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<p:dataTable value="#{ticketBean.tickets}"
|
||||
var="ticket"
|
||||
emptyMessage="Aucun ticket trouvé"
|
||||
rendered="#{empty ticketBean.tickets}">
|
||||
<p:column headerText="Numéro">#{ticket.numeroTicket}</p:column>
|
||||
<p:column headerText="Sujet">#{ticket.sujet}</p:column>
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="#{ticket.statut}"
|
||||
severity="#{ticket.statut == 'RESOLU' ? 'success' : (ticket.statut == 'FERME' ? 'danger' : (ticket.statut == 'EN_ATTENTE' ? 'info' : 'warning'))}" />
|
||||
</p:column>
|
||||
<p:column headerText="Priorité">
|
||||
<p:tag value="#{ticket.priorite}"
|
||||
severity="#{ticket.priorite == 'URGENTE' or ticket.priorite == 'HAUTE' ? 'danger' : (ticket.priorite == 'NORMALE' ? 'success' : 'secondary')}" />
|
||||
</p:column>
|
||||
<p:column headerText="Date Création">#{ticket.dateCreation}</p:column>
|
||||
<p:column headerText="Actions">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="p-button-text p-button-sm"
|
||||
title="Voir détails"
|
||||
action="#{ticketBean.voirDetails}"
|
||||
update="@form">
|
||||
<f:setPropertyActionListener target="#{ticketBean.ticketSelectionne}" value="#{ticket}" />
|
||||
</p:commandButton>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -371,7 +265,8 @@
|
||||
header="Créer un Nouveau Ticket"
|
||||
modal="true"
|
||||
width="800"
|
||||
styleClass="surface-0">
|
||||
styleClass="surface-0"
|
||||
visible="#{ticketBean.afficherDialogNouveauTicket}">
|
||||
<h:form id="nouveauTicketForm">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
@@ -421,11 +316,14 @@
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('nouveauTicketDialog').hide()"
|
||||
action="#{ticketBean.fermerDialogNouveauTicket}"
|
||||
update="@form"
|
||||
type="button" />
|
||||
<p:commandButton value="Créer le Ticket"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-send" />
|
||||
icon="pi pi-send"
|
||||
action="#{ticketBean.creerTicket}"
|
||||
update="@form" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
|
||||
<p:column headerText="Date" sortBy="#{demande.dateDemande}">
|
||||
<h:outputText value="#{demande.dateDemande}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
|
||||
<p:column headerText="Date" sortBy="#{cotisation.dateCreation}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.dateCreation}" rendered="#{cotisation.dateCreation != null}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" />
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDateTime" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:param name="page" value="#{cotisationsGestionBean}"/>
|
||||
<ui:param name="page" value="#{cotisationsBean}"/>
|
||||
<ui:define name="title">Rapports Financiers - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:param name="page" value="#{cotisationsGestionBean}"/>
|
||||
<ui:param name="page" value="#{cotisationsBean}"/>
|
||||
<ui:define name="title">Relances de Cotisations - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
|
||||
@@ -1,657 +1,275 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:uf="http://xmlns.jcp.org/jsf/composite/components"
|
||||
template="/templates/main-template.xhtml">
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui" xmlns:uf="http://xmlns.jcp.org/jsf/composite/components"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:param name="page" value="#{membreListeBean}"/>
|
||||
<ui:define name="title">Liste des Membres - UnionFlow</ui:define>
|
||||
<ui:define name="title">Gestion des Membres</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<ui:include src="/templates/components/layout/page-header.xhtml">
|
||||
<ui:param name="icon" value="pi pi-users text-blue-500" />
|
||||
<ui:param name="title" value="Liste des Membres" />
|
||||
<ui:param name="description" value="Gestion et suivi des membres de l'association" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsMembres">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouveau membre" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="outcome" value="/pages/secure/membre/inscription" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Import/Export" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="onclick" value="PF('dlgImportExport').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
<h:form id="formMembres">
|
||||
<p:messages id="messages" showDetail="true" closable="true" />
|
||||
|
||||
<!-- ================================================================
|
||||
EN-TÊTE (DRY/WOU: card-header)
|
||||
================================================================ -->
|
||||
<ui:decorate template="/templates/components/cards/card-header.xhtml">
|
||||
<ui:param name="title" value="Gestion des Membres" />
|
||||
<ui:param name="subtitle" value="Liste, recherche et gestion des membres de l'organisation." />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="actions">
|
||||
<p:button value="Nouveau Membre" icon="pi pi-user-plus" outcome="membreInscriptionPage"
|
||||
styleClass="ui-button-success mr-2" />
|
||||
<p:commandButton value="Import / Export" icon="pi pi-file-excel"
|
||||
onclick="PF('dlgImportExport').show();" type="button" styleClass="ui-button-info" />
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Liste des membres -->
|
||||
<div class="card">
|
||||
<h:form id="formMembres">
|
||||
<h5>Tous les Membres</h5>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar avec composants réutilisables) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<!-- Recherche globale (DRY/WOU: form-field-search-text avec icône) -->
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchFilter" value="Rechercher" />
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchFilter"
|
||||
placeholder="Nom, prénom, email..."
|
||||
value="#{membreListeBean.searchFilter}"
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" update="dtMembres" delay="500"/>
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statut (DRY/WOU: form-field-select avec AJAX) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="statutFilter" />
|
||||
<ui:param name="label" value="Statut" />
|
||||
<ui:param name="value" value="#{membreListeBean.statutFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Inactif" itemValue="INACTIF" />
|
||||
<f:selectItem itemLabel="Suspendu" itemValue="SUSPENDU" />
|
||||
<f:selectItem itemLabel="Radié" itemValue="RADIE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax event="change" update="dtMembres" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Type (DRY/WOU: form-field-select avec AJAX) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="typeFilter" />
|
||||
<ui:param name="label" value="Type" />
|
||||
<ui:param name="value" value="#{membreListeBean.typeFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Associé" itemValue="ASSOCIE" />
|
||||
<f:selectItem itemLabel="Bienfaiteur" itemValue="BIENFAITEUR" />
|
||||
<f:selectItem itemLabel="Honoraire" itemValue="HONORAIRE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax event="change" update="dtMembres" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Cotisation (DRY/WOU: form-field-select avec AJAX) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="cotisationFilter" />
|
||||
<ui:param name="label" value="Cotisation" />
|
||||
<ui:param name="value" value="#{membreListeBean.cotisationFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Toutes cotisations" itemValue="" />
|
||||
<f:selectItem itemLabel="À jour" itemValue="A_JOUR" />
|
||||
<f:selectItem itemLabel="En retard" itemValue="EN_RETARD" />
|
||||
<f:selectItem itemLabel="Jamais payé" itemValue="JAMAIS_PAYE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax event="change" update="dtMembres" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Entité/Organisation (DRY/WOU: form-field-select avec AJAX) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="entiteFilter" />
|
||||
<ui:param name="label" value="Entité" />
|
||||
<ui:param name="value" value="#{membreListeBean.entiteFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Toutes entités" itemValue="" />
|
||||
<f:selectItems value="#{membreListeBean.entitesDisponibles}"
|
||||
var="entite"
|
||||
itemLabel="#{entite.nom}"
|
||||
itemValue="#{entite.id}" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax event="change" update="dtMembres" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<!-- Filtres avancés (DRY/WOU: button-secondary) -->
|
||||
<div class="col-12 md:col-auto">
|
||||
<div class="field">
|
||||
<label class="invisible">Filtres avancés</label>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Filtres avancés" />
|
||||
<ui:param name="icon" value="pi pi-filter" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').show();" />
|
||||
<ui:param name="styleClass" value="w-full" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actualiser (DRY/WOU: button-secondary avec icône seule) -->
|
||||
<div class="col-12 md:col-auto">
|
||||
<div class="field">
|
||||
<label class="invisible">Actualiser</label>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{membreListeBean.actualiser}" />
|
||||
<ui:param name="update" value=":formMembres:dtMembres" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Réinitialiser (DRY/WOU: button-secondary) -->
|
||||
<div class="col-12 md:col-auto">
|
||||
<div class="field">
|
||||
<label class="invisible">Réinitialiser</label>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Réinitialiser" />
|
||||
<ui:param name="icon" value="pi pi-filter-slash" />
|
||||
<ui:param name="action" value="#{membreListeBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value="dtMembres searchFilter statutFilter typeFilter cotisationFilter entiteFilter" />
|
||||
<ui:param name="styleClass" value="w-full" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
<!-- ================================================================
|
||||
STATISTIQUES (DRY/WOU: stat-card)
|
||||
================================================================ -->
|
||||
<h:panelGroup id="panelStatistiques" layout="block" styleClass="grid mb-3">
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:decorate template="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{membreListeBean.totalMembres}" />
|
||||
<ui:param name="label" value="Total Membres" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="bgColor" value="bg-blue-100" />
|
||||
</ui:decorate>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:decorate template="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{membreListeBean.membresActifs}" />
|
||||
<ui:param name="label" value="Actifs" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="bg-green-100" />
|
||||
</ui:decorate>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:decorate template="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{membreListeBean.membresInactifs}" />
|
||||
<ui:param name="label" value="Inactifs / Suspendus" />
|
||||
<ui:param name="icon" value="pi pi-ban" />
|
||||
<ui:param name="bgColor" value="bg-orange-100" />
|
||||
</ui:decorate>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:decorate template="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{membreListeBean.nouveauxMembres}" />
|
||||
<ui:param name="label" value="Nouveaux (30j)" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="bgColor" value="bg-purple-100" />
|
||||
</ui:decorate>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtMembres"
|
||||
var="membre"
|
||||
value="#{membreListeBean.membres}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="10,15,25,50"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{membreListeBean.selectedMembres}"
|
||||
rowKey="#{membre.id}"
|
||||
selectionMode="multiple"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="N° Membre" sortBy="#{membre.numeroMembre}" style="width:120px">
|
||||
<h:outputText value="#{membre.numeroMembre}" styleClass="font-mono font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{membre.nom}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle overflow-hidden mr-3"
|
||||
style="width: 40px; height: 40px;">
|
||||
<h:graphicImage value="#{membre.photoUrl}"
|
||||
style="width: 100%; height: 100%; object-fit: cover;"
|
||||
rendered="#{membre.photoUrl != null}" />
|
||||
<div class="bg-primary text-white flex align-items-center justify-content-center w-full h-full"
|
||||
rendered="#{membre.photoUrl == null}">
|
||||
<span style="font-size: 0.9rem;">#{membre.initiales}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-900">#{membre.nomComplet}</div>
|
||||
<div class="text-600 text-sm">
|
||||
<span>#{membre.telephone}</span>
|
||||
<span class="mx-2">•</span>
|
||||
<span>#{membre.email}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{membre.typeMembre}" style="width:120px">
|
||||
<p:tag value="#{membre.typeMembre}"
|
||||
severity="#{membre.typeSeverity != null ? membre.typeSeverity : 'info'}"
|
||||
icon="pi #{membre.typeIcon != null ? membre.typeIcon : 'pi-user'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{membre.statut}" style="width:100px">
|
||||
<p:tag value="#{membre.statut}"
|
||||
severity="#{membre.statutSeverity}"
|
||||
icon="pi #{membre.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{membre.associationNom}" style="width:150px">
|
||||
<h:outputText value="#{membre.associationNom != null ? membre.associationNom : 'Non renseigné'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Adhésion" sortBy="#{membre.dateAdhesion}" style="width:120px">
|
||||
<div>
|
||||
<div class="font-medium">#{membre.dateAdhesion != null ? membre.dateAdhesion : 'Non renseigné'}</div>
|
||||
<small class="text-600">#{membre.anciennete}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Cotisations" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold #{membre.cotisationColor}">#{membre.cotisationStatut}</div>
|
||||
<small class="text-600">#{membre.dernierPaiement}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Participation" style="width:100px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-blue-500">#{membre.tauxParticipation}%</div>
|
||||
<small class="text-600">#{membre.evenementsAnnee} événements</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<!-- DRY/WOU: Composite Component action-button-view -->
|
||||
<uf:action-button-view itemId="#{membre.id}"
|
||||
detailPage="/pages/secure/membre/profil.xhtml"
|
||||
iconOnly="true"/>
|
||||
<!-- DRY/WOU: Composite Component action-button-edit-nav -->
|
||||
<uf:action-button-edit-nav itemId="#{membre.id}"
|
||||
editPage="/pages/secure/membre/modifier.xhtml"
|
||||
iconOnly="true"/>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-dollar" />
|
||||
<ui:param name="action" value="#{membreListeBean.gererCotisations(membre)}" />
|
||||
<ui:param name="title" value="Cotisations" />
|
||||
<ui:param name="severity" value="success" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="action" value="#{membreListeBean.contacterMembre(membre)}" />
|
||||
<ui:param name="update" value=":formMembres :formContact" />
|
||||
<ui:param name="oncomplete" value="PF('dlgContact').show();" />
|
||||
<ui:param name="title" value="Contacter" />
|
||||
<ui:param name="severity" value="" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-ban" />
|
||||
<ui:param name="action" value="#{membreListeBean.suspendreMembre(membre)}" />
|
||||
<ui:param name="onclick" value="return confirm('Êtes-vous sûr de vouloir suspendre ce membre ?');" />
|
||||
<ui:param name="title" value="Suspendre" />
|
||||
<ui:param name="severity" value="danger" />
|
||||
<ui:param name="rendered" value="#{membre.statut == 'ACTIF'}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreListeBean.reactiverMembre(membre)}" />
|
||||
<ui:param name="title" value="Réactiver" />
|
||||
<ui:param name="severity" value="success" />
|
||||
<ui:param name="rendered" value="#{membre.statut == 'SUSPENDU'}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Actions groupées -->
|
||||
<div class="mt-3 flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<span class="text-600">#{membreListeBean.selectedMembres.size()} membre(s) sélectionné(s)</span>
|
||||
<span class="text-400 ml-2" rendered="#{empty membreListeBean.selectedMembres}">
|
||||
- Cochez des cases pour activer les actions
|
||||
<!-- ================================================================
|
||||
BARRE DE FILTRES (DRY/WOU: filter-bar)
|
||||
================================================================ -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="" />
|
||||
<ui:define name="filters">
|
||||
<!-- Recherche textuelle -->
|
||||
<div class="col-12 md:col-4">
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search" />
|
||||
<p:inputText id="searchFilter" value="#{membreListeBean.searchFilter}"
|
||||
placeholder="Rechercher un membre..." styleClass="w-full">
|
||||
<p:ajax event="keyup" listener="#{membreListeBean.rechercher}" update="dtMembres"
|
||||
delay="500" />
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Envoyer message" />
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="onclick" value="PF('dlgMessageGroupe').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Rappel cotisations" />
|
||||
<ui:param name="icon" value="pi pi-bell" />
|
||||
<ui:param name="action" value="#{membreListeBean.rappelCotisationsGroupe}" />
|
||||
<ui:param name="update" value=":formMembres" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Exporter sélection" />
|
||||
<ui:param name="icon" value="pi pi-file-excel" />
|
||||
<ui:param name="action" value="#{membreListeBean.exporterSelection}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Modifier en lot" />
|
||||
<ui:param name="icon" value="pi pi-pencil" />
|
||||
<ui:param name="onclick" value="PF('dlgModificationLot').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Filtres Avancés -->
|
||||
<p:dialog header="Filtres Avancés" widgetVar="dlgFiltresAvances" modal="true" width="600">
|
||||
<h:form id="formFiltresAvances">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="ageMin" value="Âge minimum" />
|
||||
<p:inputNumber id="ageMin" value="#{membreListeBean.ageMin}" symbol="" styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="ageMax" value="Âge maximum" />
|
||||
<p:inputNumber id="ageMax" value="#{membreListeBean.ageMax}" symbol="" styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="genre" value="Genre" />
|
||||
<p:selectOneMenu id="genre" value="#{membreListeBean.genreFilter}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="Homme" itemValue="M" />
|
||||
<f:selectItem itemLabel="Femme" itemValue="F" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="ville" value="Ville" />
|
||||
<p:autoComplete id="ville"
|
||||
value="#{membreListeBean.villeFilter}"
|
||||
completeMethod="#{membreListeBean.completerVilles}"
|
||||
placeholder="Saisir une ville..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateAdhesionDebut" />
|
||||
<ui:param name="label" value="Adhésion après le" />
|
||||
<ui:param name="value" value="#{membreListeBean.dateAdhesionDebut}" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateAdhesionFin" />
|
||||
<ui:param name="label" value="Adhésion avant le" />
|
||||
<ui:param name="value" value="#{membreListeBean.dateAdhesionFin}" />
|
||||
</ui:include>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="profession" value="Profession" />
|
||||
<p:autoComplete id="profession"
|
||||
value="#{membreListeBean.professionFilter}"
|
||||
completeMethod="#{membreListeBean.completerProfessions}"
|
||||
placeholder="Saisir une profession..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="desEnfants" value="#{membreListeBean.desEnfants}" />
|
||||
<p:outputLabel for="desEnfants" value=" A des enfants déclarés" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- Filtre par statut -->
|
||||
<div class="col-12 md:col-2">
|
||||
<p:selectOneMenu id="statutFilter" value="#{membreListeBean.statutFilter}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Inactif" itemValue="INACTIF" />
|
||||
<f:selectItem itemLabel="Suspendu" itemValue="SUSPENDU" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<p:ajax event="valueChange" listener="#{membreListeBean.rechercher}" update="dtMembres" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Appliquer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreListeBean.appliquerFiltresAvances}" />
|
||||
<ui:param name="update" value=":formMembres:dtMembres" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Réinitialiser" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{membreListeBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value=":formFiltresAvances :formMembres:dtMembres" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-danger" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Message Groupé -->
|
||||
<p:dialog header="Envoyer un Message Groupé" widgetVar="dlgMessageGroupe" modal="true" width="600">
|
||||
<h:form id="formMessageGroupe">
|
||||
<div class="ui-fluid">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="sujetMessage" />
|
||||
<ui:param name="label" value="Sujet" />
|
||||
<ui:param name="value" value="#{membreListeBean.sujetMessage}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="placeholder" value="Objet du message" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="contenuMessage" />
|
||||
<ui:param name="label" value="Message" />
|
||||
<ui:param name="value" value="#{membreListeBean.contenuMessage}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="6" />
|
||||
</ui:include>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="canauxMessage" value="Canaux de diffusion" />
|
||||
<p:selectCheckboxMenu id="canauxMessage" value="#{membreListeBean.canauxMessage}"
|
||||
multiple="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="📧 Email" itemValue="EMAIL" />
|
||||
<f:selectItem itemLabel="📱 SMS" itemValue="SMS" />
|
||||
<f:selectItem itemLabel="💬 WhatsApp" itemValue="WHATSAPP" />
|
||||
<f:selectItem itemLabel="🔔 Notification push" itemValue="PUSH" />
|
||||
</p:selectCheckboxMenu>
|
||||
<!-- Filtre par rôle (aligné avec le modèle métier) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<p:selectOneMenu id="roleFilter" value="#{membreListeBean.roleFilter}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les rôles" itemValue="" />
|
||||
<f:selectItem itemLabel="Responsable" itemValue="RESPONSABLE" />
|
||||
<f:selectItem itemLabel="Bureau" itemValue="BUREAU" />
|
||||
<p:ajax event="valueChange" listener="#{membreListeBean.rechercher}" update="dtMembres" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Destinataires :</div>
|
||||
<div class="text-600">#{membreListeBean.selectedMembres.size()} membre(s) recevront ce message</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Envoyer" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{membreListeBean.envoyerMessageGroupe}" />
|
||||
<ui:param name="update" value=":formMessageGroupe :formMembres" />
|
||||
<ui:param name="onclick" value="if(!args.validationFailed) PF('dlgMessageGroupe').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgMessageGroupe').hide();" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Import/Export -->
|
||||
<p:dialog header="Import/Export des Membres" widgetVar="dlgImportExport" modal="true" width="500">
|
||||
<h:form id="formImportExport">
|
||||
<p:tabView>
|
||||
<p:tab title="Import">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="fichierImport" value="Fichier Excel" />
|
||||
<p:fileUpload id="fichierImport" mode="simple" skinSimple="true"
|
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="mettreAJourExistants" value="#{membreListeBean.mettreAJourExistants}" />
|
||||
<p:outputLabel for="mettreAJourExistants" value=" Mettre à jour les membres existants" />
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Format attendu :</div>
|
||||
<small class="text-600">
|
||||
Colonnes : Nom, Prénom, Email, Téléphone, Date naissance, Adresse, Profession, Type membre
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Importer" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="action" value="#{membreListeBean.importerMembres}" />
|
||||
<ui:param name="update" value=":formImportExport :formMembres" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Télécharger modèle" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreListeBean.telechargerModele}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<p:tab title="Export">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="formatExport" value="Format" />
|
||||
<p:selectOneMenu id="formatExport" value="#{membreListeBean.formatExport}">
|
||||
<f:selectItem itemLabel="Excel (.xlsx)" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="CSV (.csv)" itemValue="CSV" />
|
||||
<f:selectItem itemLabel="PDF (.pdf)" itemValue="PDF" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="colonnesExport" value="Colonnes à exporter" />
|
||||
<p:selectCheckboxMenu id="colonnesExport" value="#{membreListeBean.colonnesExport}"
|
||||
multiple="true">
|
||||
<f:selectItem itemLabel="Informations personnelles" itemValue="PERSO" />
|
||||
<f:selectItem itemLabel="Coordonnées" itemValue="CONTACT" />
|
||||
<f:selectItem itemLabel="Informations adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Cotisations" itemValue="COTISATIONS" />
|
||||
<f:selectItem itemLabel="Participation événements" itemValue="EVENEMENTS" />
|
||||
</p:selectCheckboxMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="exporterSelection" value="#{membreListeBean.exporterSelection}" />
|
||||
<p:outputLabel for="exporterSelection" value=" Exporter seulement la sélection" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Exporter" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreListeBean.exporterMembres}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
|
||||
<div class="flex justify-content-end mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Fermer" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgImportExport').hide();" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Contact Membre -->
|
||||
<h:form id="formContact">
|
||||
<p:dialog id="dlgContact"
|
||||
header="Contacter #{membreListeBean.membreAContacter != null ? membreListeBean.membreAContacter.nomComplet : 'Membre'}"
|
||||
widgetVar="dlgContact"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 600px;"
|
||||
visible="#{membreListeBean.dialogContactVisible}">
|
||||
<div class="ui-fluid" rendered="#{membreListeBean.membreAContacter != null}">
|
||||
<div class="field mb-4">
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="flex align-items-center">
|
||||
<div class="w-3rem h-3rem border-circle bg-primary-100 flex align-items-center justify-content-center mr-3">
|
||||
<i class="pi pi-user text-primary text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-semibold text-900">#{membreListeBean.membreAContacter.nomComplet}</div>
|
||||
<div class="text-600 text-sm">#{membreListeBean.membreAContacter.email != null ? membreListeBean.membreAContacter.email : 'Email non renseigné'}</div>
|
||||
<div class="text-600 text-sm">#{membreListeBean.membreAContacter.telephone != null ? membreListeBean.membreAContacter.telephone : 'Téléphone non renseigné'}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Filtre par organisation -->
|
||||
<div class="col-12 md:col-2">
|
||||
<p:selectOneMenu id="entiteFilter" value="#{membreListeBean.entiteFilter}" styleClass="w-full"
|
||||
filter="true" filterMatchMode="contains">
|
||||
<f:selectItem itemLabel="Toutes les organisations" itemValue="" />
|
||||
<f:selectItems value="#{membreListeBean.organisationsDisponibles}" var="org"
|
||||
itemLabel="#{org.nom}" itemValue="#{org.id}" />
|
||||
<p:ajax event="valueChange" listener="#{membreListeBean.rechercher}" update="dtMembres" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="sujetContact" />
|
||||
<ui:param name="label" value="Sujet" />
|
||||
<ui:param name="value" value="#{membreListeBean.sujetContact}" />
|
||||
<ui:param name="placeholder" value="Sujet du message (optionnel)" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="messageContact" />
|
||||
<ui:param name="label" value="Message *" />
|
||||
<ui:param name="value" value="#{membreListeBean.messageContact}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="6" />
|
||||
<ui:param name="placeholder" value="Saisissez votre message..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex justify-content-end gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="action" value="#{membreListeBean.annulerContact}" />
|
||||
<ui:param name="update" value=":formContact" />
|
||||
<ui:param name="oncomplete" value="PF('dlgContact').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Envoyer" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{membreListeBean.envoyerMessageContact}" />
|
||||
<ui:param name="update" value=":formContact :formMembres" />
|
||||
<ui:param name="oncomplete" value="if(!args.validationFailed) { PF('dlgContact').hide(); }" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
<ui:define name="actions">
|
||||
<p:commandButton icon="pi pi-filter" title="Filtres avancés"
|
||||
onclick="PF('dlgFiltresAvances').show();" type="button" styleClass="ui-button-outlined mr-1" />
|
||||
<p:commandButton icon="pi pi-refresh" title="Actualiser" action="#{membreListeBean.actualiser}"
|
||||
update="dtMembres panelStatistiques messages" styleClass="ui-button-outlined" />
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- ================================================================
|
||||
ACTIONS GROUPÉES (visible si sélection)
|
||||
================================================================ -->
|
||||
<h:panelGroup id="panelActionsGroupeesWrapper">
|
||||
<h:panelGroup id="panelActionsGroupees" layout="block" styleClass="flex gap-2 mb-3"
|
||||
rendered="#{not empty membreListeBean.selectedMembres}">
|
||||
<p:commandButton value="Rappel Cotisations" icon="pi pi-bell"
|
||||
action="#{membreListeBean.rappelCotisationsGroupe}" update="messages"
|
||||
styleClass="ui-button-warning ui-button-sm" />
|
||||
<p:commandButton value="Message Groupé" icon="pi pi-envelope"
|
||||
onclick="PF('dlgMessageGroupe').show();" type="button"
|
||||
styleClass="ui-button-info ui-button-sm" />
|
||||
<p:commandButton value="Exporter Sélection" icon="pi pi-download" ajax="false"
|
||||
action="#{membreListeBean.exporterSelection}" styleClass="ui-button-secondary ui-button-sm" />
|
||||
<h:outputText value="#{membreListeBean.selectedMembres.size()} membre(s) sélectionné(s)"
|
||||
styleClass="ml-2 text-500 align-self-center" />
|
||||
</h:panelGroup>
|
||||
</h:panelGroup>
|
||||
|
||||
<!-- ================================================================
|
||||
DataTable LAZY (pagination/tri/filtrage côté serveur)
|
||||
================================================================ -->
|
||||
<p:dataTable id="dtMembres" var="membre" value="#{membreListeBean.lazyModel}" lazy="true" paginator="true"
|
||||
rows="20" rowsPerPageTemplate="10,20,50"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
currentPageReportTemplate="{startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{membreListeBean.selectedMembres}" rowKey="#{membre.id}" emptyMessage="Aucun membre trouvé."
|
||||
stripedRows="true" showGridlines="false" size="small" styleClass="mb-4" tableStyle="min-width: 60rem">
|
||||
|
||||
<!-- AJAX sélection pour mise à jour des actions groupées -->
|
||||
<p:ajax event="rowSelect" update=":formMembres:panelActionsGroupeesWrapper" />
|
||||
<p:ajax event="rowUnselect" update=":formMembres:panelActionsGroupeesWrapper" />
|
||||
<p:ajax event="toggleSelect" update=":formMembres:panelActionsGroupeesWrapper" />
|
||||
|
||||
<!-- Colonne sélection checkbox -->
|
||||
<p:column selectionMode="multiple" headerText="" style="width: 3rem; text-align: center;" />
|
||||
|
||||
<!-- Colonne: Membre (Nom + Email) -->
|
||||
<ui:decorate template="/templates/components/columns/column-name-with-subtitle.xhtml">
|
||||
<ui:param name="headerText" value="Membre" />
|
||||
<ui:param name="name" value="#{membre.nomComplet}" />
|
||||
<ui:param name="subtitle" value="#{membre.email}" />
|
||||
<ui:param name="sortBy" value="#{membre.nom}" />
|
||||
<ui:param name="filterBy" value="#{membre.nom}" />
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Colonne: Rôle -->
|
||||
<ui:decorate template="/templates/components/columns/column-tag.xhtml">
|
||||
<ui:param name="headerText" value="Rôle" />
|
||||
<ui:param name="value" value="#{membre.typeMembre}" />
|
||||
<ui:param name="severity" value="#{membre.typeSeverity}" />
|
||||
<ui:param name="icon" value="#{membre.typeIcon}" />
|
||||
<ui:param name="width" value="8rem" />
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Colonne: Organisation -->
|
||||
<ui:decorate template="/templates/components/columns/column-text-with-icon.xhtml">
|
||||
<ui:param name="headerText" value="Organisation" />
|
||||
<ui:param name="icon" value="pi pi-building" />
|
||||
<ui:param name="text" value="#{not empty membre.associationNom ? membre.associationNom : '—'}" />
|
||||
<ui:param name="sortBy" value="#{membre.associationNom}" />
|
||||
<ui:param name="filterBy" value="#{membre.associationNom}" />
|
||||
<ui:param name="styleClass" value="#{empty membre.associationNom ? 'text-500' : ''}" />
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Colonne: Téléphone -->
|
||||
<ui:decorate template="/templates/components/columns/column-text-with-icon.xhtml">
|
||||
<ui:param name="headerText" value="Téléphone" />
|
||||
<ui:param name="icon" value="pi pi-phone" />
|
||||
<ui:param name="text" value="#{not empty membre.telephone ? membre.telephone : '—'}" />
|
||||
<ui:param name="styleClass" value="#{empty membre.telephone ? 'text-500' : ''}" />
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Colonne: Statut -->
|
||||
<ui:decorate template="/templates/components/columns/column-tag.xhtml">
|
||||
<ui:param name="headerText" value="Statut" />
|
||||
<ui:param name="value" value="#{membre.statutLibelle}" />
|
||||
<ui:param name="severity" value="#{membre.statutSeverity}" />
|
||||
<ui:param name="icon" value="#{membre.statutIcon}" />
|
||||
<ui:param name="sortBy" value="#{membre.statut}" />
|
||||
<ui:param name="width" value="8rem" />
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Colonne: Date Adhésion -->
|
||||
<p:column headerText="Adhésion" sortBy="#{membre.dateAdhesion}"
|
||||
style="width: 8rem; text-align: center;">
|
||||
<i class="pi pi-calendar mr-1 text-primary"></i>
|
||||
<h:outputText value="#{membre.dateAdhesion}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<!-- Colonne: Actions (DRY/WOU: column-actions) -->
|
||||
<ui:decorate template="/templates/components/columns/column-actions.xhtml">
|
||||
<ui:param name="width" value="14rem" />
|
||||
<ui:define name="actions">
|
||||
<!-- Voir le profil -->
|
||||
<p:button icon="pi pi-user" outcome="membreProfilPage" title="Profil"
|
||||
styleClass="ui-button-info ui-button-sm ui-button-rounded mr-1">
|
||||
<f:param name="id" value="#{membre.id}" />
|
||||
</p:button>
|
||||
|
||||
<!-- Éditer -->
|
||||
<p:button icon="pi pi-pencil" outcome="membreModifierPage" title="Modifier"
|
||||
styleClass="ui-button-warning ui-button-sm ui-button-rounded mr-1">
|
||||
<f:param name="id" value="#{membre.id}" />
|
||||
</p:button>
|
||||
|
||||
<!-- Contacter -->
|
||||
<p:commandButton icon="pi pi-envelope" title="Contacter"
|
||||
action="#{membreListeBean.contacterMembre(membre)}" process="@this"
|
||||
oncomplete="PF('dlgContact').show();" update=":dlgContact"
|
||||
styleClass="ui-button-help ui-button-sm ui-button-rounded mr-1" />
|
||||
|
||||
<!-- Suspendre (visible si actif) -->
|
||||
<p:commandButton icon="pi pi-ban" title="Suspendre"
|
||||
action="#{membreListeBean.suspendreMembre(membre)}"
|
||||
update="dtMembres messages panelStatistiques" rendered="#{membre.statut == 'ACTIF'}"
|
||||
styleClass="ui-button-danger ui-button-sm ui-button-rounded mr-1">
|
||||
<p:confirm header="Confirmation" message="Suspendre #{membre.nomComplet} ?"
|
||||
icon="pi pi-exclamation-triangle" />
|
||||
</p:commandButton>
|
||||
|
||||
<!-- Réactiver (visible si suspendu) -->
|
||||
<p:commandButton icon="pi pi-replay" title="Réactiver"
|
||||
action="#{membreListeBean.reactiverMembre(membre)}"
|
||||
update="dtMembres messages panelStatistiques" rendered="#{membre.statut == 'SUSPENDU'}"
|
||||
styleClass="ui-button-success ui-button-sm ui-button-rounded" />
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Confirmation dialog global -->
|
||||
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade" responsive="true" width="450">
|
||||
<p:commandButton value="Oui" type="button" styleClass="ui-button-danger ui-confirmdialog-yes"
|
||||
icon="pi pi-check" />
|
||||
<p:commandButton value="Non" type="button" styleClass="ui-button-secondary ui-confirmdialog-no"
|
||||
icon="pi pi-times" />
|
||||
</p:confirmDialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
<!-- ================================================================
|
||||
DIALOGS EXTRAITS (DRY/WOU: fichiers include séparés)
|
||||
================================================================ -->
|
||||
<ui:include src="/ui/includes/membre-dialog-filtres-avances.xhtml" />
|
||||
<ui:include src="/ui/includes/membre-dialog-message-groupe.xhtml" />
|
||||
<ui:include src="/ui/includes/membre-dialog-import-export.xhtml" />
|
||||
<ui:include src="/ui/includes/membre-dialog-contact.xhtml" />
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,122 +1,164 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:uf="http://xmlns.jcp.org/jsf/composite/components">
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:define name="title">Organisations - UnionFlow</ui:define>
|
||||
|
||||
<ui:composition template="/templates/main-template.xhtml">
|
||||
<ui:param name="page" value="#{organisationsBean}"/>
|
||||
<ui:define name="title">Gestion des Organisations</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formOrganisations">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête avec titre et action principale (DRY/WOU: card-header) -->
|
||||
<ui:decorate template="/templates/components/cards/card-header.xhtml">
|
||||
<ui:param name="title" value="Gestion des Organisations" />
|
||||
<ui:param name="subtitle" value="Liste complète des organisations avec filtres et actions." />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="actions">
|
||||
<p:button value="Nouvelle Organisation"
|
||||
icon="pi pi-plus"
|
||||
outcome="/pages/secure/organisation/nouvelle"
|
||||
styleClass="ui-button-success" />
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- Statistiques (DRY/WOU: stat-card) -->
|
||||
<div class="grid mb-3">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{organisationsBean.totalOrganisations}" />
|
||||
<ui:param name="label" value="Total" />
|
||||
<ui:param name="icon" value="pi pi-building" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{organisationsBean.organisationsActives}" />
|
||||
<ui:param name="label" value="Actives" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{organisationsBean.organisationsInactives}" />
|
||||
<ui:param name="label" value="Inactives" />
|
||||
<ui:param name="icon" value="pi pi-times-circle" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="rechercheGlobale" value="Rechercher" />
|
||||
<p:inputText id="rechercheGlobale"
|
||||
value="#{organisationsBean.rechercheGlobale}"
|
||||
placeholder="Nom, ville, description..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" update="dtOrganisations" listener="#{organisationsBean.appliquerFiltres}" delay="500"/>
|
||||
</p:inputText>
|
||||
</div>
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- EN-TÊTE -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<div class="card mb-3">
|
||||
<div class="formgrid grid align-items-center">
|
||||
<div class="field col-12 lg:col-8 mb-0">
|
||||
<h2 class="text-primary font-bold mb-1 mt-0">
|
||||
<i class="pi pi-building text-blue-500 mr-2"></i>
|
||||
Organisations
|
||||
</h2>
|
||||
<p class="text-600 m-0">
|
||||
Administration des organisations ·
|
||||
<span class="font-semibold text-900">#{organisationsBean.totalOrganisations}</span> au total ·
|
||||
<span class="font-semibold text-green-600">#{organisationsBean.organisationsActives} active(s)</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filtreStatut"
|
||||
value="#{organisationsBean.filtreStatut}"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{organisationsBean.statutsSelectItems}" />
|
||||
<p:ajax event="change" update="dtOrganisations" listener="#{organisationsBean.appliquerFiltres}"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreType" value="Type" />
|
||||
<p:selectOneMenu id="filtreType"
|
||||
value="#{organisationsBean.filtreType}"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{organisationsBean.typesSelectItems}" />
|
||||
<p:ajax event="change" update="dtOrganisations" listener="#{organisationsBean.appliquerFiltres}"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
action="#{organisationsBean.reinitialiserFiltres}"
|
||||
update="dtOrganisations rechercheGlobale filtreStatut filtreType"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<div class="field col-12 lg:col-4 mb-0 flex justify-content-end gap-2">
|
||||
<h:form id="formEntete">
|
||||
<p:commandButton value="Rafraîchir"
|
||||
icon="pi pi-refresh"
|
||||
action="#{organisationsBean.recharger}"
|
||||
update="@form"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
styleClass="ui-button-secondary ui-button-outlined"
|
||||
actionListener="#{organisationsBean.recharger}"
|
||||
update=":panelKPIs :formOrganisations" />
|
||||
</h:form>
|
||||
<p:button value="Nouvelle organisation"
|
||||
icon="pi pi-plus"
|
||||
styleClass="ui-button-success"
|
||||
outcome="/pages/secure/organisation/nouvelle" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- KPIs -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<h:panelGroup id="panelKPIs" layout="block">
|
||||
<div class="formgrid grid">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Total Organisations" />
|
||||
<ui:param name="value" value="#{organisationsBean.totalOrganisations}" />
|
||||
<ui:param name="icon" value="pi-building" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Actives" />
|
||||
<ui:param name="value" value="#{organisationsBean.organisationsActives}" />
|
||||
<ui:param name="icon" value="pi-check-circle" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="progressValue" value="#{organisationsBean.tauxActivite}" />
|
||||
<ui:param name="noDataLabel" value="Aucune organisation active" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Inactives / Suspendues" />
|
||||
<ui:param name="value" value="#{organisationsBean.organisationsInactives}" />
|
||||
<ui:param name="icon" value="pi-pause-circle" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Taux d'activité" />
|
||||
<ui:param name="value" value="#{organisationsBean.tauxActivite} %" />
|
||||
<ui:param name="icon" value="pi-chart-pie" />
|
||||
<ui:param name="iconColor" value="purple-600" />
|
||||
<ui:param name="progressValue" value="#{organisationsBean.tauxActivite}" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- FILTRES -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<div class="card mb-3">
|
||||
<h5 class="mb-3 mt-0">
|
||||
<i class="pi pi-filter text-blue-500 mr-2"></i>
|
||||
Filtres et Recherche
|
||||
</h5>
|
||||
<h:form id="formFiltres">
|
||||
<div class="formgrid grid align-items-end">
|
||||
<div class="field col-12 md:col-6 lg:col-4">
|
||||
<label for="searchNom" class="block text-900 font-medium mb-2">Nom / Description</label>
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchNom"
|
||||
value="#{organisationsBean.rechercheGlobale}"
|
||||
placeholder="Nom, ville, description..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" delay="400"
|
||||
listener="#{organisationsBean.appliquerFiltres}"
|
||||
update=":formOrganisations:dtOrganisations" />
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filterStatut" class="block text-900 font-medium mb-2">Statut</label>
|
||||
<p:selectOneMenu id="filterStatut"
|
||||
value="#{organisationsBean.filtreStatut}"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{organisationsBean.statutsSelectItems}" />
|
||||
<p:ajax listener="#{organisationsBean.appliquerFiltres}"
|
||||
update=":formOrganisations:dtOrganisations" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filterType" class="block text-900 font-medium mb-2">Type</label>
|
||||
<p:selectOneMenu id="filterType"
|
||||
value="#{organisationsBean.filtreType}"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{organisationsBean.typesSelectItems}" />
|
||||
<p:ajax listener="#{organisationsBean.appliquerFiltres}"
|
||||
update=":formOrganisations:dtOrganisations" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-2">
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
styleClass="ui-button-secondary ui-button-outlined w-full"
|
||||
actionListener="#{organisationsBean.reinitialiserFiltres}"
|
||||
update="@form :formOrganisations:dtOrganisations" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- TABLE -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<div class="card">
|
||||
<h:form id="formOrganisations">
|
||||
<p:messages id="messages" showDetail="true" closable="true" styleClass="mb-3" />
|
||||
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h5 class="m-0">
|
||||
<i class="pi pi-list text-primary mr-2"></i>
|
||||
Liste des Organisations
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<!-- Table des organisations (DRY/WOU: card-simple) -->
|
||||
<ui:decorate template="/templates/components/cards/card-simple.xhtml">
|
||||
<ui:param name="title" value="Liste des Organisations" />
|
||||
<ui:define name="content">
|
||||
<!-- Note: p:dataTable avec var, sortBy, filterBy doit être directement dans la page -->
|
||||
<p:dataTable id="dtOrganisations"
|
||||
value="#{organisationsBean.organisationsFiltrees}"
|
||||
var="org"
|
||||
@@ -124,97 +166,130 @@
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
paginatorPosition="bottom"
|
||||
emptyMessage="Aucune organisation trouvée"
|
||||
styleClass="table-responsive"
|
||||
size="small">
|
||||
|
||||
<!-- Logo (DRY/WOU: organisation-logo) -->
|
||||
<p:column headerText="" style="width: 80px;">
|
||||
<ui:include src="/templates/components/layout/organisation-logo.xhtml">
|
||||
<ui:param name="logo" value="#{org.logo}"/>
|
||||
<ui:param name="size" value="40"/>
|
||||
</ui:include>
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords} organisations"
|
||||
styleClass="p-datatable-sm p-datatable-gridlines p-datatable-striped"
|
||||
emptyMessage="Aucune organisation trouvée">
|
||||
|
||||
<!-- Organisation : nom + type -->
|
||||
<p:column headerText="Organisation" sortBy="#{org.nom}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="flex align-items-center justify-content-center bg-primary-100 border-circle mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem; min-width: 2.5rem;">
|
||||
<i class="pi pi-building text-primary-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-900 font-semibold">#{org.nom}</div>
|
||||
<div class="text-500 text-xs">
|
||||
#{empty org.nomCourt ? '' : org.nomCourt}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<!-- Nom avec sous-titre -->
|
||||
<p:column headerText="Nom" sortBy="#{org.nom}" filterBy="#{org.nom}">
|
||||
<h:outputText value="#{org.nom}" styleClass="font-bold"/>
|
||||
<br/>
|
||||
<h:outputText value="#{org.typeLibelle}" styleClass="text-sm text-500"/>
|
||||
</p:column>
|
||||
|
||||
|
||||
<!-- Type -->
|
||||
<p:column headerText="Type" sortBy="#{org.typeAssociation}" style="width: 150px;">
|
||||
<p:tag value="#{org.typeLibelle}"
|
||||
severity="#{org.typeAssociation == 'LIONS_CLUB' ? 'info' : 'primary'}"/>
|
||||
<p:column headerText="Type" sortBy="#{org.typeAssociation}" style="width: 11rem;">
|
||||
<p:tag value="#{org.typeLibelle}"
|
||||
severity="info"
|
||||
styleClass="text-xs" />
|
||||
</p:column>
|
||||
|
||||
|
||||
<!-- Localisation -->
|
||||
<p:column headerText="Localisation" style="width: 200px;">
|
||||
<i class="pi pi-map-marker mr-2 text-500"/>
|
||||
<h:outputText value="#{org.ville}, #{org.region}"/>
|
||||
<p:column headerText="Localisation" style="width: 13rem;">
|
||||
<div class="flex align-items-center text-700 text-sm">
|
||||
<i class="pi pi-map-marker text-400 mr-1"></i>
|
||||
<span>
|
||||
#{empty org.ville ? '' : org.ville}#{(not empty org.ville and not empty org.region) ? ', ' : ''}#{empty org.region ? '' : org.region}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-400 text-xs mt-1" rendered="#{not empty org.pays}">
|
||||
#{org.pays}
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
|
||||
<!-- Membres -->
|
||||
<p:column headerText="Membres" styleClass="text-center" style="width: 100px;">
|
||||
<p:tag value="#{org.nombreMembres}" severity="info" icon="pi pi-users"/>
|
||||
<p:column headerText="Membres" style="width: 7rem; text-align: center;">
|
||||
<div class="text-center">
|
||||
<span class="text-900 font-bold text-lg">
|
||||
#{empty org.nombreMembres ? 0 : org.nombreMembres}
|
||||
</span>
|
||||
<div class="text-500 text-xs">membres</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
|
||||
<!-- Statut -->
|
||||
<p:column headerText="Statut" sortBy="#{org.statut}" styleClass="text-center" style="width: 100px;">
|
||||
<p:tag value="#{org.statut}"
|
||||
severity="#{org.statut == organisationsBean.statutActive ? 'success' : 'warning'}"
|
||||
icon="#{org.statut == organisationsBean.statutActive ? 'pi pi-check' : 'pi pi-times'}"/>
|
||||
<p:column headerText="Statut" sortBy="#{org.statut}" style="width: 9rem; text-align: center;">
|
||||
<p:tag value="#{org.statut}"
|
||||
severity="#{org.statut == organisationsBean.statutActive ? 'success' :
|
||||
(org.statut == organisationsBean.statutSuspendue ? 'danger' :
|
||||
(org.statut == organisationsBean.statutDissoute ? 'danger' : 'warning'))}"
|
||||
icon="pi #{org.statut == organisationsBean.statutActive ? 'pi-check' :
|
||||
(org.statut == organisationsBean.statutSuspendue ? 'pi-ban' : 'pi-pause')}"
|
||||
styleClass="text-xs w-full" />
|
||||
</p:column>
|
||||
|
||||
<!-- Actions (DRY/WOU: Composite Components) -->
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
|
||||
<!-- Actions -->
|
||||
<p:column headerText="Actions" style="width: 10rem;" exportable="false">
|
||||
<div class="flex gap-1">
|
||||
<!-- DRY/WOU: Composite Component action-button-view -->
|
||||
<uf:action-button-view itemId="#{org.id.toString()}"
|
||||
detailPage="/pages/secure/organisation/detail.xhtml"
|
||||
iconOnly="true"/>
|
||||
<!-- DRY/WOU: button-icon pour Modifier -->
|
||||
<p:button icon="pi pi-eye"
|
||||
title="Voir le détail"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info ui-button-sm"
|
||||
href="/pages/secure/organisation/detail.xhtml?id=#{org.id}" />
|
||||
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
actionListener="#{organisationsBean.setOrganisationSelectionnee(org)}"
|
||||
oncomplete="PF('dlgModifier').show();"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning ui-button-sm"
|
||||
title="Modifier"
|
||||
update=":formModifier"
|
||||
styleClass="ui-button-rounded ui-button-warning"
|
||||
title="Modifier"/>
|
||||
<!-- DRY/WOU: button-icon pour Activer/Désactiver -->
|
||||
<p:commandButton icon="#{org.statut == organisationsBean.statutActive ? 'pi pi-ban' : 'pi pi-check'}"
|
||||
actionListener="#{organisationsBean.basculerStatutOrganisation(org)}"
|
||||
update=":formOrganisations:dtOrganisations :formOrganisations:messages"
|
||||
styleClass="ui-button-rounded #{org.statut == organisationsBean.statutActive ? 'ui-button-secondary' : 'ui-button-success'}"
|
||||
title="#{org.statut == organisationsBean.statutActive ? 'Désactiver' : 'Activer'}">
|
||||
<p:confirm header="Confirmation"
|
||||
message="Êtes-vous sûr de vouloir changer le statut de cette organisation ?"
|
||||
icon="pi pi-exclamation-triangle"/>
|
||||
oncomplete="PF('dlgModifier').show();">
|
||||
<f:setPropertyActionListener target="#{organisationsBean.organisationSelectionnee}" value="#{org}" />
|
||||
</p:commandButton>
|
||||
<!-- DRY/WOU: button-icon pour Supprimer -->
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
actionListener="#{organisationsBean.supprimerOrganisation(org)}"
|
||||
update=":formOrganisations:dtOrganisations :formOrganisations:messages"
|
||||
styleClass="ui-button-rounded ui-button-danger"
|
||||
title="Supprimer">
|
||||
|
||||
<p:commandButton icon="#{org.statut == organisationsBean.statutActive ? 'pi pi-ban' : 'pi pi-check'}"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-sm #{org.statut == organisationsBean.statutActive ? 'ui-button-secondary' : 'ui-button-success'}"
|
||||
title="#{org.statut == organisationsBean.statutActive ? 'Désactiver' : 'Activer'}"
|
||||
actionListener="#{organisationsBean.basculerStatutOrganisation(org)}"
|
||||
update=":panelKPIs :formOrganisations:dtOrganisations :formOrganisations:messages">
|
||||
<p:confirm header="Confirmation"
|
||||
message="Êtes-vous sûr de vouloir supprimer cette organisation ? Cette action est irréversible."
|
||||
icon="pi pi-exclamation-triangle"/>
|
||||
message="Changer le statut de cette organisation ?"
|
||||
icon="pi pi-exclamation-triangle" />
|
||||
</p:commandButton>
|
||||
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger ui-button-sm"
|
||||
title="Supprimer"
|
||||
actionListener="#{organisationsBean.supprimerOrganisation(org)}"
|
||||
update=":panelKPIs :formOrganisations:dtOrganisations :formOrganisations:messages">
|
||||
<p:confirm header="Confirmation"
|
||||
message="Supprimer définitivement cette organisation ? Cette action est irréversible."
|
||||
icon="pi pi-exclamation-triangle" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Dialogue de confirmation global (DRY/WOU: confirm-dialog) -->
|
||||
<ui:include src="/templates/components/dialogs/confirm-dialog.xhtml" />
|
||||
</h:form>
|
||||
|
||||
<!-- Dialogue Modifier Organisation (DRY/WOU: form-dialog) -->
|
||||
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade" responsive="true" width="380">
|
||||
<p:commandButton value="Non"
|
||||
type="button"
|
||||
styleClass="ui-button-secondary ui-button-outlined"
|
||||
icon="pi pi-times"
|
||||
onclick="PF('confirmDialog').hide()" />
|
||||
<p:commandButton value="Oui"
|
||||
type="button"
|
||||
styleClass="ui-button-danger"
|
||||
icon="pi pi-check" />
|
||||
</p:confirmDialog>
|
||||
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
</div><!-- /ui-fluid -->
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- DIALOGUE MODIFICATION -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<ui:decorate template="/templates/components/dialogs/form-dialog.xhtml">
|
||||
<ui:param name="dialogId" value="dlgModifier" />
|
||||
<ui:param name="header" value="Modifier Organisation" />
|
||||
<ui:param name="header" value="Modifier l'organisation" />
|
||||
<ui:param name="widgetVar" value="dlgModifier" />
|
||||
<ui:param name="formId" value="formModifier" />
|
||||
<ui:param name="width" value="900" />
|
||||
@@ -225,27 +300,24 @@
|
||||
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||
<ui:param name="model" value="#{organisationsBean.organisationSelectionnee}" />
|
||||
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||
<ui:param name="completionBean" value="#{organisationsBean}" />
|
||||
</ui:include>
|
||||
</ui:fragment>
|
||||
</ui:define>
|
||||
<ui:define name="footer">
|
||||
<!-- Bouton Annuler : type="button" pour éviter la soumission -->
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
type="button"
|
||||
onclick="PF('dlgModifier').hide();"
|
||||
styleClass="ui-button-secondary" />
|
||||
<!-- DRY/WOU: button-form-submit pour action backend -->
|
||||
<ui:decorate template="/templates/components/buttons/button-form-submit.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{organisationsBean.modifierOrganisation}" />
|
||||
<ui:param name="update" value=":formOrganisations:dtOrganisations :formOrganisations:messages" />
|
||||
<ui:param name="oncomplete" value="if(!args.validationFailed) PF('dlgModifier').hide();" />
|
||||
<ui:param name="severity" value="success" />
|
||||
</ui:decorate>
|
||||
styleClass="ui-button-secondary ui-button-outlined" />
|
||||
<p:commandButton value="Enregistrer"
|
||||
icon="pi pi-check"
|
||||
actionListener="#{organisationsBean.modifierOrganisation}"
|
||||
update=":panelKPIs :formOrganisations:dtOrganisations :formOrganisations:messages"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgModifier').hide();"
|
||||
styleClass="ui-button-success" />
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
</html>
|
||||
|
||||
@@ -1,64 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:composition template="/templates/main-template.xhtml">
|
||||
<ui:param name="page" value="#{organisationsBean}"/>
|
||||
<ui:define name="title">Nouvelle Organisation</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- Initialiser le modèle et le catalogue des types à chaque affichage de la vue -->
|
||||
<f:event type="preRenderView" listener="#{organisationsBean.preparerNouvelleOrganisation}" />
|
||||
|
||||
<h:form id="formNouvelleOrganisation">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div class="mb-2 md:mb-0">
|
||||
<h3 class="m-0">Nouvelle Organisation</h3>
|
||||
<span class="text-600">
|
||||
Renseignez l'ensemble des informations de l'organisation.
|
||||
</span>
|
||||
<!-- En-tête avec titre et actions (DRY/WOU: card-header) -->
|
||||
<ui:decorate template="/templates/components/cards/card-header.xhtml">
|
||||
<ui:param name="title" value="Nouvelle Organisation" />
|
||||
<ui:param name="subtitle" value="Créez une nouvelle organisation en renseignant les informations essentielles." />
|
||||
<ui:param name="icon" value="pi pi-building" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="actions">
|
||||
<!-- Bouton Enregistrer (MethodExpression direct) -->
|
||||
<p:commandButton value="Enregistrer"
|
||||
icon="pi pi-save"
|
||||
action="#{organisationsBean.creerOrganisation}"
|
||||
update="formNouvelleOrganisation messages"
|
||||
styleClass="p-button-success p-button-lg"
|
||||
validateClient="true">
|
||||
<p:confirm header="Confirmation"
|
||||
message="Voulez-vous créer cette organisation ?"
|
||||
icon="pi pi-question-circle"/>
|
||||
</p:commandButton>
|
||||
|
||||
<!-- DRY/WOU: button-secondary pour Annuler -->
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler"/>
|
||||
<ui:param name="icon" value="pi pi-times"/>
|
||||
<ui:param name="outcome" value="/pages/secure/organisation/liste"/>
|
||||
</ui:include>
|
||||
</ui:define>
|
||||
<ui:define name="info">
|
||||
<p class="text-500 text-sm m-0">
|
||||
<i class="pi pi-asterisk text-red-500 mr-1" style="font-size: 0.5rem;"/>
|
||||
Les champs marqués d'un astérisque sont obligatoires
|
||||
</p>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Messages globaux -->
|
||||
<p:messages id="messages" showDetail="true" closable="true" styleClass="mb-3"/>
|
||||
|
||||
<!-- Formulaire (DRY/WOU: card-simple) -->
|
||||
<ui:decorate template="/templates/components/cards/card-simple.xhtml">
|
||||
<ui:param name="styleClass" value="shadow-2" />
|
||||
<ui:define name="content">
|
||||
<!-- DRY/WOU: organisation-form.xhtml include réutilisable -->
|
||||
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||
<ui:param name="model" value="#{organisationsBean.nouvelleOrganisation}" />
|
||||
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||
<ui:param name="completionBean" value="#{organisationsBean}" />
|
||||
</ui:include>
|
||||
|
||||
<!-- Actions du formulaire (bas de page) -->
|
||||
<p:divider styleClass="mt-5"/>
|
||||
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row gap-3 mt-4">
|
||||
<div class="text-600">
|
||||
<i class="pi pi-shield mr-2"/>
|
||||
Toutes les données sont sécurisées et conformes
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<!-- Bouton Réinitialiser avec confirmation -->
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
action="#{organisationsBean.preparerNouvelleOrganisation}"
|
||||
update="formNouvelleOrganisation"
|
||||
styleClass="p-button-outlined p-button-warning"
|
||||
immediate="true">
|
||||
<p:confirm header="Confirmation"
|
||||
message="Réinitialiser le formulaire ? Toutes les données seront perdues."
|
||||
icon="pi pi-exclamation-triangle"/>
|
||||
</p:commandButton>
|
||||
|
||||
<!-- DRY/WOU: button-secondary pour Annuler -->
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler"/>
|
||||
<ui:param name="icon" value="pi pi-times"/>
|
||||
<ui:param name="outcome" value="/pages/secure/organisation/liste"/>
|
||||
</ui:include>
|
||||
|
||||
<!-- Bouton Créer l'organisation (MethodExpression direct) -->
|
||||
<p:commandButton value="Créer l'organisation"
|
||||
icon="pi pi-check"
|
||||
action="#{organisationsBean.creerOrganisation}"
|
||||
update="formNouvelleOrganisation messages"
|
||||
styleClass="p-button-success p-button-lg"
|
||||
validateClient="true">
|
||||
<p:confirm header="Confirmation de création"
|
||||
message="Créer cette organisation avec les informations saisies ?"
|
||||
icon="pi pi-question-circle"/>
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler"/>
|
||||
<ui:param name="icon" value="pi pi-times"/>
|
||||
<ui:param name="outcome" value="/pages/secure/organisation/liste"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Informations de l'Organisation</h5>
|
||||
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||
<ui:param name="model" value="#{organisationsBean.nouvelleOrganisation}" />
|
||||
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<!-- Dialog de confirmation global (DRY/WOU: confirm-dialog) -->
|
||||
<ui:include src="/templates/components/dialogs/confirm-dialog.xhtml" />
|
||||
|
||||
<div class="mt-3 flex justify-content-end gap-2">
|
||||
<!-- DRY/WOU: button-secondary pour navigation -->
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler"/>
|
||||
<ui:param name="icon" value="pi pi-times"/>
|
||||
<ui:param name="outcome" value="/pages/secure/organisation/liste"/>
|
||||
</ui:include>
|
||||
<!-- Bouton Créer : p:commandButton direct car action avec méthode backend -->
|
||||
<p:commandButton value="Créer"
|
||||
icon="pi pi-check"
|
||||
action="#{organisationsBean.creerOrganisation}"
|
||||
update=":formNouvelleOrganisation:messages"
|
||||
styleClass="ui-button-success" />
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
@@ -164,9 +164,11 @@
|
||||
<div class="field">
|
||||
<p:outputLabel for="devise" value="Devise" />
|
||||
<p:selectOneMenu id="devise" value="#{configBean.config.devise}">
|
||||
<f:selectItem itemLabel="FCFA (XOF)" itemValue="XOF" />
|
||||
<f:selectItem itemLabel="Euro (EUR)" itemValue="EUR" />
|
||||
<f:selectItem itemLabel="Dollar (USD)" itemValue="USD" />
|
||||
<f:selectItem itemLabel="XOF — Franc CFA (UEMOA)" itemValue="XOF" />
|
||||
<f:selectItem itemLabel="XAF — Franc CFA (CEMAC)" itemValue="XAF" />
|
||||
<f:selectItem itemLabel="MAD — Dirham marocain" itemValue="MAD" />
|
||||
<f:selectItem itemLabel="NGN — Naira nigérian" itemValue="NGN" />
|
||||
<f:selectItem itemLabel="GHS — Cédi ghanéen" itemValue="GHS" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -156,11 +156,12 @@
|
||||
<p:selectOneMenu id="devise"
|
||||
value="#{configurationBean.deviseDefaut}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="FCFA (Franc CFA)" itemValue="XOF" />
|
||||
<f:selectItem itemLabel="EUR (Euro)" itemValue="EUR" />
|
||||
<f:selectItem itemLabel="USD (Dollar)" itemValue="USD" />
|
||||
<f:selectItem itemLabel="GHS (Cédi Ghana)" itemValue="GHS" />
|
||||
<f:selectItem itemLabel="NGN (Naira Nigeria)" itemValue="NGN" />
|
||||
<f:selectItem itemLabel="XOF — Franc CFA (UEMOA)" itemValue="XOF" />
|
||||
<f:selectItem itemLabel="XAF — Franc CFA (CEMAC)" itemValue="XAF" />
|
||||
<f:selectItem itemLabel="MAD — Dirham marocain" itemValue="MAD" />
|
||||
<f:selectItem itemLabel="GHS — Cédi ghanéen" itemValue="GHS" />
|
||||
<f:selectItem itemLabel="NGN — Naira nigérian" itemValue="NGN" />
|
||||
<f:selectItem itemLabel="ZAR — Rand sud-africain" itemValue="ZAR" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -119,10 +119,7 @@
|
||||
<p:selectOneMenu id="filterType"
|
||||
value="#{entitesGestionBean.filtres.type}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Club Lions" itemValue="CLUB_LIONS" />
|
||||
<f:selectItem itemLabel="LEO Club" itemValue="LEO_CLUB" />
|
||||
<f:selectItem itemLabel="Branche" itemValue="BRANCHE" />
|
||||
<f:selectItems value="#{entitesGestionBean.typesSelectItems}" />
|
||||
<p:ajax update=":formTableEntites:dtEntites" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
@@ -145,11 +142,7 @@
|
||||
<p:selectOneMenu id="filterRegion"
|
||||
value="#{entitesGestionBean.filtres.region}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les régions" itemValue="" />
|
||||
<f:selectItem itemLabel="Dakar" itemValue="DAKAR" />
|
||||
<f:selectItem itemLabel="Thiès" itemValue="THIES" />
|
||||
<f:selectItem itemLabel="Kaolack" itemValue="KAOLACK" />
|
||||
<f:selectItem itemLabel="Saint-Louis" itemValue="SAINT_LOUIS" />
|
||||
<f:selectItems value="#{entitesGestionBean.regionsDisponibles}" />
|
||||
<p:ajax update=":formTableEntites:dtEntites" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
@@ -259,26 +252,23 @@
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:8rem" exportable="false">
|
||||
<h:form id="formActions#{entite.id}">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info ui-button-sm"
|
||||
action="#{entitesGestionBean.voirEntite(entite)}"
|
||||
title="Voir détails" />
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning ui-button-sm"
|
||||
onclick="PF('dlgModifierEntite').show();"
|
||||
title="Modifier">
|
||||
<f:setPropertyActionListener target="#{entitesGestionBean.entiteSelectionne}" value="#{entite}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-cog"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary ui-button-sm"
|
||||
onclick="PF('dlgActionsEntite').show();"
|
||||
title="Actions">
|
||||
<f:setPropertyActionListener target="#{entitesGestionBean.entiteSelectionne}" value="#{entite}" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</h:form>
|
||||
<div class="flex gap-1">
|
||||
<p:button icon="pi pi-eye"
|
||||
title="Voir détails"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info ui-button-sm"
|
||||
href="/pages/secure/organisation/detail.xhtml?id=#{entite.id}" />
|
||||
<p:button icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning ui-button-sm"
|
||||
title="Modifier"
|
||||
href="/pages/secure/organisation/detail.xhtml?id=#{entite.id}&mode=edit" />
|
||||
<p:commandButton icon="pi pi-cog"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary ui-button-sm"
|
||||
title="Actions"
|
||||
update=":formActionsEntite"
|
||||
oncomplete="PF('dlgActionsEntite').show();">
|
||||
<f:setPropertyActionListener target="#{entitesGestionBean.entiteSelectionne}" value="#{entite}" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
@@ -308,25 +298,19 @@
|
||||
<label for="newType" class="block text-900 font-medium mb-2">Type d'entité *</label>
|
||||
<p:selectOneMenu id="newType"
|
||||
value="#{entitesGestionBean.nouvelleEntite.type}"
|
||||
required="true">
|
||||
<f:selectItem itemLabel="Sélectionner un type" itemValue="" />
|
||||
<f:selectItem itemLabel="Club Lions" itemValue="CLUB_LIONS" />
|
||||
<f:selectItem itemLabel="LEO Club" itemValue="LEO_CLUB" />
|
||||
<f:selectItem itemLabel="Branche" itemValue="BRANCHE" />
|
||||
required="true"
|
||||
requiredMessage="Le type d'entité est requis.">
|
||||
<f:selectItems value="#{entitesGestionBean.typesSelectItemsForForm}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="newType" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="newRegion" class="block text-900 font-medium mb-2">Région *</label>
|
||||
<p:selectOneMenu id="newRegion"
|
||||
value="#{entitesGestionBean.nouvelleEntite.region}"
|
||||
required="true">
|
||||
<f:selectItem itemLabel="Sélectionner une région" itemValue="" />
|
||||
<f:selectItem itemLabel="Dakar" itemValue="DAKAR" />
|
||||
<f:selectItem itemLabel="Thiès" itemValue="THIES" />
|
||||
<f:selectItem itemLabel="Kaolack" itemValue="KAOLACK" />
|
||||
<f:selectItem itemLabel="Saint-Louis" itemValue="SAINT_LOUIS" />
|
||||
</p:selectOneMenu>
|
||||
<label for="newRegion" class="block text-900 font-medium mb-2">Région</label>
|
||||
<p:inputText id="newRegion"
|
||||
value="#{entitesGestionBean.nouvelleEntite.region}"
|
||||
placeholder="Ex: Lagunes, Dakar, Abidjan..."
|
||||
maxlength="100" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
@@ -394,38 +378,47 @@
|
||||
<p:commandButton value="Gérer les membres"
|
||||
icon="pi pi-users"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm w-full"
|
||||
action="#{entitesGestionBean.gererMembres}" />
|
||||
action="#{entitesGestionBean.gererMembres}"
|
||||
ajax="false" />
|
||||
|
||||
<p:commandButton value="Configuration"
|
||||
icon="pi pi-cog"
|
||||
<p:commandButton value="Voir / Configurer"
|
||||
icon="pi pi-eye"
|
||||
styleClass="ui-button-warning ui-button-outlined ui-button-sm w-full"
|
||||
action="#{entitesGestionBean.configurerEntite}" />
|
||||
action="#{entitesGestionBean.configurerEntite}"
|
||||
ajax="false" />
|
||||
|
||||
<p:commandButton value="Rapports"
|
||||
<p:commandButton value="Rapports & Stats"
|
||||
icon="pi pi-chart-bar"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm w-full"
|
||||
action="#{entitesGestionBean.voirRapports}" />
|
||||
action="#{entitesGestionBean.voirRapports}"
|
||||
ajax="false" />
|
||||
|
||||
<p:commandButton value="Suspendre"
|
||||
icon="pi pi-ban"
|
||||
styleClass="ui-button-danger ui-button-outlined ui-button-sm w-full"
|
||||
action="#{entitesGestionBean.suspendreEntite}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir suspendre cette entité ?');"
|
||||
update=":formTableEntites:dtEntites :formActionsEntite"
|
||||
oncomplete="PF('dlgActionsEntite').hide();"
|
||||
onclick="return confirm('Suspendre cette entité ?');"
|
||||
rendered="#{entitesGestionBean.entiteSelectionne.statut == 'ACTIVE'}" />
|
||||
|
||||
<p:commandButton value="Réactiver"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-success ui-button-outlined ui-button-sm w-full"
|
||||
action="#{entitesGestionBean.reactiverEntite}"
|
||||
update=":formTableEntites:dtEntites :formActionsEntite"
|
||||
oncomplete="PF('dlgActionsEntite').hide();"
|
||||
rendered="#{entitesGestionBean.entiteSelectionne.statut == 'SUSPENDUE'}" />
|
||||
|
||||
<hr class="surface-border" />
|
||||
|
||||
<p:commandButton value="Supprimer"
|
||||
<p:commandButton value="Supprimer définitivement"
|
||||
icon="pi pi-trash"
|
||||
styleClass="ui-button-danger ui-button-sm w-full"
|
||||
onclick="return confirm('ATTENTION: Cette action est irréversible. Confirmer la suppression ?');"
|
||||
action="#{entitesGestionBean.supprimerEntite}" />
|
||||
action="#{entitesGestionBean.supprimerEntite}"
|
||||
update=":formTableEntites:dtEntites"
|
||||
oncomplete="PF('dlgActionsEntite').hide();"
|
||||
onclick="return confirm('ATTENTION : action irréversible. Confirmer la suppression ?');" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
@@ -162,6 +162,7 @@
|
||||
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||
<ui:param name="model" value="#{organisationsBean.nouvelleOrganisation}" />
|
||||
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||
<ui:param name="completionBean" value="#{organisationsBean}" />
|
||||
</ui:include>
|
||||
|
||||
<f:facet name="footer">
|
||||
@@ -191,6 +192,7 @@
|
||||
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||
<ui:param name="model" value="#{organisationsBean.organisationSelectionnee}" />
|
||||
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||
<ui:param name="completionBean" value="#{organisationsBean}" />
|
||||
</ui:include>
|
||||
|
||||
<f:facet name="footer">
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
|
||||
|
||||
<!--
|
||||
Composant bouton icône seule réutilisable (WOU/DRY)
|
||||
@@ -20,9 +21,9 @@
|
||||
<ui:fragment rendered="#{empty rendered or rendered}">
|
||||
<p:commandButton
|
||||
icon="#{icon}"
|
||||
action="#{action}"
|
||||
update="#{update}"
|
||||
onclick="#{onclick}"
|
||||
type="button"
|
||||
disabled="#{not empty disabled and disabled}"
|
||||
styleClass="#{not empty rounded and rounded ? 'ui-button-rounded' : ''} #{not empty text and text ? 'ui-button-text' : ''} #{not empty severity ? 'ui-button-' += severity : ''} #{not empty styleClass ? styleClass : ''}"
|
||||
title="#{title}" />
|
||||
|
||||
@@ -15,21 +15,21 @@
|
||||
-->
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<h:panelGroup layout="block"
|
||||
styleClass="card #{bgColor == 'blue' ? 'bg-blue-100 border-left-3 border-blue-500' : (bgColor == 'green' ? 'bg-green-100 border-left-3 border-green-500' : (bgColor == 'orange' ? 'bg-orange-100 border-left-3 border-orange-500' : 'bg-blue-100 border-left-3 border-blue-500'))}">
|
||||
<h:panelGroup layout="block"
|
||||
styleClass="card bg-#{bgColor}-100 border-left-3 border-#{bgColor}-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<h:panelGroup layout="block"
|
||||
styleClass="font-bold text-xl #{bgColor == 'blue' ? 'text-blue-900' : (bgColor == 'green' ? 'text-green-900' : (bgColor == 'orange' ? 'text-orange-900' : 'text-blue-900'))}">
|
||||
styleClass="font-bold text-xl text-#{bgColor}-900">
|
||||
<h:outputText value="#{value}" />
|
||||
</h:panelGroup>
|
||||
<h:panelGroup layout="block"
|
||||
styleClass="#{bgColor == 'blue' ? 'text-blue-700' : (bgColor == 'green' ? 'text-green-700' : (bgColor == 'orange' ? 'text-orange-700' : 'text-blue-700'))}">
|
||||
styleClass="text-#{bgColor}-700">
|
||||
<h:outputText value="#{label}" />
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
<h:panelGroup layout="block"
|
||||
styleClass="text-white border-round text-center #{bgColor == 'blue' ? 'bg-blue-500' : (bgColor == 'green' ? 'bg-green-500' : (bgColor == 'orange' ? 'bg-orange-500' : 'bg-blue-500'))}"
|
||||
styleClass="text-white border-round text-center bg-#{bgColor}-500"
|
||||
style="width: 2.5rem; height: 2.5rem; line-height: 2.5rem;">
|
||||
<i class="#{icon} text-lg"></i>
|
||||
</h:panelGroup>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Composant colonne Texte avec icône réutilisable - DRY/WOU
|
||||
@@ -14,12 +12,13 @@
|
||||
</ui:include>
|
||||
-->
|
||||
|
||||
<p:column headerText="#{headerText}"
|
||||
style="#{not empty width ? 'width: ' += width : ''}">
|
||||
<p:column headerText="#{headerText}" sortBy="#{sortBy}" filterBy="#{filterBy}"
|
||||
filterMatchMode="#{empty filterMatchMode ? 'contains' : filterMatchMode}"
|
||||
style="#{not empty width ? 'width: ' += width : ''}">
|
||||
<ui:fragment rendered="#{not empty icon}">
|
||||
<i class="#{icon} mr-1"></i>
|
||||
<i class="#{icon} mr-1 text-primary"></i>
|
||||
</ui:fragment>
|
||||
<h:outputText value="#{text}"/>
|
||||
<h:outputText value="#{text}" styleClass="#{not empty styleClass ? styleClass : ''}" />
|
||||
<ui:insert />
|
||||
</p:column>
|
||||
</ui:composition>
|
||||
|
||||
</ui:composition>
|
||||
@@ -11,22 +11,19 @@
|
||||
<ui:param name="value" value="#{bean.property}"/>
|
||||
<ui:param name="multiline" value="true" />
|
||||
</ui:include>
|
||||
Note : utilise l'opérateur EL `empty` pour gérer correctement null,
|
||||
chaînes vides, 0 (entier valide) et false (booléen valide).
|
||||
-->
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="text-600 text-sm mb-1">
|
||||
<h:outputText value="#{label}" />
|
||||
<h:panelGroup rendered="#{not empty value}">
|
||||
<div class="mb-4">
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.09em;color:var(--text-color-secondary);opacity:.7;margin-bottom:.35rem;">
|
||||
<h:outputText value="#{label}" />
|
||||
</div>
|
||||
<div style="font-size:.925rem;font-weight:600;color:var(--text-color);#{multiline ? 'white-space:pre-line;line-height:1.6;' : ''}">
|
||||
<h:outputText value="#{value}" escape="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900">
|
||||
<h:outputText value="#{value}"
|
||||
rendered="#{value != null}"
|
||||
escape="true"
|
||||
style="#{multiline ? 'white-space: pre-line;' : ''}" />
|
||||
<h:outputText value="Non renseigné"
|
||||
rendered="#{value == null}"
|
||||
styleClass="text-400" />
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
</ui:composition>
|
||||
|
||||
|
||||
|
||||
@@ -1,57 +1,12 @@
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui">
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
||||
|
||||
<div class="layout-footer">
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<span class="footer-menutitle">NAVIGATION</span>
|
||||
<ul>
|
||||
<li><a href="/pages/secure/dashboard">Tableau de Bord</a></li>
|
||||
<li><a href="/pages/secure/membre/liste">Membres</a></li>
|
||||
<li><a href="/pages/secure/adhesion/liste">Adhésions</a></li>
|
||||
<li><a href="/pages/secure/aide/documentation">Aide</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<span class="footer-menutitle"></span>
|
||||
<ul>
|
||||
<li><a href="/pages/secure/evenement/calendrier">Calendrier</a></li>
|
||||
<li><a href="/pages/secure/cotisation/historique">Cotisations</a></li>
|
||||
<li><a href="/pages/secure/rapport/membres">Rapports</a></li>
|
||||
<li><a href="/pages/secure/admin/parametres">Paramètres</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-12 md:col-6 lg:col-3">
|
||||
<span class="footer-menutitle">CONTACT</span>
|
||||
<ul>
|
||||
<li>+221 77 123 45 67</li>
|
||||
<li>Plateau, Dakar,</li>
|
||||
<li>Sénégal</li>
|
||||
<li>contact@unionflow.sn</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 md:col-6 lg:col-5">
|
||||
<span class="footer-menutitle">NEWSLETTER</span>
|
||||
<span class="footer-subtitle">Rejoignez notre newsletter pour être informé des nouvelles fonctionnalités.</span>
|
||||
<h:form>
|
||||
<div class="newsletter-input">
|
||||
<p:inputText placeholder="adresse email" />
|
||||
<p:commandButton value="S'abonner" styleClass="ui-button-secondary" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="footer-bottom">
|
||||
<h4>UnionFlow</h4>
|
||||
<h6>Copyright © Lions Dev Team</h6>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="footer-bottom" style="justify-content:space-between;align-items:center;flex-wrap:wrap;gap:.5rem;">
|
||||
<h4 style="margin:0;">UnionFlow</h4>
|
||||
<h6 style="margin:0;opacity:.7;">Copyright © Lions Dev Team</h6>
|
||||
</div>
|
||||
</div>
|
||||
</ui:composition>
|
||||
|
||||
</ui:composition>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<p:menuitem id="m_dashboard" value="Tableau de Bord" icon="pi pi-home" outcome="/pages/secure/dashboard" />
|
||||
|
||||
<!-- Super Administration -->
|
||||
<p:submenu id="m_super_admin" label="Super Administration" icon="pi pi-shield">
|
||||
<p:submenu id="m_super_admin" label="Super Administration" icon="pi pi-shield" rendered="#{menuBean.superAdminMenuVisible}">
|
||||
<p:menuitem id="m_super_dashboard" value="Dashboard Super-Admin" icon="pi pi-chart-bar" outcome="/pages/super-admin/dashboard" />
|
||||
<p:menuitem id="m_gestion_entites" value="Gestion des Entités" icon="pi pi-sitemap" outcome="/pages/super-admin/entites/gestion" />
|
||||
<p:menuitem id="m_gestion_types_organisations" value="Types d'Organisation" icon="pi pi-tags" outcome="/pages/super-admin/types/organisations" />
|
||||
@@ -29,140 +29,154 @@
|
||||
</p:submenu>
|
||||
|
||||
<!-- Administration Générale -->
|
||||
<p:submenu id="m_administration" label="Administration" icon="pi pi-cog">
|
||||
<p:menuitem id="m_gestion_cotisations" value="Gestion Cotisations" icon="pi pi-dollar" outcome="/pages/admin/cotisations/gestion" />
|
||||
<p:menuitem id="m_gestion_evenements" value="Gestion Événements" icon="pi pi-calendar" outcome="/pages/admin/evenements/gestion" />
|
||||
<p:menuitem id="m_demandes_aide" value="Demandes d'Aide" icon="pi pi-heart" outcome="/pages/admin/demandes/gestion" />
|
||||
<p:menuitem id="m_rapports_stats" value="Rapports et Statistiques" icon="pi pi-chart-bar" outcome="/pages/admin/rapports/statistiques" />
|
||||
<p:submenu id="m_administration" label="Administration" icon="pi pi-cog" rendered="#{menuBean.administrationMenuVisible}">
|
||||
<p:menuitem id="m_gestion_cotisations" value="Gestion Cotisations" icon="pi pi-dollar" outcome="/pages/admin/cotisations/gestion" rendered="#{menuBean.cotisationsAdminVisible}" />
|
||||
<p:menuitem id="m_gestion_evenements" value="Gestion Événements" icon="pi pi-calendar" outcome="/pages/admin/evenements/gestion" rendered="#{menuBean.creationEvenementVisible}" />
|
||||
<p:menuitem id="m_demandes_aide" value="Demandes d'Aide" icon="pi pi-heart" outcome="/pages/admin/demandes/gestion" rendered="#{menuBean.traitementAideVisible}" />
|
||||
<p:menuitem id="m_rapports_stats" value="Rapports et Statistiques" icon="pi pi-chart-bar" outcome="/pages/admin/rapports/statistiques" rendered="#{menuBean.rapportsMenuVisible}" />
|
||||
<p:menuitem id="m_gestion_documents" value="Gestion Documents" icon="pi pi-folder" outcome="/pages/admin/documents/gestion" />
|
||||
<p:menuitem id="m_parametres" value="Paramètres Système" icon="pi pi-sliders-h" url="#" />
|
||||
<p:menuitem id="m_utilisateurs" value="Gestion Utilisateurs" icon="pi pi-users" outcome="/pages/admin/utilisateurs/gestion" />
|
||||
<p:menuitem id="m_roles" value="Rôles et Permissions" icon="pi pi-key" outcome="/pages/super-admin/roles/gestion" />
|
||||
<p:menuitem id="m_audit" value="Journal d'Audit" icon="pi pi-file-o" outcome="/pages/admin/audit/journal" />
|
||||
<p:menuitem id="m_parametres" value="Paramètres Système" icon="pi pi-sliders-h" url="#" rendered="#{menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_roles" value="Rôles Applicatifs" icon="pi pi-key" outcome="/pages/super-admin/roles/gestion" rendered="#{menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_audit" value="Journal d'Audit Applicatif" icon="pi pi-file-o" outcome="/pages/admin/audit/journal" rendered="#{menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:separator rendered="#{menuBean.keycloakUserManagerVisible}" />
|
||||
<!-- Lions User Manager - Gestion Keycloak -->
|
||||
<p:menuitem id="m_user_manager_list" value="Utilisateurs Keycloak" icon="pi pi-users-cog" outcome="/pages/user-manager/users/list" rendered="#{menuBean.keycloakUserManagerVisible}" />
|
||||
<p:menuitem id="m_user_manager_create" value="Nouvel Utilisateur Keycloak" icon="pi pi-user-plus" outcome="/pages/user-manager/users/create" rendered="#{menuBean.keycloakUserManagerVisible}" />
|
||||
<p:menuitem id="m_user_manager_roles" value="Rôles Keycloak" icon="pi pi-shield" outcome="/pages/user-manager/roles/list" rendered="#{menuBean.keycloakUserManagerVisible}" />
|
||||
<p:menuitem id="m_user_manager_audit" value="Journal d'Audit Keycloak" icon="pi pi-history" outcome="/pages/user-manager/audit/logs" rendered="#{menuBean.keycloakUserManagerVisible}" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Gestion des Membres -->
|
||||
<p:submenu id="m_membres" label="Gestion des Membres" icon="pi pi-users">
|
||||
<!-- Annuaire des Membres (MEMBRE_ACTIF et plus - Consultation) -->
|
||||
<p:submenu id="m_annuaire" label="Annuaire des Membres" icon="pi pi-users" rendered="#{menuBean.annuaireMembresVisible}">
|
||||
<p:menuitem id="m_liste_membres_lecture" value="Liste des Membres" icon="pi pi-list" outcome="/pages/secure/membre/liste" />
|
||||
<p:menuitem id="m_recherche_membres" value="Rechercher un Membre" icon="pi pi-search" outcome="/pages/secure/membre/recherche" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Gestion des Membres (SECRETAIRE, ADMIN - Administration) -->
|
||||
<p:submenu id="m_gestion_membres" label="Gestion des Membres" icon="pi pi-users-cog" rendered="#{menuBean.gestionMembresMenuVisible}">
|
||||
<p:menuitem id="m_inscription" value="Nouvelle Inscription" icon="pi pi-user-plus" outcome="/pages/secure/membre/inscription" />
|
||||
<p:menuitem id="m_liste_membres" value="Liste des Membres" icon="pi pi-list" outcome="/pages/secure/membre/liste" />
|
||||
<p:menuitem id="m_recherche_membres" value="Recherche Avancée" icon="pi pi-search" outcome="/pages/secure/membre/recherche" />
|
||||
<p:menuitem id="m_profil_membre" value="Mon Profil" icon="pi pi-user" outcome="/pages/secure/membre/profil" />
|
||||
<p:menuitem id="m_liste_membres" value="Liste Complète" icon="pi pi-list" outcome="/pages/secure/membre/liste" />
|
||||
<p:menuitem id="m_validation_membres" value="Validation Inscriptions" icon="pi pi-check-circle" outcome="/pages/secure/membre/validation" />
|
||||
<p:menuitem id="m_import_membres" value="Import en Masse" icon="pi pi-upload" outcome="/pages/secure/membre/import" />
|
||||
<p:menuitem id="m_export_membres" value="Export Membres" icon="pi pi-download" outcome="/pages/secure/membre/export" />
|
||||
<p:separator />
|
||||
<!-- Lions User Manager - Gestion Keycloak -->
|
||||
<p:menuitem id="m_user_manager_list" value="Utilisateurs Keycloak" icon="pi pi-users-cog" outcome="/pages/user-manager/users/list" />
|
||||
<p:menuitem id="m_user_manager_create" value="Nouvel Utilisateur" icon="pi pi-user-plus" outcome="/pages/user-manager/users/create" />
|
||||
<p:menuitem id="m_user_manager_roles" value="Gestion des Rôles" icon="pi pi-shield" outcome="/pages/user-manager/roles/list" />
|
||||
<p:menuitem id="m_user_manager_audit" value="Journal d'Audit" icon="pi pi-history" outcome="/pages/user-manager/audit/logs" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Gestion des Organisations -->
|
||||
<p:submenu id="m_organisations" label="Organisations" icon="pi pi-building">
|
||||
<p:submenu id="m_organisations" label="Organisations" icon="pi pi-building" rendered="#{menuBean.organisationsMenuVisible}">
|
||||
<p:menuitem id="m_liste_organisations" value="Liste des Organisations" icon="pi pi-list" outcome="/pages/secure/organisation/liste" />
|
||||
<p:menuitem id="m_nouvelle_organisation" value="Nouvelle Organisation" icon="pi pi-plus" outcome="/pages/secure/organisation/nouvelle" />
|
||||
<p:menuitem id="m_statistiques_orga" value="Statistiques" icon="pi pi-chart-bar" url="#" />
|
||||
<p:menuitem id="m_statistiques_orga" value="Statistiques" icon="pi pi-chart-bar" outcome="/pages/secure/organisation/statistiques" />
|
||||
</p:submenu>
|
||||
|
||||
|
||||
<!-- Gestion des Adhésions -->
|
||||
<p:submenu id="m_adhesions" label="Gestion des Adhésions" icon="pi pi-bookmark">
|
||||
<p:submenu id="m_adhesions" label="Gestion des Adhésions" icon="pi pi-bookmark" rendered="#{menuBean.adhesionsMenuVisible}">
|
||||
<p:menuitem id="m_demande_adhesion" value="Nouvelle Demande" icon="pi pi-plus-circle" outcome="/pages/secure/adhesion/demande" />
|
||||
<p:menuitem id="m_validation_adhesion" value="Validation des Demandes" icon="pi pi-check-circle" outcome="/pages/secure/adhesion/validation" />
|
||||
<p:menuitem id="m_validation_adhesion" value="Validation des Demandes" icon="pi pi-check-circle" outcome="/pages/secure/adhesion/validation" rendered="#{menuBean.validationAdhesionVisible}" />
|
||||
<p:menuitem id="m_liste_adhesions" value="Toutes les Adhésions" icon="pi pi-list" outcome="/pages/secure/adhesion/liste" />
|
||||
<p:menuitem id="m_renouvellement" value="Renouvellements" icon="pi pi-refresh" outcome="/pages/secure/adhesion/renouvellement" />
|
||||
<p:menuitem id="m_cartes_membres" value="Cartes de Membres" icon="pi pi-id-card" url="#" />
|
||||
<p:menuitem id="m_historique_adhesions" value="Historique" icon="pi pi-history" url="#" />
|
||||
<p:menuitem id="m_cartes_membres" value="Cartes de Membres" icon="pi pi-id-card" outcome="/pages/secure/adhesion/cartes-membres" rendered="#{menuBean.secretaire or menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_historique_adhesions" value="Historique" icon="pi pi-history" outcome="/pages/secure/adhesion/historique" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Gestion Financière -->
|
||||
<p:submenu id="m_finances" label="Gestion Financière" icon="pi pi-dollar">
|
||||
<p:menuitem id="m_cotisations" value="Cotisations" icon="pi pi-credit-card" outcome="/pages/secure/cotisation/paiement" />
|
||||
<p:menuitem id="m_historique_cotisations" value="Historique Paiements" icon="pi pi-history" outcome="/pages/secure/cotisation/historique" />
|
||||
<p:menuitem id="m_relances" value="Relances et Rappels" icon="pi pi-bell" outcome="/pages/secure/cotisation/relances" />
|
||||
<!-- Mes Finances (TOUS - Finances personnelles) -->
|
||||
<p:submenu id="m_mes_finances" label="Mes Finances" icon="pi pi-wallet" rendered="#{menuBean.mesFinancesMenuVisible}">
|
||||
<p:menuitem id="m_mes_cotisations" value="Mes Cotisations" icon="pi pi-credit-card" outcome="/pages/secure/membre/cotisations" rendered="#{menuBean.paiementCotisationVisible}" />
|
||||
<p:menuitem id="m_payer_cotisations" value="Payer mes Cotisations" icon="pi pi-dollar" outcome="/pages/secure/cotisation/paiement" rendered="#{menuBean.paiementCotisationVisible}" />
|
||||
<p:menuitem id="m_historique_finances" value="Historique" icon="pi pi-history" outcome="/pages/secure/cotisation/historique" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Gestion Financière (TRESORIER, ADMIN - Administration finances) -->
|
||||
<p:submenu id="m_gestion_finances" label="Gestion Financière" icon="pi pi-dollar" rendered="#{menuBean.gestionFinancesMenuVisible}">
|
||||
<p:menuitem id="m_tresorerie" value="Trésorerie" icon="pi pi-wallet" outcome="/pages/secure/finance/tresorerie" />
|
||||
<p:menuitem id="m_budgets" value="Gestion des Budgets" icon="pi pi-chart-pie" outcome="/pages/secure/finance/budgets" />
|
||||
<p:menuitem id="m_comptabilite" value="Comptabilité" icon="pi pi-calculator" outcome="/pages/secure/comptabilite/gestion" />
|
||||
<p:menuitem id="m_relances" value="Relances Cotisations" icon="pi pi-bell" outcome="/pages/secure/cotisation/relances" />
|
||||
<p:menuitem id="m_rapports_cotisations" value="Rapports Cotisations" icon="pi pi-chart-bar" outcome="/pages/secure/cotisation/rapports" />
|
||||
<p:menuitem id="m_budgets" value="Gestion des Budgets" icon="pi pi-chart-pie" url="#" />
|
||||
<p:menuitem id="m_tresorerie" value="Trésorerie" icon="pi pi-wallet" url="#" />
|
||||
<p:menuitem id="m_comptabilite" value="Comptabilité" icon="pi pi-calculator" url="#" />
|
||||
<p:menuitem id="m_bilans" value="Bilans Financiers" icon="pi pi-chart-line" url="#" />
|
||||
<p:menuitem id="m_bilans" value="Bilans Financiers" icon="pi pi-chart-line" outcome="/pages/secure/finance/bilans" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Épargne et Crédit (RESPONSABLE_CREDIT, TRESORIER, ADMIN - Spécifique mutuelles) -->
|
||||
<p:submenu id="m_epargne_credit" label="Épargne et Crédit" icon="pi pi-money-bill" rendered="#{menuBean.epargneCreditVisible}">
|
||||
<p:menuitem id="m_demandes_credit" value="Demandes de Crédit" icon="pi pi-inbox" outcome="/pages/secure/credit/demandes" />
|
||||
<p:menuitem id="m_evaluation_credit" value="Évaluation Solvabilité" icon="pi pi-search" outcome="/pages/secure/credit/evaluation" />
|
||||
<p:menuitem id="m_suivi_credits" value="Suivi des Crédits" icon="pi pi-eye" outcome="/pages/secure/credit/suivi" />
|
||||
<p:menuitem id="m_remboursements" value="Remboursements" icon="pi pi-replay" outcome="/pages/secure/credit/remboursements" />
|
||||
<p:menuitem id="m_stats_credit" value="Statistiques Crédit" icon="pi pi-chart-bar" outcome="/pages/secure/credit/statistiques" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Aide Sociale -->
|
||||
<p:submenu id="m_aides" label="Aide Sociale" icon="pi pi-heart">
|
||||
<p:menuitem id="m_demande_aide" value="Nouvelle Demande" icon="pi pi-plus" outcome="/pages/secure/aide/demande" />
|
||||
<!-- Mes Demandes d'Aide (TOUS - Demandes personnelles) -->
|
||||
<p:submenu id="m_mes_aides" label="Aide Sociale" icon="pi pi-heart" rendered="#{menuBean.mesAidesSocialesMenuVisible}">
|
||||
<p:menuitem id="m_demande_aide" value="Faire une Demande" icon="pi pi-plus" outcome="/pages/secure/aide/demande" rendered="#{menuBean.demandeAideSocialeVisible}" />
|
||||
<p:menuitem id="m_mes_demandes_aide" value="Mes Demandes" icon="pi pi-list" outcome="/pages/secure/aide/requests" rendered="#{menuBean.mesDemandesAideVisible}" />
|
||||
<p:menuitem id="m_historique_aides" value="Historique" icon="pi pi-clock" outcome="/pages/secure/aide/historique" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Gestion Aide Sociale (RESPONSABLE_SOCIAL, ADMIN - Administration aide sociale) -->
|
||||
<p:submenu id="m_gestion_aides" label="Gestion Aide Sociale" icon="pi pi-heart-fill" rendered="#{menuBean.gestionAidesSocialesMenuVisible}">
|
||||
<p:menuitem id="m_traitement_aide" value="Traitement des Demandes" icon="pi pi-cog" outcome="/pages/secure/aide/traitement" />
|
||||
<p:menuitem id="m_evaluation_aide" value="Évaluation Sociale" icon="pi pi-search" url="#" />
|
||||
<p:menuitem id="m_suivi_aide" value="Suivi des Bénéficiaires" icon="pi pi-eye" url="#" />
|
||||
<p:menuitem id="m_historique_aides" value="Historique des Aides" icon="pi pi-clock" outcome="/pages/secure/aide/historique" />
|
||||
<p:menuitem id="m_suivi_aide" value="Suivi des Bénéficiaires" icon="pi pi-eye" outcome="/pages/secure/aide/approved" />
|
||||
<p:menuitem id="m_statistiques_aides" value="Statistiques Sociales" icon="pi pi-chart-line" outcome="/pages/secure/aide/statistiques" />
|
||||
<p:menuitem id="m_fonds_solidarite" value="Fonds de Solidarité" icon="pi pi-heart-fill" url="#" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Gestion des Événements -->
|
||||
<p:submenu id="m_evenements" label="Gestion des Événements" icon="pi pi-calendar">
|
||||
<p:menuitem id="m_creation_evenement" value="Nouvel Événement" icon="pi pi-plus" outcome="/pages/secure/evenement/creation" />
|
||||
<!-- Événements (TOUS - Participation) -->
|
||||
<p:submenu id="m_mes_evenements" label="Événements" icon="pi pi-calendar" rendered="#{menuBean.mesEvenementsMenuVisible}">
|
||||
<p:menuitem id="m_calendrier" value="Calendrier" icon="pi pi-calendar-plus" outcome="/pages/secure/evenement/calendrier" />
|
||||
<p:menuitem id="m_mes_inscriptions_events" value="Mes Inscriptions" icon="pi pi-list" outcome="/pages/secure/evenement/participants" rendered="#{menuBean.mesInscriptionsEvenementsVisible}" />
|
||||
<p:menuitem id="m_mes_reservations" value="Mes Réservations" icon="pi pi-ticket" outcome="/pages/secure/evenement/reservations" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Gestion Événements (RESPONSABLE_EVENEMENTS, SECRETAIRE, ADMIN - Organisation) -->
|
||||
<p:submenu id="m_gestion_evenements" label="Gestion Événements" icon="pi pi-calendar-clock" rendered="#{menuBean.gestionEvenementsMenuVisible}">
|
||||
<p:menuitem id="m_creation_evenement" value="Nouvel Événement" icon="pi pi-plus" outcome="/pages/secure/evenement/creation" />
|
||||
<p:menuitem id="m_planification" value="Planification" icon="pi pi-clock" outcome="/pages/secure/evenement/planification" />
|
||||
<p:menuitem id="m_participation" value="Gestion des Participations" icon="pi pi-users" outcome="/pages/secure/evenement/participation" />
|
||||
<p:menuitem id="m_gestion_generale_evenements" value="Gestion Générale" icon="pi pi-cog" outcome="/pages/secure/evenement/gestion" />
|
||||
<p:menuitem id="m_logistique" value="Logistique" icon="pi pi-truck" outcome="/pages/secure/evenement/logistique" />
|
||||
<p:menuitem id="m_bilan_evenements" value="Bilan des Événements" icon="pi pi-chart-bar" outcome="/pages/secure/evenement/bilan" />
|
||||
<p:menuitem id="m_reservations" value="Réservations" icon="pi pi-ticket" outcome="/pages/secure/evenement/reservations" />
|
||||
<p:menuitem id="m_participation" value="Gestion Participations" icon="pi pi-users" outcome="/pages/secure/evenement/participation" />
|
||||
<p:menuitem id="m_gestion_generale_evenements" value="Gestion Générale" icon="pi pi-cog" outcome="/pages/secure/evenement/gestion" />
|
||||
<p:menuitem id="m_bilan_evenements" value="Bilans" icon="pi pi-chart-bar" outcome="/pages/secure/evenement/bilan" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Communication -->
|
||||
<p:submenu id="m_communication" label="Communication" icon="pi pi-envelope">
|
||||
<p:menuitem id="m_messages" value="Centre de Messages" icon="pi pi-inbox" url="#" />
|
||||
<p:menuitem id="m_notifications" value="Notifications" icon="pi pi-bell" url="#" />
|
||||
<p:menuitem id="m_annonces" value="Annonces Officielles" icon="pi pi-megaphone" url="#" />
|
||||
<p:menuitem id="m_newsletter" value="Newsletter" icon="pi pi-send" url="#" />
|
||||
<p:menuitem id="m_sms" value="Envoi SMS" icon="pi pi-mobile" url="#" />
|
||||
<p:menuitem id="m_emailing" value="Campagnes Email" icon="pi pi-at" url="#" />
|
||||
<p:menuitem id="m_reseaux_sociaux" value="Réseaux Sociaux" icon="pi pi-share-alt" url="#" />
|
||||
<!-- Communication (TOUS - Messages et notifications personnelles) -->
|
||||
<p:submenu id="m_mes_communications" label="Communication" icon="pi pi-envelope" rendered="#{menuBean.mesCommunicationsMenuVisible}">
|
||||
<p:menuitem id="m_mes_notifications" value="Mes Notifications" icon="pi pi-bell" outcome="/pages/secure/communication/notifications" />
|
||||
</p:submenu>
|
||||
|
||||
|
||||
<!-- Gestion Documentaire -->
|
||||
<p:submenu id="m_documents" label="Gestion Documentaire" icon="pi pi-folder">
|
||||
<p:submenu id="m_documents" label="Gestion Documentaire" icon="pi pi-folder" rendered="#{menuBean.documentsMenuVisible}">
|
||||
<p:menuitem id="m_bibliotheque" value="Bibliothèque" icon="pi pi-book" url="#" />
|
||||
<p:menuitem id="m_mes_documents" value="Mes Documents" icon="pi pi-file" url="#" />
|
||||
<p:menuitem id="m_modeles" value="Modèles et Templates" icon="pi pi-file-o" url="#" />
|
||||
<p:menuitem id="m_archivage" value="Archivage" icon="pi pi-archive" url="#" />
|
||||
<p:menuitem id="m_mes_documents" value="Mes Documents" icon="pi pi-file" outcome="/pages/secure/documents/mes-documents" />
|
||||
<p:menuitem id="m_modeles" value="Modèles et Templates" icon="pi pi-file-o" url="#" rendered="#{menuBean.secretaire or menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_archivage" value="Archivage" icon="pi pi-archive" url="#" rendered="#{menuBean.secretaire or menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_partage" value="Documents Partagés" icon="pi pi-share-alt" url="#" />
|
||||
<p:menuitem id="m_signatures" value="Signatures Électroniques" icon="pi pi-verified" url="#" />
|
||||
<p:menuitem id="m_workflow_doc" value="Workflow Documentaire" icon="pi pi-sitemap" url="#" />
|
||||
<p:menuitem id="m_signatures" value="Signatures Électroniques" icon="pi pi-verified" url="#" rendered="#{menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_workflow_doc" value="Workflow Documentaire" icon="pi pi-sitemap" url="#" rendered="#{menuBean.secretaire or menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Formation et Développement -->
|
||||
<p:submenu id="m_formation" label="Formation et Développement" icon="pi pi-graduation-cap">
|
||||
<p:menuitem id="m_formations" value="Catalogue de Formations" icon="pi pi-book" url="#" />
|
||||
<p:menuitem id="m_inscriptions_formation" value="Inscriptions" icon="pi pi-user-plus" url="#" />
|
||||
<p:menuitem id="m_planning_formation" value="Planning des Formations" icon="pi pi-calendar" url="#" />
|
||||
<p:menuitem id="m_certifications" value="Certifications" icon="pi pi-verified" url="#" />
|
||||
<p:menuitem id="m_competences" value="Gestion des Compétences" icon="pi pi-star" url="#" />
|
||||
<p:menuitem id="m_e_learning" value="E-Learning" icon="pi pi-desktop" url="#" />
|
||||
<p:menuitem id="m_evaluations" value="Évaluations" icon="pi pi-check-square" url="#" />
|
||||
<!-- Formations (TOUS - Inscriptions et suivi) -->
|
||||
<p:submenu id="m_mes_formations" label="Formations" icon="pi pi-graduation-cap" rendered="#{menuBean.mesFormationsMenuVisible}">
|
||||
<p:menuitem id="m_info_formations" value="Informations" icon="pi pi-info-circle" outcome="/pages/secure/dashboard" />
|
||||
</p:submenu>
|
||||
|
||||
|
||||
<!-- Rapports et Analyses -->
|
||||
<p:submenu id="m_rapports" label="Rapports et Analyses" icon="pi pi-chart-bar">
|
||||
<p:menuitem id="m_tableaux_bord" value="Tableaux de Bord" icon="pi pi-chart-line" url="#" />
|
||||
<p:submenu id="m_rapports" label="Rapports et Analyses" icon="pi pi-chart-bar" rendered="#{menuBean.rapportsMenuVisible}">
|
||||
<p:menuitem id="m_tableaux_bord" value="Tableaux de Bord" icon="pi pi-chart-line" outcome="/pages/secure/rapport/tableaux-bord" />
|
||||
<p:menuitem id="m_rapport_membres" value="Rapport Membres" icon="pi pi-users" outcome="/pages/secure/rapport/membres" />
|
||||
<p:menuitem id="m_rapport_finances" value="Rapport Financier" icon="pi pi-dollar" outcome="/pages/secure/rapport/finances" />
|
||||
<p:menuitem id="m_rapport_finances" value="Rapport Financier" icon="pi pi-dollar" outcome="/pages/secure/rapport/finances" rendered="#{menuBean.rapportFinancierVisible}" />
|
||||
<p:menuitem id="m_rapport_activites" value="Rapport d'Activités" icon="pi pi-chart-line" outcome="/pages/secure/rapport/activites" />
|
||||
<p:menuitem id="m_indicateurs" value="Indicateurs de Performance" icon="pi pi-gauge" url="#" />
|
||||
<p:menuitem id="m_analyses_predicitives" value="Analyses Prédictives" icon="pi pi-eye" url="#" />
|
||||
<p:menuitem id="m_export" value="Exports Personnalisés" icon="pi pi-download" outcome="/pages/secure/rapport/export" />
|
||||
<p:menuitem id="m_indicateurs" value="Indicateurs de Performance" icon="pi pi-gauge" url="#" rendered="#{menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_analyses_predicitives" value="Analyses Prédictives" icon="pi pi-eye" url="#" rendered="#{menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_export" value="Exports Personnalisés" icon="pi pi-download" outcome="/pages/secure/rapport/export" rendered="#{menuBean.exportsPersonnalisesVisible}" />
|
||||
</p:submenu>
|
||||
|
||||
|
||||
<!-- Outils et Utilitaires -->
|
||||
<p:submenu id="m_outils" label="Outils et Utilitaires" icon="pi pi-wrench">
|
||||
<p:submenu id="m_outils" label="Outils et Utilitaires" icon="pi pi-wrench" rendered="#{menuBean.outilsMenuVisible}">
|
||||
<p:menuitem id="m_calculatrices" value="Calculatrices" icon="pi pi-calculator" url="#" />
|
||||
<p:menuitem id="m_generateurs" value="Générateurs" icon="pi pi-cog" url="#" />
|
||||
<p:menuitem id="m_imports" value="Imports de Données" icon="pi pi-upload" url="#" />
|
||||
<p:menuitem id="m_exports_masse" value="Exports en Masse" icon="pi pi-download" url="#" />
|
||||
<p:menuitem id="m_sauvegardes" value="Sauvegardes" icon="pi pi-save" url="#" />
|
||||
<p:menuitem id="m_synchronisation" value="Synchronisation" icon="pi pi-sync" url="#" />
|
||||
<p:menuitem id="m_maintenance" value="Maintenance" icon="pi pi-wrench" url="#" />
|
||||
<p:menuitem id="m_api_externe" value="APIs Externes" icon="pi pi-cloud" url="#" />
|
||||
<p:menuitem id="m_generateurs" value="Générateurs" icon="pi pi-cog" url="#" rendered="#{menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_imports" value="Imports de Données" icon="pi pi-upload" url="#" rendered="#{menuBean.importExportMembreVisible}" />
|
||||
<p:menuitem id="m_exports_masse" value="Exports en Masse" icon="pi pi-download" outcome="/pages/secure/outils/exports-masse" rendered="#{menuBean.exportsPersonnalisesVisible}" />
|
||||
<p:menuitem id="m_sauvegardes" value="Sauvegardes" icon="pi pi-save" url="#" rendered="#{menuBean.maintenanceVisible}" />
|
||||
<p:menuitem id="m_synchronisation" value="Synchronisation" icon="pi pi-sync" url="#" rendered="#{menuBean.adminOrganisation or menuBean.superAdmin}" />
|
||||
<p:menuitem id="m_maintenance" value="Maintenance" icon="pi pi-wrench" url="#" rendered="#{menuBean.maintenanceVisible}" />
|
||||
<p:menuitem id="m_api_externe" value="APIs Externes" icon="pi pi-cloud" url="#" rendered="#{menuBean.superAdmin}" />
|
||||
</p:submenu>
|
||||
|
||||
<!-- Mon Espace Personnel -->
|
||||
|
||||
@@ -4,104 +4,329 @@
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<div class="layout-topbar">
|
||||
<!--
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ UnionFlow - Elite Topbar (Freya Design System) ║
|
||||
║ Real-time Session Monitor | Modern UI | Professional ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
-->
|
||||
|
||||
<h:outputStylesheet library="css" name="topbar-elite.css" />
|
||||
|
||||
<div class="layout-topbar unionflow-elite">
|
||||
<div class="layout-topbar-wrapper">
|
||||
<!-- LEFT SECTION -->
|
||||
<div class="layout-topbar-left">
|
||||
<a href="#" class="menu-button">
|
||||
<i class="pi pi-bars"/>
|
||||
</a>
|
||||
<h:link id="logolink" outcome="/pages/secure/dashboard" styleClass="layout-topbar-logo">
|
||||
<p:graphicImage name="images/#{ guestPreferences.lightLogo ? 'logo-freya-white.svg' : 'logo-freya.svg'}" library="freya-layout" />
|
||||
<p:graphicImage name="images/#{guestPreferences.lightLogo ? 'logo-freya-white.svg' : 'logo-freya.svg'}"
|
||||
library="freya-layout"
|
||||
alt="UnionFlow"
|
||||
title="Retour au tableau de bord"/>
|
||||
</h:link>
|
||||
<span class="app-version">v1.0</span>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- CENTER - Menu -->
|
||||
<ui:include src="/templates/components/layout/menu.xhtml" />
|
||||
|
||||
<!-- RIGHT SECTION -->
|
||||
<div class="layout-topbar-right">
|
||||
<ul class="layout-topbar-actions">
|
||||
<li class="topbar-item search-item ">
|
||||
<a href="#">
|
||||
|
||||
<!-- Search -->
|
||||
<li class="topbar-item search-item">
|
||||
<a href="#" title="Rechercher">
|
||||
<i class="topbar-icon pi pi-search"/>
|
||||
</a>
|
||||
<h:form>
|
||||
<h:panelGroup styleClass="search-input-wrapper">
|
||||
<p:inputText placeholder="Rechercher..." />
|
||||
<i class="pi pi-search"/>
|
||||
</h:panelGroup>
|
||||
</h:form>
|
||||
<ul>
|
||||
<h:form onsubmit="return false;">
|
||||
<h:panelGroup styleClass="search-input-wrapper">
|
||||
<p:inputText placeholder="Rechercher..." />
|
||||
<div class="search-dropdown">
|
||||
<h:form styleClass="search-form-elite">
|
||||
<div class="search-wrapper-elite">
|
||||
<i class="pi pi-search"/>
|
||||
</h:panelGroup>
|
||||
<p:inputText placeholder="Rechercher membres, organisations..."
|
||||
styleClass="search-input"/>
|
||||
<p:commandButton icon="pi pi-arrow-right"
|
||||
styleClass="p-button-rounded p-button-sm"/>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Notifications -->
|
||||
<li class="topbar-item notifications-item">
|
||||
<a href="#" title="Notifications">
|
||||
<i class="topbar-icon pi pi-bell"/>
|
||||
<span class="badge-count">3</span>
|
||||
</a>
|
||||
<ul class="notifications-dropdown">
|
||||
<li class="notif-header">
|
||||
<span class="font-semibold">Notifications</span>
|
||||
<span class="count-label">3 nouvelles</span>
|
||||
</li>
|
||||
<li class="divider"/>
|
||||
<li class="notif-item">
|
||||
<i class="pi pi-info-circle text-blue-500"/>
|
||||
<div>
|
||||
<div class="notif-title">Nouvelle adhésion</div>
|
||||
<div class="notif-time">Il y a 5 min</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="notif-item">
|
||||
<i class="pi pi-check-circle text-green-500"/>
|
||||
<div>
|
||||
<div class="notif-title">Cotisation validée</div>
|
||||
<div class="notif-time">Il y a 1h</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="divider"/>
|
||||
<li class="notif-footer">
|
||||
<a href="#" class="text-primary">Voir tout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="topbar-item user-profile">
|
||||
<a href="#" title="#{userSession.currentUser.nomComplet}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-primary text-white border-round flex align-items-center justify-content-center mr-2"
|
||||
style="width: 32px; height: 32px; font-size: 12px; font-weight: bold;">
|
||||
|
||||
<!-- User Profile -->
|
||||
<li class="topbar-item user-profile elite-user">
|
||||
<a href="#" class="profile-trigger">
|
||||
<div class="avatar-container">
|
||||
<div class="avatar bg-gradient-primary">
|
||||
#{userSession.currentUser.initiales}
|
||||
</div>
|
||||
<div class="text-sm">
|
||||
<div class="text-900 font-medium">#{userSession.currentUser.nomComplet}</div>
|
||||
<div class="text-600 text-xs">#{userSession.typeCompte}</div>
|
||||
<span class="status-dot online"/>
|
||||
</div>
|
||||
|
||||
<div class="user-info">
|
||||
<div class="user-header">
|
||||
<span class="user-name">#{userSession.currentUser.nomComplet}</span>
|
||||
<span class="role-badge">#{userSession.typeCompte}</span>
|
||||
</div>
|
||||
<div class="session-timer">
|
||||
<h:panelGroup id="sessionTimerDisplay">
|
||||
<i class="#{sessionMonitor.timeIndicatorIcon} icon-sm"/>
|
||||
<span class="#{sessionMonitor.timeIndicatorClass} timer-text">
|
||||
#{sessionMonitor.formattedRemainingTime}
|
||||
</span>
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<i class="pi pi-angle-down arrow"/>
|
||||
</a>
|
||||
<ul>
|
||||
<li>
|
||||
<h:form>
|
||||
<p:commandLink action="#{navigationBean.goToProfile}">
|
||||
<i class="pi pi-user mr-2"></i>
|
||||
<span>Mon Profil</span>
|
||||
</p:commandLink>
|
||||
</h:form>
|
||||
</li>
|
||||
<li>
|
||||
<h:form>
|
||||
<p:commandLink action="#{navigationBean.goToSettings}">
|
||||
<i class="pi pi-cog mr-2"></i>
|
||||
<span>Paramètres</span>
|
||||
</p:commandLink>
|
||||
</h:form>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/pages/secure/messages.xhtml">
|
||||
<i class="pi pi-envelope mr-2"></i>
|
||||
<span>Messages</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="border-top-1 surface-border">
|
||||
<div class="p-2 text-xs text-600">
|
||||
<div>Entité: #{userSession.entite.nom}</div>
|
||||
<div>Connecté depuis:
|
||||
<span class="text-green-600">#{jwtTokenManager.timeUntilExpiration / 60} min</span>
|
||||
|
||||
<!-- User Dropdown -->
|
||||
<ul class="user-dropdown elite-dropdown">
|
||||
<!-- Header -->
|
||||
<li class="dropdown-header">
|
||||
<div class="header-content">
|
||||
<div class="header-avatar">
|
||||
<div class="avatar-lg bg-gradient-primary">
|
||||
#{userSession.currentUser.initiales}
|
||||
</div>
|
||||
<span class="status-indicator online">
|
||||
<i class="pi pi-circle-fill"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="header-info">
|
||||
<div class="name">#{userSession.currentUser.nomComplet}</div>
|
||||
<div class="email">#{userSession.currentUser.email}</div>
|
||||
<span class="role-tag">#{userSession.typeCompte}</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<!-- Session Card -->
|
||||
<li class="session-card">
|
||||
<div class="card-content">
|
||||
<div class="info-row">
|
||||
<span class="label">
|
||||
<i class="pi pi-building"/>
|
||||
Organisation
|
||||
</span>
|
||||
<span class="value">#{userSession.entite.nom}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="label">
|
||||
<i class="#{sessionMonitor.timeIndicatorIcon}"/>
|
||||
Temps restant
|
||||
</span>
|
||||
<span class="value #{sessionMonitor.timeIndicatorClass}">
|
||||
#{sessionMonitor.formattedRemainingTime}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Progress Bar -->
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill"
|
||||
style="width: #{100 - sessionMonitor.sessionProgressPercent}%"/>
|
||||
</div>
|
||||
<div class="progress-label">
|
||||
#{sessionMonitor.remainingMinutes} min
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="divider"/>
|
||||
|
||||
<!-- Actions -->
|
||||
<li class="menu-section">
|
||||
<div class="section-title">
|
||||
<i class="pi pi-user"/>
|
||||
Mon Compte
|
||||
</div>
|
||||
<div class="section-items">
|
||||
<h:form>
|
||||
<p:commandLink action="#{navigationBean.goToProfile}"
|
||||
styleClass="menu-item">
|
||||
<i class="pi pi-user-edit"/>
|
||||
<span>Mon Profil</span>
|
||||
<i class="pi pi-angle-right arrow-right"/>
|
||||
</p:commandLink>
|
||||
</h:form>
|
||||
|
||||
<h:form>
|
||||
<p:commandLink action="#{navigationBean.goToSettings}"
|
||||
styleClass="menu-item">
|
||||
<i class="pi pi-cog"/>
|
||||
<span>Paramètres</span>
|
||||
<i class="pi pi-angle-right arrow-right"/>
|
||||
</p:commandLink>
|
||||
</h:form>
|
||||
|
||||
<a href="/pages/secure/messages.xhtml" class="menu-item">
|
||||
<i class="pi pi-envelope"/>
|
||||
<span>Messages</span>
|
||||
<span class="item-badge">2</span>
|
||||
<i class="pi pi-angle-right arrow-right"/>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="divider"/>
|
||||
|
||||
<!-- Preferences -->
|
||||
<li class="menu-section">
|
||||
<div class="section-title">
|
||||
<i class="pi pi-palette"/>
|
||||
Préférences
|
||||
</div>
|
||||
<div class="section-items">
|
||||
<a href="#" class="menu-item">
|
||||
<i class="pi pi-sun"/>
|
||||
<span>Thème</span>
|
||||
<span class="value-badge">Clair</span>
|
||||
</a>
|
||||
<a href="#" class="menu-item">
|
||||
<i class="pi pi-bell"/>
|
||||
<span>Notifications</span>
|
||||
<i class="pi pi-angle-right arrow-right"/>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="divider"/>
|
||||
|
||||
<!-- Support -->
|
||||
<li class="menu-section compact">
|
||||
<div class="section-items">
|
||||
<a href="#" class="menu-item">
|
||||
<i class="pi pi-question-circle text-blue-500"/>
|
||||
<span>Aide</span>
|
||||
</a>
|
||||
<a href="#" class="menu-item">
|
||||
<i class="pi pi-info-circle text-cyan-500"/>
|
||||
<span>À propos</span>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="divider logout-divider"/>
|
||||
|
||||
<!-- Logout -->
|
||||
<li class="logout-section">
|
||||
<h:form>
|
||||
<p:commandLink action="#{loginBean.logout}"
|
||||
styleClass="text-red-600"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir vous déconnecter ?');">
|
||||
<i class="pi pi-sign-out mr-2"></i>
|
||||
<p:commandLink styleClass="logout-btn"
|
||||
onclick="PF('logoutDialog').show(); return false;">
|
||||
<i class="pi pi-sign-out"/>
|
||||
<span>Déconnexion</span>
|
||||
<i class="pi pi-lock ml-auto"/>
|
||||
</p:commandLink>
|
||||
</h:form>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
<a href="#" class="layout-rightpanel-button">
|
||||
<i class="pi pi-arrow-left"></i>
|
||||
|
||||
<a href="#" class="layout-rightpanel-button" title="Configuration">
|
||||
<i class="pi pi-arrow-left"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</ui:composition>
|
||||
<!-- LOGOUT DIALOG -->
|
||||
<p:dialog id="logoutDialog"
|
||||
widgetVar="logoutDialog"
|
||||
header="Confirmation de déconnexion"
|
||||
modal="true"
|
||||
closable="true"
|
||||
styleClass="elite-dialog"
|
||||
responsive="true"
|
||||
width="450">
|
||||
|
||||
<div class="dialog-content">
|
||||
<div class="icon-wrapper">
|
||||
<i class="pi pi-sign-out icon-lg"/>
|
||||
</div>
|
||||
|
||||
<h3 class="dialog-title">Êtes-vous sûr de vouloir vous déconnecter ?</h3>
|
||||
|
||||
<div class="info-box">
|
||||
<div class="info-item">
|
||||
<i class="pi pi-user"/>
|
||||
<span>#{userSession.currentUser.nomComplet}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<i class="pi pi-clock"/>
|
||||
<span>Session: #{sessionMonitor.formattedRemainingTime}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="warning-text">
|
||||
<i class="pi pi-info-circle"/>
|
||||
Vous devrez vous reconnecter pour accéder à l'application.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="dialog-footer">
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
styleClass="p-button-outlined p-button-secondary"
|
||||
onclick="PF('logoutDialog').hide(); return false;"/>
|
||||
|
||||
<h:form>
|
||||
<p:commandButton value="Se déconnecter"
|
||||
icon="pi pi-sign-out"
|
||||
styleClass="p-button-danger"
|
||||
action="#{loginBean.logout}"
|
||||
onclick="PF('logoutDialog').hide();"/>
|
||||
</h:form>
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
|
||||
<!-- SESSION TIMER AUTO-REFRESH -->
|
||||
<h:form id="sessionTimerForm">
|
||||
<p:poll interval="5"
|
||||
listener="#{sessionMonitor.updateActivity}"
|
||||
update=":sessionTimerDisplay"
|
||||
global="false"
|
||||
autoStart="true"/>
|
||||
</h:form>
|
||||
|
||||
</ui:composition>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Fragment réutilisable pour le formulaire d'Organisation
|
||||
Fragment réutilisable pour le formulaire d'Organisation - Version Elite
|
||||
Paramètres attendus via <ui:param>:
|
||||
- model: l'objet cible (ex: #{organisationsBean.nouvelleOrganisation})
|
||||
- typesItems: la liste des SelectItem pour les types
|
||||
@@ -15,18 +15,26 @@
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 1 : INFORMATIONS GÉNÉRALES -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Informations générales" toggleable="true" collapsed="false" styleClass="mb-3">
|
||||
<p:fieldset legend="📋 Informations générales" toggleable="true" collapsed="false" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
<!-- Nom complet -->
|
||||
<div class="field col-12 md:col-8">
|
||||
<p:outputLabel for="nom" value="Nom complet *" styleClass="font-semibold" />
|
||||
<p:outputLabel for="nom" value="Nom complet" styleClass="font-semibold">
|
||||
<span class="text-red-500">*</span>
|
||||
</p:outputLabel>
|
||||
<p:inputText id="nom"
|
||||
value="#{model.nom}"
|
||||
required="true"
|
||||
requiredMessage="Le nom de l'organisation est requis."
|
||||
maxlength="200"
|
||||
placeholder="Ex: Association pour le développement durable" />
|
||||
placeholder="Ex: Association pour le développement durable">
|
||||
<f:validateLength minimum="3" maximum="200" />
|
||||
</p:inputText>
|
||||
<p:message for="nom" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-info-circle mr-1"/>
|
||||
Nom officiel complet de l'organisation (3-200 caractères)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Nom court / Sigle -->
|
||||
@@ -35,53 +43,91 @@
|
||||
<p:inputText id="nomCourt"
|
||||
value="#{model.nomCourt}"
|
||||
maxlength="100"
|
||||
placeholder="Ex: ADD" />
|
||||
placeholder="Ex: ADD">
|
||||
<f:validateLength maximum="100" />
|
||||
</p:inputText>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-tag mr-1"/>
|
||||
Acronyme ou nom abrégé
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Type d'organisation -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="type" value="Type d'organisation *" styleClass="font-semibold" />
|
||||
<p:selectOneMenu id="type"
|
||||
value="#{model.typeAssociation}"
|
||||
<p:outputLabel for="type" value="Type d'organisation" styleClass="font-semibold">
|
||||
<span class="text-red-500">*</span>
|
||||
</p:outputLabel>
|
||||
<p:selectOneMenu id="type"
|
||||
value="#{model.typeAssociation}"
|
||||
required="true"
|
||||
requiredMessage="Le type d'organisation est requis.">
|
||||
<f:selectItem itemLabel="-- Sélectionnez un type --" itemValue="#{null}" noSelectionOption="true" />
|
||||
<f:selectItems value="#{typesItems}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="type" />
|
||||
<p:tooltip for="type" value="Catégorie juridique ou fonctionnelle de l'organisation" position="top"/>
|
||||
</div>
|
||||
|
||||
<!-- Statut de l'organisation -->
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="statut" value="Statut" styleClass="font-semibold">
|
||||
<span class="text-red-500">*</span>
|
||||
</p:outputLabel>
|
||||
<p:selectOneMenu id="statut"
|
||||
value="#{model.statut}"
|
||||
required="true"
|
||||
requiredMessage="Le statut de l'organisation est requis.">
|
||||
<f:selectItem itemLabel="✅ Active" itemValue="ACTIVE" />
|
||||
<f:selectItem itemLabel="🔨 En création" itemValue="EN_CREATION" />
|
||||
<f:selectItem itemLabel="⏸️ Inactive" itemValue="INACTIVE" />
|
||||
<f:selectItem itemLabel="⚠️ Suspendue" itemValue="SUSPENDUE" />
|
||||
<f:selectItem itemLabel="🚫 Dissoute" itemValue="DISSOUTE" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="statut" />
|
||||
<p:tooltip for="statut" value="État actuel de l'organisation - peut être modifié ultérieurement" position="top"/>
|
||||
</div>
|
||||
|
||||
<!-- Date de fondation -->
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="dateFondation" value="Date de fondation" styleClass="font-semibold" />
|
||||
<p:datePicker id="dateFondation"
|
||||
value="#{model.dateFondation}"
|
||||
pattern="dd/MM/yyyy"
|
||||
<p:datePicker id="dateFondation"
|
||||
value="#{model.dateFondation}"
|
||||
pattern="dd/MM/yyyy"
|
||||
showIcon="true"
|
||||
yearNavigator="true"
|
||||
yearRange="1900:2025"
|
||||
maxdate="#{null}"
|
||||
placeholder="jj/mm/aaaa" />
|
||||
<p:tooltip for="dateFondation" value="Date officielle de création de l'organisation" position="top"/>
|
||||
</div>
|
||||
|
||||
<!-- Numéro d'enregistrement -->
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="numEnreg" value="N° d'enregistrement" styleClass="font-semibold" />
|
||||
<p:inputText id="numEnreg"
|
||||
value="#{model.numeroRegistre}"
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="numEnreg" value="N° d'enregistrement / RCCM" styleClass="font-semibold" />
|
||||
<p:inputText id="numEnreg"
|
||||
value="#{model.numeroRegistre}"
|
||||
maxlength="100"
|
||||
placeholder="Ex: RNA-W123456789" />
|
||||
placeholder="Ex: CI-ABJ-01-2024-B12-12345">
|
||||
<f:validateLength maximum="100" />
|
||||
</p:inputText>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-shield mr-1"/>
|
||||
Numéro d'immatriculation officiel (RCCM, RNA, etc.)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="description" value="Description" styleClass="font-semibold" />
|
||||
<p:inputTextarea id="description"
|
||||
value="#{model.description}"
|
||||
rows="4"
|
||||
<p:inputTextarea id="description"
|
||||
value="#{model.description}"
|
||||
rows="4"
|
||||
maxlength="2000"
|
||||
placeholder="Décrivez brièvement l'organisation..."
|
||||
autoResize="false" />
|
||||
<small class="text-muted">#{2000 - (empty model.description ? 0 : model.description.length())} caractères restants</small>
|
||||
placeholder="Décrivez brièvement la mission, les objectifs et les activités principales de l'organisation..."
|
||||
autoResize="false">
|
||||
<f:validateLength maximum="2000" />
|
||||
</p:inputTextarea>
|
||||
<p:message for="description" />
|
||||
<small class="text-500">Maximum 2000 caractères</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:fieldset>
|
||||
@@ -89,76 +135,119 @@
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 2 : COORDONNÉES -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Coordonnées" toggleable="true" collapsed="false" styleClass="mb-3">
|
||||
<p:fieldset legend="📞 Coordonnées" toggleable="true" collapsed="false" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
<!-- Email principal -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="email" value="Email principal" styleClass="font-semibold" />
|
||||
<p:inputText id="email"
|
||||
value="#{model.email}"
|
||||
<p:inputText id="email"
|
||||
value="#{model.email}"
|
||||
maxlength="200"
|
||||
type="email"
|
||||
placeholder="contact@exemple.com" />
|
||||
placeholder="contact@organisation.com">
|
||||
<f:validateLength maximum="200" />
|
||||
</p:inputText>
|
||||
<p:message for="email" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-envelope mr-1"/>
|
||||
Email principal de contact
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Email secondaire -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="email2" value="Email secondaire" styleClass="font-semibold" />
|
||||
<p:inputText id="email2"
|
||||
value="#{model.emailSecondaire}"
|
||||
<p:inputText id="email2"
|
||||
value="#{model.emailSecondaire}"
|
||||
maxlength="200"
|
||||
type="email"
|
||||
placeholder="admin@exemple.com" />
|
||||
placeholder="admin@organisation.com">
|
||||
<f:validateLength maximum="200" />
|
||||
</p:inputText>
|
||||
<p:message for="email2" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-envelope mr-1"/>
|
||||
Email alternatif (optionnel)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Téléphone principal -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="telephone" value="Téléphone principal" styleClass="font-semibold" />
|
||||
<p:inputText id="telephone"
|
||||
value="#{model.telephone}"
|
||||
maxlength="20"
|
||||
placeholder="+225 XX XX XX XX XX" />
|
||||
<p:inputText id="telephone"
|
||||
value="#{model.telephone}"
|
||||
maxlength="30"
|
||||
placeholder="+225 07 00 00 00 00">
|
||||
<f:validateLength maximum="30" />
|
||||
</p:inputText>
|
||||
<p:message for="telephone" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-phone mr-1"/>
|
||||
Numéro principal avec indicatif pays
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Téléphone secondaire -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="telephone2" value="Téléphone secondaire" styleClass="font-semibold" />
|
||||
<p:inputText id="telephone2"
|
||||
value="#{model.telephoneSecondaire}"
|
||||
maxlength="20"
|
||||
placeholder="+225 XX XX XX XX XX" />
|
||||
<p:inputText id="telephone2"
|
||||
value="#{model.telephoneSecondaire}"
|
||||
maxlength="30"
|
||||
placeholder="+221 77 00 00 00">
|
||||
<f:validateLength maximum="30" />
|
||||
</p:inputText>
|
||||
<p:message for="telephone2" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-phone mr-1"/>
|
||||
Numéro alternatif (optionnel)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Site web -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="siteWeb" value="Site web" styleClass="font-semibold" />
|
||||
<p:inputText id="siteWeb"
|
||||
value="#{model.siteWeb}"
|
||||
<p:inputText id="siteWeb"
|
||||
value="#{model.siteWeb}"
|
||||
maxlength="500"
|
||||
placeholder="https://www.exemple.com" />
|
||||
placeholder="https://www.organisation.com">
|
||||
<f:validateLength maximum="500" />
|
||||
</p:inputText>
|
||||
<p:message for="siteWeb" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-globe mr-1"/>
|
||||
URL du site officiel (http:// ou https://)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Logo URL -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="logo" value="Logo (URL)" styleClass="font-semibold" />
|
||||
<p:inputText id="logo"
|
||||
value="#{model.logo}"
|
||||
<p:inputText id="logo"
|
||||
value="#{model.logo}"
|
||||
maxlength="500"
|
||||
placeholder="https://www.exemple.com/logo.png" />
|
||||
placeholder="https://www.organisation.com/logo.png">
|
||||
<f:validateLength maximum="500" />
|
||||
</p:inputText>
|
||||
<p:message for="logo" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-image mr-1"/>
|
||||
Lien vers le logo de l'organisation (PNG, JPG, SVG)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Réseaux sociaux -->
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="reseauxSociaux" value="Réseaux sociaux" styleClass="font-semibold" />
|
||||
<p:inputTextarea id="reseauxSociaux"
|
||||
value="#{model.reseauxSociaux}"
|
||||
rows="3"
|
||||
<p:inputTextarea id="reseauxSociaux"
|
||||
value="#{model.reseauxSociaux}"
|
||||
rows="3"
|
||||
maxlength="1000"
|
||||
placeholder='Ex: {"facebook":"@pageOfficielle", "twitter":"@compte", "linkedin":"entreprise/nom"}'
|
||||
autoResize="false" />
|
||||
<small class="text-muted">Format JSON recommandé</small>
|
||||
placeholder='{"facebook":"@page_officielle", "twitter":"@compte", "linkedin":"entreprise/nom", "instagram":"@profil"}'
|
||||
autoResize="false">
|
||||
<f:validateLength maximum="1000" />
|
||||
</p:inputTextarea>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-share-alt mr-1"/>
|
||||
Format JSON recommandé - Maximum 1000 caractères
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:fieldset>
|
||||
@@ -166,80 +255,174 @@
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 3 : LOCALISATION -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Localisation" toggleable="true" collapsed="false" styleClass="mb-3">
|
||||
<p:fieldset legend="📍 Localisation" toggleable="true" collapsed="false" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
<!-- Adresse complète -->
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="adresse" value="Adresse complète" styleClass="font-semibold" />
|
||||
<p:inputTextarea id="adresse"
|
||||
value="#{model.adresse}"
|
||||
rows="2"
|
||||
<p:inputTextarea id="adresse"
|
||||
value="#{model.adresse}"
|
||||
rows="2"
|
||||
maxlength="500"
|
||||
placeholder="N° rue, quartier..."
|
||||
autoResize="false" />
|
||||
placeholder="N° de la parcelle, nom de la rue, quartier..."
|
||||
autoResize="false">
|
||||
<f:validateLength maximum="500" />
|
||||
</p:inputTextarea>
|
||||
<small class="text-500">Maximum 500 caractères</small>
|
||||
</div>
|
||||
|
||||
<!-- Quartier / Commune -->
|
||||
<div class="field col-12 md:col-5">
|
||||
<p:outputLabel for="quartier" value="Quartier / Commune" styleClass="font-semibold" />
|
||||
<p:inputText id="quartier"
|
||||
value="#{model.quartier}"
|
||||
maxlength="100"
|
||||
placeholder="Ex: Cocody, Hay Riad, Plateau...">
|
||||
<f:validateLength maximum="100" />
|
||||
</p:inputText>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-home mr-1"/>
|
||||
Quartier, commune ou arrondissement
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Ville -->
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:outputLabel for="ville" value="Ville" styleClass="font-semibold" />
|
||||
<p:inputText id="ville"
|
||||
value="#{model.ville}"
|
||||
maxlength="100"
|
||||
placeholder="Ex: Abidjan" />
|
||||
<p:autoComplete id="ville"
|
||||
value="#{model.ville}"
|
||||
completeMethod="#{completionBean.completerVilles}"
|
||||
minQueryLength="1"
|
||||
queryDelay="200"
|
||||
dropdown="true"
|
||||
forceSelection="false"
|
||||
placeholder="Ex: Abidjan"
|
||||
maxlength="100">
|
||||
<f:validateLength maximum="100" />
|
||||
</p:autoComplete>
|
||||
<p:tooltip for="ville" value="Commencez à taper pour voir les suggestions de villes de Côte d'Ivoire" position="top"/>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-building mr-1"/>
|
||||
Ville du siège social
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Code postal -->
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="codePostal" value="Code postal" styleClass="font-semibold" />
|
||||
<p:inputText id="codePostal"
|
||||
value="#{model.codePostal}"
|
||||
maxlength="10"
|
||||
placeholder="Ex: 01 BP 123" />
|
||||
<p:inputText id="codePostal"
|
||||
value="#{model.codePostal}"
|
||||
maxlength="20"
|
||||
placeholder="Ex: 01 BP 123, 75001…">
|
||||
<f:validateLength maximum="20" />
|
||||
</p:inputText>
|
||||
<p:message for="codePostal" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-map-marker mr-1"/>
|
||||
Format : 3-10 caractères (chiffres, lettres, tiret)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Région -->
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="region" value="Région" styleClass="font-semibold" />
|
||||
<p:inputText id="region"
|
||||
value="#{model.region}"
|
||||
maxlength="100"
|
||||
placeholder="Ex: Lagunes" />
|
||||
<p:autoComplete id="region"
|
||||
value="#{model.region}"
|
||||
completeMethod="#{completionBean.completerRegions}"
|
||||
minQueryLength="1"
|
||||
queryDelay="200"
|
||||
dropdown="true"
|
||||
forceSelection="false"
|
||||
placeholder="Ex: Lagunes"
|
||||
maxlength="100">
|
||||
<f:validateLength maximum="100" />
|
||||
</p:autoComplete>
|
||||
<p:tooltip for="region" value="Commencez à taper pour voir les suggestions de régions de Côte d'Ivoire" position="top"/>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-map mr-1"/>
|
||||
Région administrative
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Pays -->
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="pays" value="Pays" styleClass="font-semibold" />
|
||||
<p:inputText id="pays"
|
||||
value="#{model.pays}"
|
||||
maxlength="100"
|
||||
placeholder="Ex: Côte d'Ivoire" />
|
||||
<p:selectOneMenu id="pays"
|
||||
value="#{model.pays}">
|
||||
<f:selectItem itemLabel="— Sélectionner —" itemValue="" />
|
||||
<!-- Afrique de l'Ouest (UEMOA / XOF) -->
|
||||
<f:selectItem itemLabel="🇨🇮 Côte d'Ivoire" itemValue="Côte d'Ivoire" />
|
||||
<f:selectItem itemLabel="🇸🇳 Sénégal" itemValue="Sénégal" />
|
||||
<f:selectItem itemLabel="🇲🇱 Mali" itemValue="Mali" />
|
||||
<f:selectItem itemLabel="🇧🇫 Burkina Faso" itemValue="Burkina Faso" />
|
||||
<f:selectItem itemLabel="🇬🇳 Guinée" itemValue="Guinée" />
|
||||
<f:selectItem itemLabel="🇳🇪 Niger" itemValue="Niger" />
|
||||
<f:selectItem itemLabel="🇹🇬 Togo" itemValue="Togo" />
|
||||
<f:selectItem itemLabel="🇧🇯 Bénin" itemValue="Bénin" />
|
||||
<f:selectItem itemLabel="🇬🇼 Guinée-Bissau" itemValue="Guinée-Bissau" />
|
||||
<!-- Afrique Centrale (CEMAC / XAF) -->
|
||||
<f:selectItem itemLabel="🇨🇲 Cameroun" itemValue="Cameroun" />
|
||||
<f:selectItem itemLabel="🇬🇦 Gabon" itemValue="Gabon" />
|
||||
<f:selectItem itemLabel="🇨🇬 Congo" itemValue="Congo" />
|
||||
<f:selectItem itemLabel="🇨🇩 RD Congo" itemValue="RD Congo" />
|
||||
<f:selectItem itemLabel="🇹🇩 Tchad" itemValue="Tchad" />
|
||||
<f:selectItem itemLabel="🇨🇫 Centrafrique" itemValue="Centrafrique" />
|
||||
<!-- Afrique du Nord -->
|
||||
<f:selectItem itemLabel="🇲🇦 Maroc" itemValue="Maroc" />
|
||||
<f:selectItem itemLabel="🇩🇿 Algérie" itemValue="Algérie" />
|
||||
<f:selectItem itemLabel="🇹🇳 Tunisie" itemValue="Tunisie" />
|
||||
<!-- Autres Afrique -->
|
||||
<f:selectItem itemLabel="🇳🇬 Nigeria" itemValue="Nigeria" />
|
||||
<f:selectItem itemLabel="🇬🇭 Ghana" itemValue="Ghana" />
|
||||
<f:selectItem itemLabel="🇰🇪 Kenya" itemValue="Kenya" />
|
||||
<f:selectItem itemLabel="🇿🇦 Afrique du Sud" itemValue="Afrique du Sud" />
|
||||
<f:selectItem itemLabel="🇷🇼 Rwanda" itemValue="Rwanda" />
|
||||
<f:selectItem itemLabel="🇪🇹 Éthiopie" itemValue="Éthiopie" />
|
||||
<!-- Diaspora / Europe -->
|
||||
<f:selectItem itemLabel="🇫🇷 France" itemValue="France" />
|
||||
<f:selectItem itemLabel="🇧🇪 Belgique" itemValue="Belgique" />
|
||||
<f:selectItem itemLabel="🌍 Autre" itemValue="Autre" />
|
||||
</p:selectOneMenu>
|
||||
<p:tooltip for="pays" value="Pays où l'organisation est enregistrée" position="top"/>
|
||||
</div>
|
||||
|
||||
<!-- Coordonnées GPS -->
|
||||
<div class="field col-12">
|
||||
<p:outputLabel value="Coordonnées GPS" styleClass="font-semibold" />
|
||||
<p:divider styleClass="my-3">
|
||||
<span class="text-600 font-semibold">
|
||||
<i class="pi pi-map-marker mr-2"/>
|
||||
Coordonnées GPS (optionnel)
|
||||
</span>
|
||||
</p:divider>
|
||||
</div>
|
||||
|
||||
<!-- Latitude -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="latitude" value="Latitude" />
|
||||
<p:inputNumber id="latitude"
|
||||
value="#{model.latitude}"
|
||||
<p:outputLabel for="latitude" value="Latitude" styleClass="font-semibold"/>
|
||||
<p:inputNumber id="latitude"
|
||||
value="#{model.latitude}"
|
||||
decimalPlaces="6"
|
||||
minValue="-90"
|
||||
maxValue="90"
|
||||
placeholder="Ex: 5.316667" />
|
||||
<small class="text-muted">Valeur entre -90 et 90</small>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-compass mr-1"/>
|
||||
Valeur entre -90 et 90 (ex: Abidjan ≈ 5.316667)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Longitude -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="longitude" value="Longitude" />
|
||||
<p:inputNumber id="longitude"
|
||||
value="#{model.longitude}"
|
||||
<p:outputLabel for="longitude" value="Longitude" styleClass="font-semibold"/>
|
||||
<p:inputNumber id="longitude"
|
||||
value="#{model.longitude}"
|
||||
decimalPlaces="6"
|
||||
minValue="-180"
|
||||
maxValue="180"
|
||||
placeholder="Ex: -4.033333" />
|
||||
<small class="text-muted">Valeur entre -180 et 180</small>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-compass mr-1"/>
|
||||
Valeur entre -180 et 180 (ex: Abidjan ≈ -4.033333)
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:fieldset>
|
||||
@@ -247,63 +430,103 @@
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 4 : STRUCTURE & HIÉRARCHIE -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Structure & Hiérarchie" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<p:fieldset legend="🏢 Structure & Hiérarchie" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
<!-- Statut juridique -->
|
||||
<div class="field col-12">
|
||||
<p:outputLabel value="Statut juridique" styleClass="font-semibold block mb-3" />
|
||||
<p:outputLabel value="Statut juridique" styleClass="font-semibold block mb-3">
|
||||
<i class="pi pi-building text-primary mr-2"/>
|
||||
</p:outputLabel>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-4">
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="publique" value="#{model.organisationPublique}" />
|
||||
<p:outputLabel for="publique" value="Organisation publique" styleClass="ml-2" />
|
||||
<p:outputLabel for="publique" value="Organisation publique" styleClass="ml-2 font-semibold" />
|
||||
</div>
|
||||
<small class="text-muted block mt-1">Institution étatique ou gouvernementale</small>
|
||||
<small class="text-500 block mt-1">
|
||||
<i class="pi pi-shield mr-1"/>
|
||||
Institution étatique ou gouvernementale
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-4">
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="accepteMembres" value="#{model.accepteNouveauxMembres}" />
|
||||
<p:outputLabel for="accepteMembres" value="Recrutement ouvert" styleClass="ml-2" />
|
||||
<p:outputLabel for="accepteMembres" value="Recrutement ouvert" styleClass="ml-2 font-semibold" />
|
||||
</div>
|
||||
<small class="text-muted block mt-1">Accepte de nouveaux membres</small>
|
||||
<small class="text-500 block mt-1">
|
||||
<i class="pi pi-user-plus mr-1"/>
|
||||
Accepte de nouveaux membres actuellement
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-4">
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="cotisationObl" value="#{model.cotisationObligatoire}" />
|
||||
<p:outputLabel for="cotisationObl" value="Cotisation obligatoire" styleClass="ml-2" />
|
||||
<p:outputLabel for="cotisationObl" value="Cotisation obligatoire" styleClass="ml-2 font-semibold" />
|
||||
</div>
|
||||
<small class="text-muted block mt-1">Adhésion payante requise</small>
|
||||
<small class="text-500 block mt-1">
|
||||
<i class="pi pi-money-bill mr-1"/>
|
||||
Adhésion payante requise pour les membres
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Séparateur visuel -->
|
||||
<div class="field col-12">
|
||||
<p:divider />
|
||||
<p:outputLabel value="Rattachement hiérarchique" styleClass="font-semibold block mb-3" />
|
||||
<p:divider styleClass="my-3">
|
||||
<span class="text-600 font-semibold">
|
||||
<i class="pi pi-sitemap mr-2"/>
|
||||
Rattachement hiérarchique
|
||||
</span>
|
||||
</p:divider>
|
||||
</div>
|
||||
|
||||
<!-- Organisation parente -->
|
||||
<div class="field col-12 md:col-9">
|
||||
<p:outputLabel for="orgParente" value="Organisation parente" styleClass="font-semibold" />
|
||||
<p:inputText id="orgParente"
|
||||
value="#{model.organisationParenteId}"
|
||||
maxlength="36"
|
||||
placeholder="Sélectionner ou saisir l'identifiant de l'organisation mère" />
|
||||
<small class="text-muted">Laisser vide si l'organisation est indépendante ou au sommet de la hiérarchie</small>
|
||||
<p:autoComplete id="orgParente"
|
||||
value="#{model.organisationParenteId}"
|
||||
completeMethod="#{completionBean.rechercherOrganisations}"
|
||||
var="org"
|
||||
itemLabel="#{org.nom}"
|
||||
itemValue="#{org.id}"
|
||||
placeholder="Rechercher une organisation parente..."
|
||||
minQueryLength="2"
|
||||
queryDelay="300"
|
||||
forceSelection="true"
|
||||
dropdown="true"
|
||||
scrollHeight="300"
|
||||
emptyMessage="Aucune organisation trouvée">
|
||||
<p:column headerText="Nom" style="width:60%">
|
||||
<h:outputText value="#{org.nom}" styleClass="font-semibold"/>
|
||||
</p:column>
|
||||
<p:column headerText="Type" style="width:40%">
|
||||
<h:outputText value="#{org.typeLibelle}" styleClass="text-500" />
|
||||
</p:column>
|
||||
</p:autoComplete>
|
||||
<p:message for="orgParente" />
|
||||
<p:tooltip for="orgParente" value="Recherchez et sélectionnez l'organisation mère si cette organisation est une sous-structure. Laissez vide si c'est une organisation racine." position="top"/>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-sitemap mr-1"/>
|
||||
Laisser vide si l'organisation est indépendante ou au sommet de la hiérarchie
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Niveau hiérarchique -->
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="niveau" value="Niveau" styleClass="font-semibold" />
|
||||
<p:inputNumber id="niveau"
|
||||
value="#{model.niveauHierarchique}"
|
||||
<p:outputLabel for="niveau" value="Niveau hiérarchique" styleClass="font-semibold" />
|
||||
<p:inputNumber id="niveau"
|
||||
value="#{model.niveauHierarchique}"
|
||||
decimalPlaces="0"
|
||||
minValue="0"
|
||||
maxValue="10"
|
||||
placeholder="0" />
|
||||
<small class="text-muted">0 = Niveau national/racine<br/>1 = Niveau régional<br/>2+ = Niveaux locaux</small>
|
||||
<small class="text-500">
|
||||
0 = National/Racine<br/>
|
||||
1 = Régional<br/>
|
||||
2+ = Niveaux locaux
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:fieldset>
|
||||
@@ -311,26 +534,34 @@
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 5 : MEMBRES & GOUVERNANCE -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Membres & Gouvernance" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<p:fieldset legend="👥 Membres & Gouvernance" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
<!-- Nombre de membres -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="nbMembres" value="Nombre de membres" styleClass="font-semibold" />
|
||||
<p:inputNumber id="nbMembres"
|
||||
value="#{model.nombreMembres}"
|
||||
<p:inputNumber id="nbMembres"
|
||||
value="#{model.nombreMembres}"
|
||||
decimalPlaces="0"
|
||||
minValue="0"
|
||||
placeholder="0" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-users mr-1"/>
|
||||
Nombre total de membres actifs de l'organisation
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Nombre d'administrateurs -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="nbAdmins" value="Nombre d'administrateurs" styleClass="font-semibold" />
|
||||
<p:inputNumber id="nbAdmins"
|
||||
value="#{model.nombreAdministrateurs}"
|
||||
<p:inputNumber id="nbAdmins"
|
||||
value="#{model.nombreAdministrateurs}"
|
||||
decimalPlaces="0"
|
||||
minValue="0"
|
||||
placeholder="0" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-user-edit mr-1"/>
|
||||
Nombre de membres du bureau exécutif ou du conseil d'administration
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:fieldset>
|
||||
@@ -338,68 +569,114 @@
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 6 : BUDGET & FINANCES -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Budget & Finances" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<p:fieldset legend="💰 Budget & Finances" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
|
||||
<!-- Devise — placée EN PREMIER pour piloter les décimales des champs montants -->
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="devise" value="Devise" styleClass="font-semibold" />
|
||||
<p:selectOneMenu id="devise"
|
||||
value="#{model.devise}">
|
||||
<!-- Devises africaines uniquement -->
|
||||
<!-- Franc CFA : pas de centimes (0 décimale) -->
|
||||
<f:selectItem itemLabel="XOF — Franc CFA (UEMOA)" itemValue="XOF" />
|
||||
<f:selectItem itemLabel="XAF — Franc CFA (CEMAC)" itemValue="XAF" />
|
||||
<!-- Afrique du Nord -->
|
||||
<f:selectItem itemLabel="MAD — Dirham marocain" itemValue="MAD" />
|
||||
<f:selectItem itemLabel="DZD — Dinar algérien" itemValue="DZD" />
|
||||
<f:selectItem itemLabel="TND — Dinar tunisien" itemValue="TND" />
|
||||
<!-- Autres devises africaines (2 décimales) -->
|
||||
<f:selectItem itemLabel="NGN — Naira nigérian" itemValue="NGN" />
|
||||
<f:selectItem itemLabel="GHS — Cedi ghanéen" itemValue="GHS" />
|
||||
<f:selectItem itemLabel="KES — Shilling kényan" itemValue="KES" />
|
||||
<f:selectItem itemLabel="ZAR — Rand sud-africain" itemValue="ZAR" />
|
||||
<p:ajax event="change" update="panelBudget panelCotisation" />
|
||||
</p:selectOneMenu>
|
||||
<p:tooltip for="devise" value="Code ISO 4217 de la devise (3 lettres)" position="top"/>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-info-circle mr-1"/>
|
||||
XOF/XAF (Franc CFA) : entiers, sans centimes
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Budget annuel -->
|
||||
<div class="field col-12 md:col-5">
|
||||
<p:outputLabel for="budget" value="Budget annuel" styleClass="font-semibold" />
|
||||
<p:inputNumber id="budget"
|
||||
value="#{model.budgetAnnuel}"
|
||||
decimalPlaces="2"
|
||||
minValue="0"
|
||||
placeholder="0.00" />
|
||||
</div>
|
||||
|
||||
<!-- Devise -->
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="devise" value="Devise" styleClass="font-semibold" />
|
||||
<p:inputText id="devise"
|
||||
value="#{model.devise}"
|
||||
maxlength="3"
|
||||
placeholder="XOF"
|
||||
style="text-transform: uppercase;" />
|
||||
<small class="text-muted">Code ISO (ex: XOF, EUR)</small>
|
||||
<h:panelGroup id="panelBudget" layout="block">
|
||||
<p:inputNumber id="budget"
|
||||
value="#{model.budgetAnnuel}"
|
||||
decimalPlaces="#{model.devise == 'XOF' or model.devise == 'XAF' ? 0 : 2}"
|
||||
minValue="0"
|
||||
placeholder="#{model.devise == 'XOF' or model.devise == 'XAF' ? '0' : '0,00'}"
|
||||
decimalSeparator=","
|
||||
thousandSeparator=" " />
|
||||
</h:panelGroup>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-chart-line mr-1"/>
|
||||
Budget prévisionnel ou réalisé de l'année en cours
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Montant cotisation -->
|
||||
<div class="field col-12 md:col-5">
|
||||
<p:outputLabel for="montantCotisation" value="Cotisation annuelle" styleClass="font-semibold" />
|
||||
<p:inputNumber id="montantCotisation"
|
||||
value="#{model.montantCotisationAnnuelle}"
|
||||
decimalPlaces="2"
|
||||
minValue="0"
|
||||
placeholder="0.00" />
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:outputLabel for="montantCotisation" value="Cotisation annuelle (membre)" styleClass="font-semibold" />
|
||||
<h:panelGroup id="panelCotisation" layout="block">
|
||||
<p:inputNumber id="montantCotisation"
|
||||
value="#{model.montantCotisationAnnuelle}"
|
||||
decimalPlaces="#{model.devise == 'XOF' or model.devise == 'XAF' ? 0 : 2}"
|
||||
minValue="0"
|
||||
placeholder="#{model.devise == 'XOF' or model.devise == 'XAF' ? '0' : '0,00'}"
|
||||
decimalSeparator=","
|
||||
thousandSeparator=" " />
|
||||
</h:panelGroup>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-wallet mr-1"/>
|
||||
Montant annuel de la cotisation par membre (si applicable)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</p:fieldset>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 7 : MISSION & ACTIVITÉS -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Mission & Activités" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<p:fieldset legend="🎯 Mission & Activités" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
<!-- Objectifs -->
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="objectifs" value="Objectifs stratégiques" styleClass="font-semibold" />
|
||||
<p:inputTextarea id="objectifs"
|
||||
value="#{model.objectifs}"
|
||||
rows="4"
|
||||
<p:inputTextarea id="objectifs"
|
||||
value="#{model.objectifs}"
|
||||
rows="4"
|
||||
maxlength="2000"
|
||||
placeholder="Décrivez les objectifs principaux de l'organisation..."
|
||||
autoResize="false" />
|
||||
<small class="text-muted">#{2000 - (empty model.objectifs ? 0 : model.objectifs.length())} caractères restants</small>
|
||||
placeholder="Décrivez les objectifs principaux de l'organisation, sa vision et ses buts stratégiques..."
|
||||
autoResize="false">
|
||||
<f:validateLength maximum="2000" />
|
||||
</p:inputTextarea>
|
||||
<p:message for="objectifs" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-flag mr-1"/>
|
||||
Maximum 2000 caractères
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Activités principales -->
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="activites" value="Activités principales" styleClass="font-semibold" />
|
||||
<p:inputTextarea id="activites"
|
||||
value="#{model.activitesPrincipales}"
|
||||
rows="4"
|
||||
<p:inputTextarea id="activites"
|
||||
value="#{model.activitesPrincipales}"
|
||||
rows="4"
|
||||
maxlength="2000"
|
||||
placeholder="Décrivez les activités et programmes mis en œuvre..."
|
||||
autoResize="false" />
|
||||
<small class="text-muted">#{2000 - (empty model.activitesPrincipales ? 0 : model.activitesPrincipales.length())} caractères restants</small>
|
||||
placeholder="Décrivez les activités, programmes et initiatives concrètes mis en œuvre par l'organisation..."
|
||||
autoResize="false">
|
||||
<f:validateLength maximum="2000" />
|
||||
</p:inputTextarea>
|
||||
<p:message for="activites" />
|
||||
<small class="text-500">
|
||||
<i class="pi pi-list mr-1"/>
|
||||
Maximum 2000 caractères
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:fieldset>
|
||||
@@ -407,28 +684,40 @@
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 8 : PARTENARIATS & CERTIFICATIONS -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Partenariats & Certifications" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<p:fieldset legend="🤝 Partenariats & Certifications" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
<!-- Certifications / Labels -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="certifications" value="Certifications / Labels" styleClass="font-semibold" />
|
||||
<p:inputTextarea id="certifications"
|
||||
value="#{model.certifications}"
|
||||
rows="3"
|
||||
<p:inputTextarea id="certifications"
|
||||
value="#{model.certifications}"
|
||||
rows="3"
|
||||
maxlength="500"
|
||||
placeholder="Ex: ISO 9001, Label RSE..."
|
||||
autoResize="false" />
|
||||
placeholder="Ex: ISO 9001:2015, Label RSE, Certification Qualité..."
|
||||
autoResize="false">
|
||||
<f:validateLength maximum="500" />
|
||||
</p:inputTextarea>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-verified mr-1"/>
|
||||
Maximum 500 caractères
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Partenaires principaux -->
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="partenaires" value="Partenaires principaux" styleClass="font-semibold" />
|
||||
<p:inputTextarea id="partenaires"
|
||||
value="#{model.partenaires}"
|
||||
rows="3"
|
||||
<p:inputTextarea id="partenaires"
|
||||
value="#{model.partenaires}"
|
||||
rows="3"
|
||||
maxlength="1000"
|
||||
placeholder="Liste des partenaires stratégiques..."
|
||||
autoResize="false" />
|
||||
placeholder="Liste des partenaires stratégiques, bailleurs, organisations partenaires..."
|
||||
autoResize="false">
|
||||
<f:validateLength maximum="1000" />
|
||||
</p:inputTextarea>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-users mr-1"/>
|
||||
Maximum 1000 caractères
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:fieldset>
|
||||
@@ -436,21 +725,26 @@
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<!-- SECTION 9 : NOTES ADMINISTRATIVES -->
|
||||
<!-- ═══════════════════════════════════════════════════════════════ -->
|
||||
<p:fieldset legend="Notes administratives" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<p:fieldset legend="📝 Notes administratives" toggleable="true" collapsed="true" styleClass="mb-3">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="notes" value="Notes internes" styleClass="font-semibold" />
|
||||
<p:inputTextarea id="notes"
|
||||
value="#{model.notes}"
|
||||
rows="4"
|
||||
<p:inputTextarea id="notes"
|
||||
value="#{model.notes}"
|
||||
rows="4"
|
||||
maxlength="1000"
|
||||
placeholder="Notes réservées à l'usage administratif interne..."
|
||||
autoResize="false" />
|
||||
<small class="text-muted">Ces notes ne sont visibles que par les administrateurs</small>
|
||||
placeholder="Notes réservées à l'usage administratif interne, remarques, historique..."
|
||||
autoResize="false">
|
||||
<f:validateLength maximum="1000" />
|
||||
</p:inputTextarea>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-lock mr-1"/>
|
||||
Ces notes ne sont visibles que par les administrateurs - Maximum 1000 caractères
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:fieldset>
|
||||
|
||||
</div>
|
||||
|
||||
</ui:fragment>
|
||||
</ui:fragment>
|
||||
|
||||
Reference in New Issue
Block a user