Configure Maven repository for unionflow-server-api dependency

This commit is contained in:
dahoud
2025-12-10 01:12:54 +00:00
commit 2910809949
1173 changed files with 435718 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
<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 bouton "Consulter" réutilisable - DRY/WOU
Style: Rounded Text (icône + texte)
Usage :
<ui:include src="/templates/components/buttons/action-button-view.xhtml">
<ui:param name="id" value="#{item.id}"/>
<ui:param name="detailPage" value="/pages/secure/organisation/detail.xhtml"/>
<ui:param name="styleClass" value="mr-2"/>
</ui:include>
-->
<p:commandButton value="Consulter"
icon="pi pi-search"
styleClass="ui-button-rounded ui-button-text ui-button-info #{not empty styleClass ? styleClass : ''}"
onclick="window.location='#{request.contextPath}#{detailPage}?id=#{id}';return false;"/>
</ui:composition>

View File

@@ -0,0 +1,33 @@
<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">
<!--
Composant bouton de soumission de formulaire réutilisable (WOU/DRY)
Usage: <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="#{bean.method}" />
<ui:param name="update" value="componentId" />
<ui:param name="oncomplete" value="javascript" />
<ui:param name="severity" value="success|primary|info|warning|danger" />
<ui:param name="disabled" value="false" />
<ui:param name="styleClass" value="" />
</ui:decorate>
-->
<ui:fragment rendered="#{empty rendered or rendered}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
update="#{update}"
oncomplete="#{oncomplete}"
disabled="#{not empty disabled and disabled}"
styleClass="ui-button-#{empty severity ? 'primary' : severity} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:composition>

View File

@@ -0,0 +1,31 @@
<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">
<!--
Composant bouton icône seule réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/buttons/button-icon.xhtml">
<ui:param name="icon" value="pi pi-icon-name" />
<ui:param name="action" value="#{bean.method}" />
<ui:param name="update" value="componentId" />
<ui:param name="onclick" value="javascript" />
<ui:param name="severity" value="info|success|warning|danger" />
<ui:param name="rounded" value="true" />
<ui:param name="text" value="true" />
</ui:include>
-->
<ui:fragment rendered="#{empty rendered or rendered}">
<p:commandButton
icon="#{icon}"
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}" />
</ui:fragment>
</ui:composition>

View File

@@ -0,0 +1,52 @@
<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">
<!--
Composant bouton info réutilisable (WOU/DRY)
-->
<ui:fragment rendered="#{empty rendered or rendered}">
<ui:fragment rendered="#{empty outcome}">
<ui:fragment rendered="#{not empty update and update != 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
update="#{update}"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
type="button"
disabled="#{not empty disabled and disabled}"
rendered="#{empty rendered or rendered}"
styleClass="ui-button-info #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
<ui:fragment rendered="#{empty update or update == 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
ajax="false"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
type="button"
disabled="#{not empty disabled and disabled}"
rendered="#{empty rendered or rendered}"
styleClass="ui-button-info #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
<ui:fragment rendered="#{not empty outcome}">
<p:button
value="#{value}"
icon="#{icon}"
outcome="#{outcome}"
styleClass="ui-button-info #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
</ui:composition>

View File

@@ -0,0 +1,58 @@
<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">
<!--
Composant bouton primaire réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/buttons/button-primary.xhtml">
<ui:param name="value" value="Texte du bouton" />
<ui:param name="icon" value="pi pi-icon-name" />
<ui:param name="action" value="#{bean.method}" />
<ui:param name="outcome" value="/page" />
<ui:param name="update" value="componentId" />
<ui:param name="onclick" value="javascript" />
<ui:param name="disabled" value="false" />
<ui:param name="styleClass" value="" />
</ui:include>
-->
<ui:fragment rendered="#{empty rendered or rendered}">
<ui:fragment rendered="#{empty outcome}">
<ui:fragment rendered="#{not empty update and update != 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
update="#{update}"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
disabled="#{not empty disabled and disabled}"
styleClass="ui-button-primary #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
<ui:fragment rendered="#{empty update or update == 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
ajax="false"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
disabled="#{not empty disabled and disabled}"
styleClass="ui-button-primary #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
<ui:fragment rendered="#{not empty outcome}">
<p:button
value="#{value}"
icon="#{icon}"
outcome="#{outcome}"
styleClass="ui-button-primary #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
</ui:composition>

View File

@@ -0,0 +1,61 @@
<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">
<!--
Composant bouton secondaire réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/buttons/button-secondary.xhtml">
<ui:param name="value" value="Texte du bouton" />
<ui:param name="icon" value="pi pi-icon-name" />
<ui:param name="action" value="#{bean.method}" />
<ui:param name="outcome" value="/page" />
<ui:param name="update" value="componentId" />
<ui:param name="onclick" value="javascript" />
<ui:param name="disabled" value="false" />
<ui:param name="outlined" value="true" />
<ui:param name="styleClass" value="" />
</ui:include>
-->
<ui:fragment rendered="#{empty rendered or rendered}">
<ui:fragment rendered="#{empty outcome}">
<ui:fragment rendered="#{not empty update and update != 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
update="#{update}"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
disabled="#{not empty disabled and disabled}"
rendered="#{empty rendered or rendered}"
styleClass="ui-button-secondary #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
<ui:fragment rendered="#{empty update or update == 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
ajax="false"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
disabled="#{not empty disabled and disabled}"
rendered="#{empty rendered or rendered}"
styleClass="ui-button-secondary #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
<ui:fragment rendered="#{not empty outcome}">
<p:button
value="#{value}"
icon="#{icon}"
outcome="#{outcome}"
styleClass="ui-button-secondary #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
</ui:composition>

View File

@@ -0,0 +1,50 @@
<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">
<!--
Composant bouton succès réutilisable (WOU/DRY)
-->
<ui:fragment rendered="#{empty rendered or rendered}">
<ui:fragment rendered="#{empty outcome}">
<ui:fragment rendered="#{not empty update and update != 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
update="#{update}"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
disabled="#{not empty disabled and disabled}"
rendered="#{empty rendered or rendered}"
styleClass="ui-button-success #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
<ui:fragment rendered="#{empty update or update == 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
ajax="false"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
disabled="#{not empty disabled and disabled}"
rendered="#{empty rendered or rendered}"
styleClass="ui-button-success #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
<ui:fragment rendered="#{not empty outcome}">
<p:button
value="#{value}"
icon="#{icon}"
outcome="#{outcome}"
styleClass="ui-button-success #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
</ui:composition>

View File

@@ -0,0 +1,52 @@
<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">
<!--
Composant bouton warning réutilisable (WOU/DRY)
-->
<ui:fragment rendered="#{empty rendered or rendered}">
<ui:fragment rendered="#{empty outcome}">
<ui:fragment rendered="#{not empty update and update != 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
update="#{update}"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
type="button"
disabled="#{not empty disabled and disabled}"
rendered="#{empty rendered or rendered}"
styleClass="ui-button-warning #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
<ui:fragment rendered="#{empty update or update == 'none'}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
ajax="false"
onclick="#{onclick}"
oncomplete="#{oncomplete}"
type="button"
disabled="#{not empty disabled and disabled}"
rendered="#{empty rendered or rendered}"
styleClass="ui-button-warning #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
<ui:fragment rendered="#{not empty outcome}">
<p:button
value="#{value}"
icon="#{icon}"
outcome="#{outcome}"
styleClass="ui-button-warning #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
title="#{title}" />
</ui:fragment>
</ui:fragment>
</ui:composition>

View File

@@ -0,0 +1,47 @@
<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 card avec en-tête et actions - DRY/WOU
Usage :
<ui:decorate template="/templates/components/cards/card-header.xhtml">
<ui:param name="title" value="Titre de la card"/>
<ui:param name="subtitle" value="Sous-titre optionnel"/>
<ui:param name="styleClass" value="mb-3"/>
<ui:define name="actions">
Boutons d'action ici
</ui:define>
<ui:define name="content">
Contenu de la card ici
</ui:define>
</ui:decorate>
-->
<div class="card #{styleClass}">
<div class="flex justify-content-between align-items-center flex-column md:flex-row mb-3">
<div class="mb-2 md:mb-0">
<ui:fragment rendered="#{not empty title}">
<h3 class="m-0">
<h:outputText value="#{title}" />
</h3>
</ui:fragment>
<ui:fragment rendered="#{not empty subtitle}">
<span class="text-600">
<h:outputText value="#{subtitle}" />
</span>
</ui:fragment>
</div>
<div class="flex gap-2">
<ui:insert name="actions">
<!-- Actions buttons go here -->
</ui:insert>
</div>
</div>
<ui:insert name="content">
<!-- Card content goes here -->
</ui:insert>
</div>
</ui:composition>

View File

@@ -0,0 +1,29 @@
<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 card simple avec titre optionnel - DRY/WOU
Usage :
<ui:decorate template="/templates/components/cards/card-simple.xhtml">
<ui:param name="title" value="Titre de la card"/>
<ui:param name="styleClass" value="mb-3"/>
<ui:define name="content">
Contenu de la card ici
</ui:define>
</ui:decorate>
-->
<div class="card #{styleClass}">
<ui:fragment rendered="#{not empty title}">
<h5 class="mb-3">
<h:outputText value="#{title}" />
</h5>
</ui:fragment>
<ui:insert name="content">
<!-- Card content goes here -->
</ui:insert>
</div>
</ui:composition>

View File

@@ -0,0 +1,38 @@
<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">
<!--
Composant barre de filtres et recherche réutilisable - DRY/WOU
Usage :
<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">
Champs de filtres ici (recherche, dropdowns, etc.)
</ui:define>
<ui:define name="actions">
Boutons d'action (réinitialiser, rafraîchir, etc.)
</ui:define>
</ui:decorate>
-->
<div class="card #{styleClass}">
<ui:fragment rendered="#{not empty title}">
<h5 class="mb-3">
<h:outputText value="#{title}" />
</h5>
</ui:fragment>
<div class="grid">
<ui:insert name="filters">
<!-- Filter fields go here -->
</ui:insert>
<ui:insert name="actions">
<!-- Action buttons go here -->
</ui:insert>
</div>
</div>
</ui:composition>

View File

@@ -0,0 +1,150 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<!--
Composant réutilisable: Carte KPI (Indicateur de Performance)
Paramètres:
- title: Titre du KPI (requis)
- value: Valeur principale à afficher (requis)
- icon: Classe d'icône PrimeIcons (requis, ex: pi-users)
- iconColor: Couleur de l'icône (requis, ex: blue-600, green-600, purple-600, orange-600)
- growthValue: Valeur de croissance (optionnel, ex: "12.5", "5", "+10")
- growthLabel: Libellé de la croissance (optionnel, ex: "ce mois", "vs mois dernier")
- growthType: Type de croissance - "percentage" (défaut) ou "number" ou "status"
- showGrowth: Afficher la section croissance (défaut: true si growthValue fourni)
- noDataLabel: Libellé si pas de données (optionnel, défaut: "Données non disponibles")
- progressValue: Valeur pour la barre de progression 0-100 (optionnel)
- showProgress: Afficher la barre de progression (défaut: true si progressValue fourni)
- statusIcon: Icône de statut au lieu de croissance (optionnel, ex: "pi-check-circle")
- statusLabel: Libellé de statut (optionnel, ex: "En ligne")
- statusValue: Valeur de statut (optionnel, ex: "5 actifs")
- colSize: Taille de colonne (optionnel, défaut: "col-12 md:col-6 lg:col-3")
Exemples d'utilisation:
1. KPI simple avec croissance en pourcentage:
<ui:include src="/templates/components/cards/kpi-card.xhtml">
<ui:param name="title" value="Membres Actifs" />
<ui:param name="value" value="#{bean.totalMembres}" />
<ui:param name="icon" value="pi-users" />
<ui:param name="iconColor" value="blue-600" />
<ui:param name="growthValue" value="#{bean.croissanceMembres}" />
<ui:param name="growthLabel" value="ce mois" />
<ui:param name="progressValue" value="#{bean.pourcentageMembres}" />
</ui:include>
2. KPI avec croissance en nombre:
<ui:include src="/templates/components/cards/kpi-card.xhtml">
<ui:param name="title" value="Organisations" />
<ui:param name="value" value="#{bean.totalEntites}" />
<ui:param name="icon" value="pi-sitemap" />
<ui:param name="iconColor" value="green-600" />
<ui:param name="growthValue" value="#{bean.nouvellesEntites}" />
<ui:param name="growthLabel" value="nouvelles" />
<ui:param name="growthType" value="number" />
<ui:param name="progressValue" value="#{bean.pourcentageOrganisations}" />
</ui:include>
3. KPI avec statut au lieu de croissance:
<ui:include src="/templates/components/cards/kpi-card.xhtml">
<ui:param name="title" value="Activité du Jour" />
<ui:param name="value" value="#{bean.activiteJournaliere}" />
<ui:param name="icon" value="pi-chart-line" />
<ui:param name="iconColor" value="orange-600" />
<ui:param name="statusIcon" value="pi-check-circle" />
<ui:param name="statusLabel" value="En ligne" />
<ui:param name="statusValue" value="#{bean.utilisateursActifs} actifs" />
<ui:param name="progressValue" value="#{bean.pourcentageActivite}" />
</ui:include>
4. KPI sans croissance ni progression:
<ui:include src="/templates/components/cards/kpi-card.xhtml">
<ui:param name="title" value="Total" />
<ui:param name="value" value="#{bean.total}" />
<ui:param name="icon" value="pi-calendar" />
<ui:param name="iconColor" value="purple-600" />
<ui:param name="showGrowth" value="false" />
<ui:param name="showProgress" value="false" />
</ui:include>
-->
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
<ui:param name="showGrowth" value="#{not empty growthValue}" />
<ui:param name="showProgress" value="#{not empty progressValue}" />
<ui:param name="growthType" value="percentage" />
<ui:param name="noDataLabel" value="Données non disponibles" />
<div class="field #{colSize}">
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
<div class="p-4" style="min-height: 9rem;">
<!-- Header: Titre et Icône -->
<div class="flex align-items-center justify-content-between mb-3">
<span class="block text-600 font-medium text-sm">#{title}</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 #{icon} text-#{iconColor} text-lg"></i>
</div>
</div>
<!-- Valeur principale -->
<div class="text-900 font-bold text-2xl mb-3">#{value}</div>
<!-- Section Croissance ou Statut -->
<c:choose>
<!-- Mode Statut (statusIcon fourni) -->
<c:when test="#{not empty statusIcon}">
<div class="flex align-items-center mb-2" rendered="#{not empty statusValue and statusValue != '0'}">
<div class="bg-green-500 border-circle mr-2" style="width: 8px; height: 8px;"></div>
<span class="text-green-600 font-semibold text-sm mr-2">#{statusLabel}</span>
<span class="text-500 text-xs">#{statusValue}</span>
</div>
<div class="text-500 text-xs" rendered="#{empty statusValue or statusValue == '0'}">
Aucun utilisateur actif
</div>
</c:when>
<!-- Mode Croissance -->
<c:otherwise>
<c:choose>
<!-- Croissance en nombre -->
<c:when test="#{growthType == 'number'}">
<div class="flex align-items-center mb-2" rendered="#{showGrowth and not empty growthValue and growthValue != '0' and growthValue != '0.0'}">
<i class="pi pi-arrow-up text-green-500 text-sm mr-2"></i>
<span class="text-green-600 font-semibold text-sm mr-2">+#{growthValue}</span>
<span class="text-500 text-xs">#{growthLabel}</span>
</div>
<div class="text-500 text-xs" rendered="#{not showGrowth or empty growthValue or growthValue == '0' or growthValue == '0.0'}">
#{noDataLabel}
</div>
</c:when>
<!-- Croissance en pourcentage (défaut) -->
<c:otherwise>
<div class="flex align-items-center mb-2" rendered="#{showGrowth and not empty growthValue and growthValue != '0' and growthValue != '0.0'}">
<i class="pi pi-arrow-up text-green-500 text-sm mr-2"></i>
<span class="text-green-600 font-semibold text-sm mr-2">+#{growthValue}%</span>
<span class="text-500 text-xs">#{growthLabel}</span>
</div>
<div class="text-500 text-xs" rendered="#{not showGrowth or empty growthValue or growthValue == '0' or growthValue == '0.0'}">
#{noDataLabel}
</div>
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
<!-- Barre de progression -->
<p:progressBar value="#{progressValue}"
showValue="false"
styleClass="surface-200"
style="height: 0.5rem; width: 100%;"
rendered="#{showProgress}" />
</div>
</div>
</div>
</ui:composition>

View File

@@ -0,0 +1,40 @@
<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">
<!--
Composant carte de statistique réutilisable (WOU/DRY)
Usage: ui:include src="/templates/components/cards/stat-card.xhtml"
ui:param name="value" value="EXPRESSION_EL_ICI"
ui:param name="label" value="Label de la statistique"
ui:param name="icon" value="pi pi-icon-name"
ui:param name="bgColor" value="blue"
bgColor: blue, green, orange, purple, etc.
-->
<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'))}">
<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'))}">
<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'))}">
<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'))}"
style="width: 2.5rem; height: 2.5rem; line-height: 2.5rem;">
<i class="#{icon} text-lg"></i>
</h:panelGroup>
</div>
</h:panelGroup>
</div>
</ui:composition>

View File

@@ -0,0 +1,25 @@
<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 Actions réutilisable - DRY/WOU
Usage :
<ui:decorate template="/templates/components/columns/column-actions.xhtml">
<ui:param name="width" value="220px"/>
<ui:define name="actions">
Boutons d'action ici (view, edit, toggle, delete, etc.)
</ui:define>
</ui:decorate>
-->
<p:column headerText="Actions"
styleClass="text-center"
style="width: #{empty width ? '200px' : width};">
<ui:insert name="actions">
<!-- Action buttons go here -->
</ui:insert>
</p:column>
</ui:composition>

View File

@@ -0,0 +1,25 @@
<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 Logo réutilisable - DRY/WOU
Usage :
<ui:include src="/templates/components/columns/column-logo.xhtml">
<ui:param name="logo" value="#{item.logo}"/>
<ui:param name="size" value="40"/>
<ui:param name="width" value="80px"/>
</ui:include>
-->
<p:column headerText="Logo"
styleClass="text-center"
style="width: #{empty width ? '80px' : width};">
<ui:include src="/templates/components/layout/organisation-logo.xhtml">
<ui:param name="logo" value="#{logo}"/>
<ui:param name="size" value="#{empty size ? '40' : size}"/>
</ui:include>
</p:column>
</ui:composition>

View File

@@ -0,0 +1,28 @@
<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 Nom avec sous-titre réutilisable - DRY/WOU
Usage :
<ui:include src="/templates/components/columns/column-name-with-subtitle.xhtml">
<ui:param name="headerText" value="Nom"/>
<ui:param name="name" value="#{item.nom}"/>
<ui:param name="subtitle" value="#{item.typeLibelle}"/>
<ui:param name="sortBy" value="#{item.nom}"/>
<ui:param name="filterBy" value="#{item.nom}"/>
</ui:include>
-->
<p:column headerText="#{empty headerText ? 'Nom' : headerText}"
sortBy="#{sortBy}"
filterBy="#{filterBy}">
<h:outputText value="#{name}" styleClass="font-bold"/>
<ui:fragment rendered="#{not empty subtitle}">
<br/>
<h:outputText value="#{subtitle}" styleClass="text-sm text-500"/>
</ui:fragment>
</p:column>
</ui:composition>

View File

@@ -0,0 +1,28 @@
<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 Tag réutilisable - DRY/WOU
Usage :
<ui:include src="/templates/components/columns/column-tag.xhtml">
<ui:param name="headerText" value="Type"/>
<ui:param name="value" value="#{item.typeLibelle}"/>
<ui:param name="severity" value="info"/>
<ui:param name="icon" value="pi pi-building"/>
<ui:param name="sortBy" value="#{item.type}"/>
<ui:param name="width" value="150px"/>
</ui:include>
-->
<p:column headerText="#{headerText}"
sortBy="#{sortBy}"
styleClass="#{empty centered or centered ? 'text-center' : ''}"
style="#{not empty width ? 'width: ' += width : ''}">
<p:tag value="#{value}"
severity="#{empty severity ? 'info' : severity}"
icon="#{icon}"/>
</p:column>
</ui:composition>

View File

@@ -0,0 +1,25 @@
<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
Usage :
<ui:include src="/templates/components/columns/column-text-with-icon.xhtml">
<ui:param name="headerText" value="Localisation"/>
<ui:param name="icon" value="pi pi-map-marker"/>
<ui:param name="text" value="#{item.ville}, #{item.region}"/>
<ui:param name="width" value="200px"/>
</ui:include>
-->
<p:column headerText="#{headerText}"
style="#{not empty width ? 'width: ' += width : ''}">
<ui:fragment rendered="#{not empty icon}">
<i class="#{icon} mr-1"></i>
</ui:fragment>
<h:outputText value="#{text}"/>
</p:column>
</ui:composition>

View File

@@ -0,0 +1,53 @@
<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 dialogue de confirmation global réutilisable - DRY/WOU
Usage :
<ui:include src="/templates/components/dialogs/confirm-dialog.xhtml">
<ui:param name="global" value="true"/>
<ui:param name="width" value="400"/>
<ui:param name="confirmLabel" value="Oui"/>
<ui:param name="cancelLabel" value="Non"/>
<ui:param name="confirmIcon" value="pi pi-check"/>
<ui:param name="cancelIcon" value="pi pi-times"/>
<ui:param name="confirmStyleClass" value="ui-button-danger"/>
<ui:param name="cancelStyleClass" value="ui-button-secondary"/>
</ui:include>
Paramètres :
- global : Dialogue global pour toute l'application (défaut: true)
- width : Largeur du dialogue (défaut: 350)
- confirmLabel : Label du bouton de confirmation (défaut: Oui)
- cancelLabel : Label du bouton d'annulation (défaut: Non)
- confirmIcon : Icône du bouton de confirmation (défaut: pi pi-check)
- cancelIcon : Icône du bouton d'annulation (défaut: pi pi-times)
- confirmStyleClass : Style du bouton de confirmation (défaut: ui-button-danger)
- cancelStyleClass : Style du bouton d'annulation (défaut: ui-button-secondary)
- showEffect : Effet d'ouverture (défaut: fade)
- hideEffect : Effet de fermeture (défaut: fade)
- responsive : Responsive (défaut: true)
-->
<p:confirmDialog global="true"
showEffect="fade"
hideEffect="fade"
responsive="true"
width="350">
<p:commandButton value="Non"
type="button"
styleClass="ui-button-secondary"
icon="pi pi-times"
onclick="PF('confirmDialog').hide()"/>
<p:commandButton value="Oui"
type="button"
styleClass="ui-button-danger"
icon="pi pi-check"/>
</p:confirmDialog>
</ui:composition>

View File

@@ -0,0 +1,87 @@
<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">
<!--
Composant dialogue de formulaire réutilisable et responsive - DRY/WOU
Usage :
<ui:decorate template="/templates/components/dialogs/form-dialog.xhtml">
<ui:param name="dialogId" value="dlgNouvelle" />
<ui:param name="header" value="Nouvelle Organisation" />
<ui:param name="widgetVar" value="dlgNouvelle" />
<ui:param name="formId" value="formNouvelle" />
<ui:param name="width" value="900" />
<ui:param name="height" value="600" />
<ui:param name="maximizable" value="true" />
<ui:param name="fitViewport" value="true" />
<ui:define name="content">
Contenu du formulaire ici
</ui:define>
<ui:define name="footer">
Boutons du footer ici
</ui:define>
</ui:decorate>
Paramètres :
- dialogId : ID unique du dialogue (requis)
- header : Titre du dialogue (requis)
- widgetVar : Variable JavaScript pour contrôler le dialogue (requis)
- formId : ID du formulaire (requis)
- width : Largeur (défaut: 600)
- height : Hauteur (optionnel)
- maximizable : Permet de maximiser (défaut: false)
- fitViewport : Ajuste au viewport (défaut: true)
- modal : Modal ou non (défaut: true)
- resizable : Redimensionnable (défaut: false)
- draggable : Déplaçable (défaut: true)
- closable : Bouton fermer (défaut: true)
- showEffect : Effet d'ouverture (défaut: fade)
- hideEffect : Effet de fermeture (défaut: fade)
-->
<h:form id="#{formId}">
<p:dialog id="#{dialogId}"
header="#{header}"
widgetVar="#{widgetVar}"
modal="#{empty modal ? true : modal}"
resizable="#{empty resizable ? false : resizable}"
width="#{empty width ? '600' : width}"
height="#{height}"
responsive="true"
closable="#{empty closable ? true : closable}"
draggable="#{empty draggable ? true : draggable}"
maximizable="#{not empty maximizable and maximizable}"
fitViewport="#{empty fitViewport ? true : fitViewport}"
showEffect="#{empty showEffect ? 'fade' : showEffect}"
hideEffect="#{empty hideEffect ? 'fade' : hideEffect}"
dynamic="true"
styleClass="#{styleClass}">
<div class="ui-fluid">
<div class="grid">
<ui:insert name="content">
<!-- Contenu du formulaire -->
</ui:insert>
</div>
</div>
<f:facet name="footer">
<div class="flex justify-content-end gap-2">
<ui:insert name="footer">
<!-- Footer par défaut : bouton Annuler -->
<p:commandButton value="#{empty cancelLabel ? 'Annuler' : cancelLabel}"
icon="pi pi-times"
type="button"
onclick="PF('#{widgetVar}').hide();"
styleClass="ui-button-secondary" />
</ui:insert>
</div>
</f:facet>
</p:dialog>
</h:form>
</ui:composition>

View File

@@ -0,0 +1,26 @@
<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">
<!--
Composant réutilisable: Champ de détail en ligne (label à gauche, valeur à droite)
Usage:
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
<ui:param name="label" value="Nom complet" />
<ui:param name="value" value="#{bean.property}" />
<ui:param name="valueClass" value="font-bold text-primary" />
<ui:param name="suffix" value="(optionnel)" />
</ui:include>
-->
<div class="flex justify-content-between align-items-center mb-2">
<span class="font-medium text-900">#{label}:</span>
<div class="text-right">
<span class="#{valueClass}">#{value}</span>
<small class="text-600 ml-1" rendered="#{not empty suffix}">#{suffix}</small>
</div>
</div>
</ui:composition>

View File

@@ -0,0 +1,32 @@
<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 d'affichage de détail (lecture seule) réutilisable - DRY/WOU
Usage :
<ui:include src="/templates/components/forms/detail-field.xhtml">
<ui:param name="label" value="Nom complet"/>
<ui:param name="value" value="#{bean.property}"/>
<ui:param name="multiline" value="true" />
</ui:include>
-->
<div class="mb-3">
<div class="text-600 text-sm mb-1">
<h:outputText value="#{label}" />
</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>
</ui:composition>

View File

@@ -0,0 +1,31 @@
<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">
<!--
Composant autoComplete réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-autocomplete.xhtml">
<ui:param name="id" value="searchProfession" />
<ui:param name="label" value="Profession" />
<ui:param name="value" value="#{bean.filtres.profession}" />
<ui:param name="completeMethod" value="#{bean.completerProfessions}" />
<ui:param name="placeholder" value="Saisir une profession..." />
<ui:param name="update" value=":formResultats:dtResultats @(.search-summary)" />
</ui:include>
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" />
<p:autoComplete id="#{id}"
value="#{value}"
completeMethod="#{completeMethod}"
placeholder="#{placeholder}"
styleClass="w-full">
<p:ajax event="itemSelect"
update="#{not empty update ? update : ':formResultats:dtResultats @(.search-summary)'}" />
</p:autoComplete>
</div>
</ui:composition>

View File

@@ -0,0 +1,24 @@
<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">
<!--
Composant checkbox booléenne réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-boolean.xhtml">
<ui:param name="id" value="desEnfants" />
<ui:param name="label" value=" A des enfants déclarés" />
<ui:param name="value" value="#{bean.filtres.desEnfants}" />
<ui:param name="update" value=":formResultats:dtResultats @(.search-summary)" />
</ui:include>
-->
<div class="field">
<p:selectBooleanCheckbox id="#{id}" value="#{value}">
<p:ajax update="#{not empty update ? update : ':formResultats:dtResultats @(.search-summary)'}" />
</p:selectBooleanCheckbox>
<p:outputLabel for="#{id}" value="#{label}" />
</div>
</ui:composition>

View File

@@ -0,0 +1,33 @@
<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">
<!--
Composant champ date réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-calendar.xhtml">
<ui:param name="id" value="fieldId" />
<ui:param name="label" value="Label du champ" />
<ui:param name="value" value="#{bean.property}" />
<ui:param name="required" value="true" />
<ui:param name="pattern" value="dd/MM/yyyy" />
</ui:include>
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" />
<p:calendar id="#{id}"
value="#{value}"
showIcon="true"
navigator="true"
required="#{not empty required and required}"
locale="fr"
pattern="#{not empty pattern ? pattern : 'dd/MM/yyyy'}"
styleClass="w-full">
<p:ajax event="dateSelect"
update="#{not empty update ? update : '@form'}" />
</p:calendar>
</div>
</ui:composition>

View File

@@ -0,0 +1,32 @@
<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">
<!--
Composant selectCheckboxMenu réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-checkbox-menu.xhtml">
<ui:param name="id" value="searchStatut" />
<ui:param name="label" value="Statut" />
<ui:param name="value" value="#{bean.filtres.statuts}" />
<ui:param name="update" value=":formResultats:dtResultats @(.search-summary)" />
<ui:define name="items">
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
<f:selectItem itemLabel="Inactif" itemValue="INACTIF" />
</ui:define>
</ui:include>
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" />
<p:selectCheckboxMenu id="#{id}"
value="#{value}"
multiple="true"
styleClass="w-full">
<ui:insert name="items" />
<p:ajax update="#{not empty update ? update : ':formResultats:dtResultats @(.search-summary)'}" />
</p:selectCheckboxMenu>
</div>
</ui:composition>

View File

@@ -0,0 +1,21 @@
<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">
<!--
Composant groupe de champs (formgrid) réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-group.xhtml">
<ui:param name="content" value="contenu des champs groupés" />
</ui:include>
-->
<div class="formgrid grid">
<ui:fragment rendered="#{not empty content}">
#{content}
</ui:fragment>
<ui:insert />
</div>
</ui:composition>

View File

@@ -0,0 +1,34 @@
<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">
<!--
Composant champ numérique réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-number.xhtml">
<ui:param name="id" value="ageMin" />
<ui:param name="label" value="Âge minimum" />
<ui:param name="value" value="#{bean.filtres.ageMin}" />
<ui:param name="placeholder" value="Ex: 25" />
<ui:param name="minValue" value="0" />
<ui:param name="maxValue" value="100" />
<ui:param name="update" value=":formResultats:dtResultats @(.search-summary)" />
</ui:include>
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" />
<p:inputNumber id="#{id}"
value="#{value}"
symbol=""
placeholder="#{placeholder}"
minValue="#{minValue}"
maxValue="#{maxValue}"
styleClass="w-full">
<p:ajax event="change"
update="#{not empty update ? update : ':formResultats:dtResultats @(.search-summary)'}" />
</p:inputNumber>
</div>
</ui:composition>

View File

@@ -0,0 +1,31 @@
<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">
<!--
Composant champ de recherche texte avec AJAX réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-search-text.xhtml">
<ui:param name="id" value="searchNom" />
<ui:param name="label" value="Nom" />
<ui:param name="value" value="#{bean.filtres.nom}" />
<ui:param name="placeholder" value="Rechercher par nom..." />
<ui:param name="update" value=":formResultats:dtResultats @(.search-summary)" />
<ui:param name="event" value="keyup" />
</ui:include>
event: keyup, change, blur
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" />
<p:inputText id="#{id}"
value="#{value}"
placeholder="#{placeholder}"
styleClass="w-full">
<p:ajax event="#{not empty event ? event : 'keyup'}"
update="#{not empty update ? update : ':formResultats:dtResultats @(.search-summary)'}" />
</p:inputText>
</div>
</ui:composition>

View File

@@ -0,0 +1,51 @@
<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">
<!--
Composant champ sélection réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-select.xhtml">
<ui:param name="id" value="fieldId" />
<ui:param name="label" value="Label du champ" />
<ui:param name="value" value="#{bean.property}" />
<ui:param name="items" value="#{bean.options}" />
<ui:param name="required" value="true" />
<ui:param name="var" value="item" />
<ui:param name="itemLabel" value="#{item.label}" />
<ui:param name="itemValue" value="#{item.value}" />
<ui:param name="update" value="componentId" />
<ui:param name="ajaxEvent" value="change" />
<ui:define name="items">
<f:selectItem itemLabel="Option 1" itemValue="1" />
</ui:define>
</ui:include>
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" />
<p:selectOneMenu id="#{id}"
value="#{value}"
required="#{not empty required and required}"
disabled="#{not empty readonly and readonly}"
styleClass="w-full">
<f:selectItem itemLabel="Sélectionner..." itemValue="" noSelectionOption="true" rendered="#{not empty required and required}" />
<ui:insert name="items">
<ui:fragment rendered="#{not empty var and not empty itemLabel and not empty itemValue}">
<f:selectItems value="#{items}"
var="#{var}"
itemLabel="#{itemLabel}"
itemValue="#{itemValue}" />
</ui:fragment>
<ui:fragment rendered="#{empty var}">
<f:selectItems value="#{items}" />
</ui:fragment>
</ui:insert>
<ui:insert name="ajax">
<!-- AJAX peut être ajouté ici via ui:define -->
</ui:insert>
</p:selectOneMenu>
</div>
</ui:composition>

View File

@@ -0,0 +1,28 @@
<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">
<!--
Composant champ texte réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-text.xhtml">
<ui:param name="id" value="fieldId" />
<ui:param name="label" value="Label du champ" />
<ui:param name="value" value="#{bean.property}" />
<ui:param name="required" value="true" />
<ui:param name="placeholder" value="Placeholder" />
</ui:include>
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" />
<p:inputText id="#{id}"
value="#{value}"
required="#{not empty required and required}"
placeholder="#{placeholder}"
readonly="#{not empty readonly and readonly}"
styleClass="w-full" />
</div>
</ui:composition>

View File

@@ -0,0 +1,28 @@
<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">
<!--
Composant champ textarea réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-textarea.xhtml">
<ui:param name="id" value="fieldId" />
<ui:param name="label" value="Label du champ" />
<ui:param name="value" value="#{bean.property}" />
<ui:param name="required" value="true" />
<ui:param name="rows" value="4" />
</ui:include>
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" />
<p:inputTextarea id="#{id}"
value="#{value}"
required="#{not empty required and required}"
rows="#{not empty rows ? rows : 3}"
readonly="#{not empty readonly and readonly}"
styleClass="w-full" />
</div>
</ui:composition>

View File

@@ -0,0 +1,24 @@
<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">
<!--
Wrapper de champ de formulaire réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/forms/form-field-wrapper.xhtml">
<ui:param name="id" value="fieldId" />
<ui:param name="label" value="Label du champ" />
<ui:define name="input">
<p:inputText id="#{id}" value="#{bean.property}" styleClass="w-full" />
</ui:define>
</ui:include>
-->
<div class="field">
<p:outputLabel for="#{id}" value="#{label}" rendered="#{not empty label}" />
<ui:insert name="input" />
<p:message for="#{id}" />
</div>
</ui:composition>

View File

@@ -0,0 +1,31 @@
<!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">
<!--
Composant section de formulaire réutilisable (WOU/DRY)
Usage: <ui:decorate template="/templates/components/forms/form-section.xhtml">
<ui:param name="title" value="Titre de la section" />
<ui:param name="fluid" value="true" />
<ui:define name="content">
Contenu de la section
</ui:define>
</ui:decorate>
-->
<ui:composition>
<div class="card #{fluid ? 'ui-fluid' : ''}">
<h:panelGroup rendered="#{not empty title}">
<h5>#{title}</h5>
</h:panelGroup>
<ui:insert name="content">
<!-- Contenu par défaut si aucun content n'est fourni -->
</ui:insert>
</div>
</ui:composition>
</html>

View File

@@ -0,0 +1,93 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<a href="#" id="layout-config-button" class="layout-config-button">
<i class="pi pi-cog"/>
</a>
<div id="layout-config" class="layout-config">
<h:form id="config-form" styleClass="layout-config-form">
<h5 style="margin-top: 0">Type de Menu</h5>
<p:selectOneRadio value="#{guestPreferences.menuMode}" layout="pageDirection"
onchange="PrimeFaces.FreyaConfigurator.changeMenuMode(event.target.value)" >
<f:selectItem itemLabel="Horizontal" itemValue="layout-horizontal" />
<f:selectItem itemLabel="Sidebar" itemValue="layout-sidebar" />
<f:selectItem itemLabel="Slim" itemValue="layout-slim" />
<p:ajax listener="#{guestPreferences.onMenuTypeChange}" update="config-form" />
</p:selectOneRadio>
<hr/>
<h5>Schéma de Couleur</h5>
<p:selectOneRadio value="#{guestPreferences.darkMode}" layout="pageDirection"
onchange="PrimeFaces.FreyaConfigurator.changeLayout('#{guestPreferences.componentTheme}', event.target.value)" >
<f:selectItem itemLabel="Clair" itemValue="light" />
<f:selectItem itemLabel="Sombre" itemValue="dark" />
<p:ajax onstart="PrimeFaces.FreyaConfigurator.beforeResourceChange()" update="config-form logolink"/>
</p:selectOneRadio>
<p:outputPanel rendered="#{guestPreferences.menuMode eq 'layout-horizontal'}">
<hr/>
<h5>Mode Barre Supérieure et Menu</h5>
<p:selectOneRadio value="#{guestPreferences.topbarTheme}" layout="pageDirection"
onchange="PrimeFaces.FreyaConfigurator.changeSectionTheme(event.target.value , 'layout-topbar');PrimeFaces.FreyaConfigurator.changeSectionTheme(event.target.value , 'layout-menu')" >
<f:selectItem itemLabel="Clair" itemValue="light" itemDisabled="#{guestPreferences.darkMode != 'light'}" />
<f:selectItem itemLabel="Sombre" itemValue="dark" itemDisabled="#{guestPreferences.darkMode != 'light'}"/>
<p:ajax update="logolink config-form"/>
</p:selectOneRadio>
</p:outputPanel>
<p:outputPanel rendered="#{guestPreferences.menuMode != 'layout-horizontal'}">
<hr/>
<h5>Mode Barre Supérieure</h5>
<p:selectOneRadio value="#{guestPreferences.topbarTheme}" layout="pageDirection"
onchange="PrimeFaces.FreyaConfigurator.changeSectionTheme(event.target.value , 'layout-topbar')" >
<f:selectItem itemLabel="Clair" itemValue="light" itemDisabled="#{guestPreferences.darkMode != 'light'}" />
<f:selectItem itemLabel="Sombre" itemValue="dark" itemDisabled="#{guestPreferences.darkMode != 'light'}"/>
<p:ajax update="logolink config-form"/>
</p:selectOneRadio>
</p:outputPanel>
<p:outputPanel rendered="#{guestPreferences.menuMode != 'layout-horizontal'}">
<hr/>
<h5>Mode Menu</h5>
<p:selectOneRadio value="#{guestPreferences.menuTheme}" layout="pageDirection"
onchange="PrimeFaces.FreyaConfigurator.changeSectionTheme(event.target.value , 'layout-menu')" >
<f:selectItem itemLabel="Clair" itemValue="light" itemDisabled="#{guestPreferences.darkMode != 'light'}" />
<f:selectItem itemLabel="Sombre" itemValue="dark" itemDisabled="#{guestPreferences.darkMode != 'light'}"/>
<p:ajax update="logolink config-form"/>
</p:selectOneRadio>
</p:outputPanel>
<hr/>
<h5>Style d'Entrée</h5>
<p:selectOneRadio value="#{guestPreferences.inputStyle}" layout="pageDirection"
onchange="PrimeFaces.FreyaConfigurator.updateInputStyle(event.target.value)">
<f:selectItem itemLabel="Contouré" itemValue="outlined" />
<f:selectItem itemLabel="Rempli" itemValue="filled" />
<p:ajax />
</p:selectOneRadio>
<hr/>
<h5>Couleurs de Thème</h5>
<div class="layout-themes">
<ui:repeat value="#{guestPreferences.componentThemes}" var="componentTheme">
<div>
<p:commandLink actionListener="#{guestPreferences.setComponentTheme(componentTheme.file)}"
style="background-color: #{componentTheme.color};" title="#{componentTheme.name}"
process="@this"
update="config-form"
onstart="PrimeFaces.FreyaConfigurator.beforeResourceChange()"
oncomplete="PrimeFaces.FreyaConfigurator.changeComponentsTheme('#{componentTheme.file}', '#{guestPreferences.darkMode}')">
</p:commandLink>
</div>
</ui:repeat>
</div>
</h:form>
</div>
</ui:composition>

View File

@@ -0,0 +1,57 @@
<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">
<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>
</div>
</ui:composition>

View File

@@ -0,0 +1,197 @@
<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:fr="http://primefaces.org/freya">
<div class="menu-wrapper">
<div class="sidebar-logo">
<a href="dashboard.xhtml">
<p:graphicImage name="images/logo-freya-single.svg" library="freya-layout" />
</a>
<a href="#" class="sidebar-pin" title="Toggle Menu">
<span class="pin"></span>
</a>
</div>
<div class="layout-menu-container">
<h:form id="menuform">
<fr:menu widgetVar="FreyaMenuWidget">
<!-- Dashboard Principal -->
<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: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" />
<p:menuitem id="m_config_systeme" value="Configuration Système" icon="pi pi-cog" outcome="/pages/super-admin/configuration/systeme" />
</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: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:submenu>
<!-- Gestion des Membres -->
<p:submenu id="m_membres" label="Gestion des Membres" icon="pi pi-users">
<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_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: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:submenu>
<!-- Gestion des Adhésions -->
<p:submenu id="m_adhesions" label="Gestion des Adhésions" icon="pi pi-bookmark">
<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_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: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" />
<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: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" />
<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_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" />
<p:menuitem id="m_calendrier" value="Calendrier" icon="pi pi-calendar-plus" outcome="/pages/secure/evenement/calendrier" />
<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: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="#" />
</p:submenu>
<!-- Gestion Documentaire -->
<p:submenu id="m_documents" label="Gestion Documentaire" icon="pi pi-folder">
<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_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: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="#" />
</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: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_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:submenu>
<!-- Outils et Utilitaires -->
<p:submenu id="m_outils" label="Outils et Utilitaires" icon="pi pi-wrench">
<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:submenu>
<!-- Mon Espace Personnel -->
<p:submenu id="m_personnel" label="Mon Espace Personnel" icon="pi pi-user">
<p:menuitem id="m_mon_profil" value="Mon Profil" icon="pi pi-user-edit" outcome="/pages/secure/personnel/profil" />
<p:menuitem id="m_mes_activites" value="Mes Activités" icon="pi pi-history" outcome="/pages/secure/personnel/activites" />
<p:menuitem id="m_mes_preferences" value="Mes Préférences" icon="pi pi-cog" outcome="/pages/secure/personnel/preferences" />
<p:menuitem id="m_mes_notifications" value="Mes Notifications" icon="pi pi-bell" outcome="/pages/secure/personnel/notifications" />
<p:menuitem id="m_mon_agenda" value="Mon Agenda" icon="pi pi-calendar" outcome="/pages/secure/personnel/agenda" />
<p:menuitem id="m_mes_documents_perso" value="Mes Documents" icon="pi pi-folder" outcome="/pages/secure/personnel/documents" />
<p:menuitem id="m_favoris" value="Mes Favoris" icon="pi pi-star-fill" outcome="/pages/secure/personnel/favoris" />
<p:menuitem id="m_parametres_compte" value="Paramètres Compte" icon="pi pi-lock" outcome="/pages/secure/personnel/parametres" />
</p:submenu>
<!-- Aide et Support -->
<p:submenu id="m_aide_documentation" label="Aide et Support" icon="pi pi-question-circle">
<p:menuitem id="m_guide_utilisateur" value="Guide Utilisateur" icon="pi pi-book" outcome="/pages/secure/aide/guide" />
<p:menuitem id="m_documentation" value="Documentation Complète" icon="pi pi-info-circle" outcome="/pages/secure/aide/documentation" />
<p:menuitem id="m_tutoriels" value="Tutoriels Vidéo" icon="pi pi-video" outcome="/pages/secure/aide/tutoriels" />
<p:menuitem id="m_faq" value="Questions Fréquentes" icon="pi pi-question" outcome="/pages/secure/aide/faq" />
<p:menuitem id="m_support" value="Contacter le Support" icon="pi pi-phone" outcome="/pages/secure/aide/support" />
<p:menuitem id="m_tickets" value="Mes Tickets" icon="pi pi-ticket" outcome="/pages/secure/aide/tickets" />
<p:menuitem id="m_feedback" value="Suggestions" icon="pi pi-comment" outcome="/pages/secure/aide/suggestions" />
<p:menuitem id="m_changelog" value="Nouveautés" icon="pi pi-sparkles" outcome="/pages/secure/aide/nouveautes" />
<p:menuitem id="m_apropos" value="À Propos d'UnionFlow" icon="pi pi-info" outcome="/pages/secure/aide/apropos" />
</p:submenu>
</fr:menu>
</h:form>
</div>
</div>
</ui:composition>

View File

@@ -0,0 +1,29 @@
<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 d'affichage du logo d'organisation (avatar circulaire) - DRY/WOU.
Paramètres :
- logo : URL du logo (peut être nul)
- size : taille en pixels (facultatif, défaut 48)
Note: Les erreurs CSS de l'IDE sur la ligne suivante sont des faux positifs.
La syntaxe EL est correcte et sera évaluée côté serveur avant l'envoi au navigateur.
-->
<p:outputPanel styleClass="flex align-items-center justify-content-center border-circle bg-primary-50"
style="width: #{empty size ? 48 : size}px; height: #{empty size ? 48 : size}px; overflow: hidden;">
<p:graphicImage value="#{logo}"
rendered="#{not empty logo}"
style="max-width: 100%; max-height: 100%; object-fit: contain;"/>
<h:panelGroup rendered="#{empty logo}">
<i class="pi pi-building text-2xl text-primary"></i>
</h:panelGroup>
</p:outputPanel>
</ui:composition>

View File

@@ -0,0 +1,38 @@
<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">
<!--
Composant en-tête de page réutilisable (WOU/DRY)
Usage: <ui:include src="/templates/components/layout/page-header.xhtml">
<ui:param name="icon" value="pi pi-icon-name" />
<ui:param name="title" value="Titre de la page" />
<ui:param name="description" value="Description de la page" />
<ui:define name="actions">
Contenu des actions (boutons, etc.)
</ui:define>
</ui:include>
-->
<div class="grid">
<div class="col-12">
<div class="card">
<div class="flex align-items-center justify-content-between">
<div>
<h3 class="mb-2">
<i class="#{icon} text-primary mr-2"></i>
#{title}
</h3>
<p class="text-600 m-0" rendered="#{not empty description}">#{description}</p>
</div>
<div>
<ui:insert name="actions" />
</div>
</div>
</div>
</div>
</div>
</ui:composition>

View File

@@ -0,0 +1,192 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<div class="layout-rightpanel">
<div class="rightpanel-wrapper">
<div class="rightpanel-section weather-section">
<div class="section-header">
<h6>Aujourd'hui</h6>
</div>
<div class="weather">
<p:graphicImage name="images/rightpanel/icon-sun.svg" library="demo" />
<div class="weather-info">
<h6>Dakar, #{currentDate}</h6>
<h1>28º</h1>
</div>
</div>
</div>
<div class="rightpanel-section tasks-section">
<div class="section-header">
<h6>Mes tâches</h6>
<h:form>
<ui:include src="/templates/components/buttons/button-icon.xhtml">
<ui:param name="icon" value="pi pi-plus" />
<ui:param name="rounded" value="true" />
<ui:param name="text" value="false" />
<ui:param name="styleClass" value="ui-button-secondary ui-button-flat" />
</ui:include>
</h:form>
</div>
<ul>
<li>
<div class="task-info">
<h6>Traiter les demandes d'adhésion en attente</h6>
<span>-Vérifier les dossiers</span>
<span>-Valider les documents</span>
</div>
</li>
<li>
<div class="task-info">
<h6>Préparer le rapport mensuel</h6>
<span>Statistiques des membres actifs</span>
</div>
</li>
<li class="done">
<div class="task-info">
<h6>Relancer les cotisations en retard</h6>
</div>
<i class="pi pi-check"></i>
</li>
<li class="done">
<div class="task-info">
<h6>Organiser la réunion mensuelle</h6>
</div>
<i class="pi pi-check"></i>
</li>
</ul>
</div>
<div class="rightpanel-section favorites-section">
<div class="section-header">
<h6>Raccourcis</h6>
</div>
<div class="favorite-items">
<a href="#" class="favorite-item" title="Membres">
<i class="pi pi-users" style="font-size: 1.5rem; color: #007ad9;"></i>
</a>
<a href="#" class="favorite-item" title="Cotisations">
<i class="pi pi-dollar" style="font-size: 1.5rem; color: #28a745;"></i>
</a>
<a href="#" class="favorite-item" title="Aides">
<i class="pi pi-heart" style="font-size: 1.5rem; color: #dc3545;"></i>
</a>
<a href="#" class="favorite-item" title="Événements">
<i class="pi pi-calendar" style="font-size: 1.5rem; color: #6f42c1;"></i>
</a>
<a href="#" class="favorite-item" title="Rapports">
<i class="pi pi-chart-bar" style="font-size: 1.5rem; color: #fd7e14;"></i>
</a>
<a href="#" class="add-item">
<i class="pi pi-plus"></i>
</a>
</div>
</div>
<div class="rightpanel-section chat-section chat">
<h:form>
<p:tabView>
<p:tab>
<f:facet name="title">
<p:graphicImage name="images/rightpanel/profile-1.png" library="demo" />
<span class="ui-badge">2</span>
</f:facet>
<div class="chat">
<span class="fade"></span>
<div class="chat-content">
<div class="chat-message send">
<span class="name">Vous</span>
<div class="message">
<p>Bonjour, j'ai besoin de votre validation pour les nouvelles adhésions.</p>
<span>Il y a 10 min</span>
</div>
<div class="message">
<p>Merci de vérifier les dossiers 🙏</p>
<span>Il y a 5 min</span>
</div>
</div>
<div class="chat-message">
<span class="name">Admin</span>
<div class="message">
<p>Parfait, je m'en occupe dans l'heure qui suit.</p>
<span>Il y a 2 min</span>
</div>
</div>
<div class="chat-message send">
<span class="name">Vous</span>
<div class="message">
<p>Excellent, merci beaucoup !</p>
<span>Il y a 1 min</span>
</div>
</div>
</div>
<div class="chat-input">
<p:inputText placeholder="Écrivez votre message..." />
</div>
</div>
</p:tab>
<p:tab>
<f:facet name="title">
<p:graphicImage name="images/rightpanel/profile-2.png" library="demo" />
</f:facet>
<div class="chat">
<div class="chat-content no-message">
<h4>Aucun message de l'équipe support</h4>
</div>
<div class="chat-input">
<p:inputText placeholder="Écrivez votre message..." />
</div>
</div>
</p:tab>
<p:tab>
<f:facet name="title">
<i class="pi pi-plus"></i>
</f:facet>
<div class="chat">
<span class="fade"></span>
<div class="contacts">
<ul>
<li>
<p:graphicImage name="images/rightpanel/profile-1.png" library="demo" />
<div class="contact-info">
<h6>Administrateur</h6>
<span>En ligne</span>
</div>
</li>
<li>
<p:graphicImage name="images/rightpanel/profile-2.png" library="demo" />
<div class="contact-info">
<h6>Support Technique</h6>
<span>Absent</span>
</div>
</li>
<li>
<p:graphicImage name="images/rightpanel/profile-3.png" library="demo" />
<div class="contact-info">
<h6>Secrétaire</h6>
<span>En ligne</span>
</div>
</li>
<li>
<p:graphicImage name="images/rightpanel/profile-4.png" library="demo" />
<div class="contact-info">
<h6>Trésorier</h6>
<span>En ligne</span>
</div>
</li>
</ul>
</div>
<div class="chat-input">
<p:inputText placeholder="Rechercher une personne" />
</div>
</div>
</p:tab>
</p:tabView>
</h:form>
</div>
</div>
</div>
</ui:composition>

View File

@@ -0,0 +1,107 @@
<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">
<div class="layout-topbar">
<div class="layout-topbar-wrapper">
<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" />
</h:link>
</div>
<ui:include src="/templates/components/layout/menu.xhtml" />
<div class="layout-topbar-right">
<ul class="layout-topbar-actions">
<li class="topbar-item search-item ">
<a href="#">
<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..." />
<i class="pi pi-search"/>
</h:panelGroup>
</h:form>
</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;">
#{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>
</div>
</div>
</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>
</div>
</div>
</li>
<li>
<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>
<span>Déconnexion</span>
</p:commandLink>
</h:form>
</li>
</ul>
</li>
</ul>
<a href="#" class="layout-rightpanel-button">
<i class="pi pi-arrow-left"></i>
</a>
</div>
</div>
</div>
</ui:composition>

View File

@@ -0,0 +1,41 @@
<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">
<!--
Composant réutilisable: Photo de profil avec upload
Paramètres:
- photoId: ID du panelGroup pour la photo (requis)
- photoUrl: URL de la photo (optionnel)
- initiales: Initiales à afficher si pas de photo (requis)
- formId: ID du formulaire pour l'upload (requis)
- listener: Méthode bean pour gérer l'upload (requis)
- update: Composants à mettre à jour après upload (requis)
- size: Taille de la photo en px (optionnel, défaut: 120)
-->
<ui:param name="size" value="120" />
<h:panelGroup id="#{photoId}">
<div class="border-circle overflow-hidden" style="width: #{size}px; height: #{size}px;">
<h:graphicImage value="#{photoUrl}"
style="width: 100%; height: 100%; object-fit: cover;"
rendered="#{photoUrl != null}" />
<div class="bg-primary text-white flex align-items-center justify-content-center w-full h-full"
rendered="#{photoUrl == null}">
<span style="font-size: #{size / 2}px;">#{initiales}</span>
</div>
</div>
</h:panelGroup>
<h:form id="#{formId}" enctype="multipart/form-data">
<p:fileUpload mode="simple" skinSimple="true"
label="Changer photo" chooseLabel="Modifier"
accept="image/*" maxFileSize="2000000"
listener="#{listener}"
update="#{update}"
styleClass="mt-2 w-full" />
</h:form>
</ui:composition>

View File

@@ -0,0 +1,53 @@
<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">
<!--
Composant DataTable réutilisable avec configuration standard - DRY/WOU
Usage :
<ui:decorate template="/templates/components/tables/data-table.xhtml">
<ui:param name="id" value="dtItems"/>
<ui:param name="value" value="#{bean.items}"/>
<ui:param name="var" value="item"/>
<ui:param name="emptyMessage" value="Aucun élément trouvé"/>
<ui:param name="rows" value="20"/>
<ui:param name="rowsPerPageTemplate" value="10,20,50,100"/>
<ui:param name="paginator" value="true"/>
<ui:param name="lazy" value="false"/>
<ui:param name="selectionMode" value="single"/>
<ui:param name="selection" value="#{bean.selectedItem}"/>
<ui:define name="columns">
<p:column headerText="Nom">...</p:column>
<p:column headerText="Actions">...</p:column>
</ui:define>
</ui:decorate>
-->
<p:dataTable id="#{id}"
value="#{value}"
var="item"
paginator="#{empty paginator ? 'true' : paginator}"
rows="#{empty rows ? 20 : rows}"
rowsPerPageTemplate="#{empty rowsPerPageTemplate ? '10,20,50,100' : rowsPerPageTemplate}"
paginatorPosition="#{empty paginatorPosition ? 'bottom' : paginatorPosition}"
emptyMessage="#{empty emptyMessage ? 'Aucun élément trouvé' : emptyMessage}"
styleClass="table-responsive #{styleClass}"
lazy="#{not empty lazy and lazy}"
selectionMode="#{selectionMode}"
selection="#{selection}"
rowKey="#{rowKey}"
sortMode="#{sortMode}"
sortField="#{sortField}"
sortOrder="#{sortOrder}"
filteredValue="#{filteredValue}"
widgetVar="#{widgetVar}"
size="#{size}">
<ui:insert name="columns">
<!-- Table columns go here -->
</ui:insert>
</p:dataTable>
</ui:composition>