Configure Maven repository for unionflow-server-api dependency
This commit is contained in:
@@ -0,0 +1,595 @@
|
||||
<!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 Aides - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<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="pi pi-heart text-pink-500 mr-2"></i>
|
||||
Gestion des Aides
|
||||
</h3>
|
||||
<p class="text-600 m-0">#{aideBean.totalAides} aides • #{aideBean.montantDistribue} distribués • #{aideBean.budgetDisponible} disponible</p>
|
||||
</div>
|
||||
<h:form id="formActionsAides">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouvelle aide"
|
||||
icon="pi pi-plus"
|
||||
styleClass="ui-button-success"
|
||||
onclick="PF('dlgNouvelleAide').show();" />
|
||||
<p:commandButton value="Campagne d'aide"
|
||||
icon="pi pi-megaphone"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{aideBean.nouvelleCampagne}" />
|
||||
<p:commandButton value="Budget & Critères"
|
||||
icon="pi pi-cog"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{aideBean.gestionBudget}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-pink-100 border-left-3 border-pink-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-pink-900 font-bold text-2xl">#{aideBean.aidesActives}</div>
|
||||
<div class="text-pink-700">Aides Actives</div>
|
||||
</div>
|
||||
<div class="bg-pink-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-heart text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-green-100 border-left-3 border-green-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-green-900 font-bold text-2xl">#{aideBean.montantDistribue}</div>
|
||||
<div class="text-green-700">Montant Distribué</div>
|
||||
</div>
|
||||
<div class="bg-green-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-dollar text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-blue-100 border-left-3 border-blue-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-blue-900 font-bold text-2xl">#{aideBean.beneficiaires}</div>
|
||||
<div class="text-blue-700">Bénéficiaires</div>
|
||||
</div>
|
||||
<div class="bg-blue-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-users text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-orange-100 border-left-3 border-orange-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-orange-900 font-bold text-2xl">#{aideBean.enAttente}</div>
|
||||
<div class="text-orange-700">En Attente</div>
|
||||
</div>
|
||||
<div class="bg-orange-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-clock text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Budget et critères -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<div class="card">
|
||||
<h5>Budget des Aides</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-2xl font-bold text-primary mb-2">#{aideBean.budgetTotal}</div>
|
||||
<div class="text-600">Budget Total</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">#{aideBean.budgetUtilise}</div>
|
||||
<div class="text-600">Utilisé</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">#{aideBean.budgetDisponible}</div>
|
||||
<div class="text-600">Disponible</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p:progressBar value="#{aideBean.tauxUtilisationBudget}"
|
||||
labelTemplate="#{aideBean.tauxUtilisationBudget}% du budget utilisé"
|
||||
styleClass="mt-3" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="card">
|
||||
<h5>Prochaines Échéances</h5>
|
||||
<ui:repeat value="#{aideBean.prochainesEcheances}" var="aide" varStatus="status">
|
||||
<div class="flex align-items-center justify-content-between p-2 mb-2 border-round"
|
||||
style="background: var(--surface-50);">
|
||||
<div>
|
||||
<div class="font-medium text-sm">#{aide.beneficiaire}</div>
|
||||
<small class="text-600">#{aide.typeAide}</small>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="font-bold text-sm">#{aide.prochainVersement}</div>
|
||||
<small class="text-orange-500">#{aide.dateEcheance}</small>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Graphiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<div class="card">
|
||||
<h5>Évolution des Aides (12 derniers mois)</h5>
|
||||
<div class="grid">
|
||||
<div class="col-2">
|
||||
<div class="text-center p-2">
|
||||
<div class="text-sm font-medium text-blue-500">15</div>
|
||||
<div class="text-xs text-600">Jan</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="text-center p-2">
|
||||
<div class="text-sm font-medium text-green-500">22</div>
|
||||
<div class="text-xs text-600">Fév</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="text-center p-2">
|
||||
<div class="text-sm font-medium text-purple-500">18</div>
|
||||
<div class="text-xs text-600">Mar</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="text-center p-2">
|
||||
<div class="text-sm font-medium text-orange-500">25</div>
|
||||
<div class="text-xs text-600">Avr</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="text-center p-2">
|
||||
<div class="text-sm font-medium text-red-500">12</div>
|
||||
<div class="text-xs text-600">Mai</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="text-center p-2">
|
||||
<div class="text-sm font-medium text-cyan-500">28</div>
|
||||
<div class="text-xs text-600">Juin</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="surface-50 p-3 border-round mt-3 text-center">
|
||||
<div class="text-2xl font-bold text-primary">235</div>
|
||||
<div class="text-600">Total aides accordées cette année</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="card">
|
||||
<h5>Répartition par Type</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="flex align-items-center justify-content-between p-2 surface-50 border-round mb-2">
|
||||
<span class="text-600">🏥 Médicale</span>
|
||||
<span class="font-bold text-blue-500">45%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="flex align-items-center justify-content-between p-2 surface-50 border-round mb-2">
|
||||
<span class="text-600">👥 Sociale</span>
|
||||
<span class="font-bold text-green-500">30%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="flex align-items-center justify-content-between p-2 surface-50 border-round mb-2">
|
||||
<span class="text-600">🎓 Scolaire</span>
|
||||
<span class="font-bold text-purple-500">15%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="flex align-items-center justify-content-between p-2 surface-50 border-round mb-2">
|
||||
<span class="text-600">🚨 Urgence</span>
|
||||
<span class="font-bold text-red-500">10%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des aides -->
|
||||
<div class="card">
|
||||
<h:form id="formAides">
|
||||
<h5>Gestion des Aides</h5>
|
||||
|
||||
<!-- Filtres -->
|
||||
<p:toolbar>
|
||||
<p:toolbarGroup>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText placeholder="Rechercher..."
|
||||
value="#{aideBean.searchFilter}">
|
||||
<p:ajax event="keyup" update="dtAides" />
|
||||
</p:inputText>
|
||||
</span>
|
||||
|
||||
<p:selectOneMenu value="#{aideBean.statutFilter}">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Active" itemValue="ACTIVE" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="Suspendue" itemValue="SUSPENDUE" />
|
||||
<f:selectItem itemLabel="Terminée" itemValue="TERMINEE" />
|
||||
<f:selectItem itemLabel="Annulée" itemValue="ANNULEE" />
|
||||
<p:ajax update="dtAides" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{aideBean.typeFilter}">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Aide médicale" itemValue="MEDICALE" />
|
||||
<f:selectItem itemLabel="Aide funéraire" itemValue="FUNERAIRE" />
|
||||
<f:selectItem itemLabel="Aide sociale" itemValue="SOCIALE" />
|
||||
<f:selectItem itemLabel="Aide scolaire" itemValue="SCOLAIRE" />
|
||||
<f:selectItem itemLabel="Aide d'urgence" itemValue="URGENCE" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
<p:ajax update="dtAides" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{aideBean.frequenceFilter}">
|
||||
<f:selectItem itemLabel="Toutes fréquences" itemValue="" />
|
||||
<f:selectItem itemLabel="Ponctuelle" itemValue="PONCTUELLE" />
|
||||
<f:selectItem itemLabel="Mensuelle" itemValue="MENSUELLE" />
|
||||
<f:selectItem itemLabel="Trimestrielle" itemValue="TRIMESTRIELLE" />
|
||||
<f:selectItem itemLabel="Annuelle" itemValue="ANNUELLE" />
|
||||
<p:ajax update="dtAides" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</p:toolbarGroup>
|
||||
|
||||
<p:toolbarGroup align="right">
|
||||
<p:commandButton value="Versements groupés"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-outlined ui-button-success mr-2"
|
||||
action="#{aideBean.versementsGroupes}" />
|
||||
<p:commandButton icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{aideBean.actualiser}"
|
||||
update="@form"
|
||||
title="Actualiser" />
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtAides"
|
||||
var="aide"
|
||||
value="#{aideBean.aides}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25,50"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{aideBean.selectedAides}"
|
||||
rowKey="#{aide.id}"
|
||||
selectionMode="multiple"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{aide.reference}" style="width:120px">
|
||||
<h:outputText value="#{aide.reference}" styleClass="font-mono font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Bénéficiaire" sortBy="#{aide.nomBeneficiaire}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle overflow-hidden mr-3"
|
||||
style="width: 40px; height: 40px;">
|
||||
<h:graphicImage value="#{aide.photoBeneficiaire}"
|
||||
style="width: 100%; height: 100%; object-fit: cover;"
|
||||
rendered="#{aide.photoBeneficiaire != null}" />
|
||||
<div class="bg-primary text-white flex align-items-center justify-content-center w-full h-full"
|
||||
rendered="#{aide.photoBeneficiaire == null}">
|
||||
<span style="font-size: 0.9rem;">#{aide.initialesBeneficiaire}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-900">#{aide.nomCompletBeneficiaire}</div>
|
||||
<div class="text-600 text-sm">
|
||||
<span>#{aide.numeroMembre}</span>
|
||||
<span class="mx-2">•</span>
|
||||
<span>#{aide.telephoneBeneficiaire}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{aide.type}" style="width:140px">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-round p-2 mr-2 #{aide.typeColorClass}">
|
||||
<i class="pi #{aide.typeIcon} text-white text-sm"></i>
|
||||
</div>
|
||||
<span>#{aide.type}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Motif" sortBy="#{aide.motif}">
|
||||
<h:outputText value="#{aide.motif}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{aide.montant}" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-green-500">#{aide.montantTotal}</div>
|
||||
<small class="text-600">#{aide.frequence}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Versé" sortBy="#{aide.montantVerse}" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-blue-500">#{aide.montantVerse}</div>
|
||||
<p:progressBar value="#{aide.pourcentageVerse}"
|
||||
labelTemplate=""
|
||||
styleClass="h-1rem mt-1" />
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{aide.statut}" style="width:120px">
|
||||
<p:tag value="#{aide.statut}"
|
||||
severity="#{aide.statutSeverity}"
|
||||
icon="pi #{aide.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Début" sortBy="#{aide.dateDebut}" style="width:100px">
|
||||
<h:outputText value="#{aide.dateDebut}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Fin prévue" sortBy="#{aide.dateFinPrevue}" style="width:100px">
|
||||
<h:outputText value="#{aide.dateFinPrevue}"
|
||||
styleClass="#{aide.finPrevueClass}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Prochain versement" style="width:130px">
|
||||
<div class="text-center" rendered="#{aide.prochainVersement != null}">
|
||||
<div class="font-medium">#{aide.prochainVersementMontant}</div>
|
||||
<small class="text-600">#{aide.prochainVersementDate}</small>
|
||||
</div>
|
||||
<span class="text-400" rendered="#{aide.prochainVersement == null}">-</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:220px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{aideBean.voirAide(aide)}"
|
||||
title="Voir détails" />
|
||||
<p:commandButton icon="pi pi-dollar"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{aideBean.effectuerVersement(aide)}"
|
||||
title="Verser"
|
||||
rendered="#{aide.statut == 'ACTIVE' and aide.prochainVersement != null}" />
|
||||
<p:commandButton icon="pi pi-history"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
action="#{aideBean.voirHistorique(aide)}"
|
||||
title="Historique" />
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
action="#{aideBean.modifierAide(aide)}"
|
||||
title="Modifier" />
|
||||
<p:commandButton icon="pi pi-pause"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
action="#{aideBean.suspendreAide(aide)}"
|
||||
title="Suspendre"
|
||||
rendered="#{aide.statut == 'ACTIVE'}" />
|
||||
<p:commandButton icon="pi pi-play"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{aideBean.reactiverAide(aide)}"
|
||||
title="Réactiver"
|
||||
rendered="#{aide.statut == 'SUSPENDUE'}" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
action="#{aideBean.annulerAide(aide)}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler cette aide ?');"
|
||||
title="Annuler"
|
||||
rendered="#{aide.statut != 'TERMINEE' and aide.statut != 'ANNULEE'}" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Actions groupées -->
|
||||
<div class="mt-3 flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<span class="text-600">#{aideBean.selectedAides.size()} aide(s) sélectionnée(s)</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Verser sélection"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-outlined ui-button-success"
|
||||
action="#{aideBean.verserSelection}"
|
||||
disabled="#{empty aideBean.selectedAides}" />
|
||||
<p:commandButton value="Suspendre sélection"
|
||||
icon="pi pi-pause"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
action="#{aideBean.suspendreSelection}"
|
||||
disabled="#{empty aideBean.selectedAides}" />
|
||||
<p:commandButton value="Exporter sélection"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{aideBean.exporterSelection}"
|
||||
disabled="#{empty aideBean.selectedAides}" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Aide -->
|
||||
<p:dialog header="Nouvelle Aide" widgetVar="dlgNouvelleAide" modal="true" width="800">
|
||||
<h:form id="formNouvelleAide">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="beneficiaireSelect" value="Bénéficiaire" />
|
||||
<p:autoComplete id="beneficiaireSelect"
|
||||
value="#{aideBean.membreBeneficiaire}"
|
||||
completeMethod="#{aideBean.rechercherMembres}"
|
||||
var="membre" itemLabel="#{membre.nomComplet}" itemValue="#{membre}"
|
||||
converter="membreConverter"
|
||||
placeholder="Rechercher un membre..."
|
||||
required="true">
|
||||
<p:column>
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-2"
|
||||
style="width: 30px; height: 30px;">
|
||||
<span style="font-size: 0.8rem;">#{membre.initiales}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium">#{membre.nomComplet}</div>
|
||||
<small class="text-600">#{membre.numeroMembre}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:autoComplete>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="typeAide" value="Type d'aide" />
|
||||
<p:selectOneMenu id="typeAide" value="#{aideBean.nouvelleAide.type}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="🏥 Aide médicale" itemValue="MEDICALE" />
|
||||
<f:selectItem itemLabel="⚰️ Aide funéraire" itemValue="FUNERAIRE" />
|
||||
<f:selectItem itemLabel="👥 Aide sociale" itemValue="SOCIALE" />
|
||||
<f:selectItem itemLabel="🎓 Aide scolaire" itemValue="SCOLAIRE" />
|
||||
<f:selectItem itemLabel="🚨 Aide d'urgence" itemValue="URGENCE" />
|
||||
<f:selectItem itemLabel="🔧 Autre" itemValue="AUTRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="montantAide" value="Montant" />
|
||||
<p:inputNumber id="montantAide" value="#{aideBean.nouvelleAide.montant}"
|
||||
symbol=" FCFA" symbolPosition="s" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="frequenceAide" value="Fréquence" />
|
||||
<p:selectOneMenu id="frequenceAide" value="#{aideBean.nouvelleAide.frequence}">
|
||||
<f:selectItem itemLabel="Ponctuelle" itemValue="PONCTUELLE" />
|
||||
<f:selectItem itemLabel="Mensuelle" itemValue="MENSUELLE" />
|
||||
<f:selectItem itemLabel="Trimestrielle" itemValue="TRIMESTRIELLE" />
|
||||
<f:selectItem itemLabel="Annuelle" itemValue="ANNUELLE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="motifAide" value="Motif" />
|
||||
<p:inputText id="motifAide" value="#{aideBean.nouvelleAide.motif}"
|
||||
required="true" placeholder="Raison de l'aide" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="dateDebutAide" value="Date de début" />
|
||||
<p:calendar id="dateDebutAide" value="#{aideBean.nouvelleAide.dateDebut}"
|
||||
pattern="dd/MM/yyyy" showIcon="true" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="dateFinAide" value="Date de fin (optionnelle)" />
|
||||
<p:calendar id="dateFinAide" value="#{aideBean.nouvelleAide.dateFin}"
|
||||
pattern="dd/MM/yyyy" showIcon="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="modePaiementAide" value="Mode de paiement" />
|
||||
<p:selectOneMenu id="modePaiementAide" value="#{aideBean.nouvelleAide.modePaiement}">
|
||||
<f:selectItem itemLabel="💰 Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="📱 Wave Money" itemValue="WAVE" />
|
||||
<f:selectItem itemLabel="🏦 Virement bancaire" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="💳 Chèque" itemValue="CHEQUE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="descriptionAide" value="Description détaillée" />
|
||||
<p:inputTextarea id="descriptionAide" value="#{aideBean.nouvelleAide.description}"
|
||||
rows="3" placeholder="Détails sur la situation et l'aide accordée..." />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="versementImmediat" value="#{aideBean.versementImmediat}" />
|
||||
<p:outputLabel for="versementImmediat" value=" Effectuer le premier versement immédiatement" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="justificatifs" value="Justificatifs" />
|
||||
<p:fileUpload id="justificatifs" mode="advanced"
|
||||
multiple="true" dragDropSupport="true"
|
||||
uploadLabel="Télécharger" cancelLabel="Annuler" chooseLabel="Sélectionner"
|
||||
sizeLimit="5000000" fileLimit="10" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Créer l'aide" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{aideBean.creerAide}"
|
||||
update="@form :formAides"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgNouvelleAide').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgNouvelleAide').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
20
target/classes/META-INF/resources/pages/admin/audit.xhtml
Normal file
20
target/classes/META-INF/resources/pages/admin/audit.xhtml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!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">UnionFlow - Administration Audit</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h2>Administration - Audit</h2>
|
||||
<p>Page d'administration en cours de développement...</p>
|
||||
<p:button value="Retour" icon="pi pi-arrow-left" outcome="/pages/secure/dashboard"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,460 @@
|
||||
<!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">Journal d'Audit - UnionFlow</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-history text-indigo-500" />
|
||||
<ui:param name="title" value="Journal d'Audit" />
|
||||
<ui:param name="description" value="Traçabilité complète des actions et modifications système" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActions">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Exporter" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="onclick" value="PF('exportDialog').show(); return false;" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<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="#{auditBean.actualiser}" />
|
||||
<ui:param name="update" value=":formFiltres :formTableau:tableauAudit" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Événements Totaux" />
|
||||
<ui:param name="value" value="#{auditBean.totalEvenements}" />
|
||||
<ui:param name="icon" value="pi-history" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Connexions Réussies" />
|
||||
<ui:param name="value" value="#{auditBean.connexionsReussies}" />
|
||||
<ui:param name="icon" value="pi-check-circle" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Tentatives Échouées" />
|
||||
<ui:param name="value" value="#{auditBean.tentativesEchouees}" />
|
||||
<ui:param name="icon" value="pi-times-circle" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Alertes Sécurité" />
|
||||
<ui:param name="value" value="#{auditBean.alertesSecurite}" />
|
||||
<ui:param name="icon" value="pi-exclamation-triangle" />
|
||||
<ui:param name="iconColor" value="red-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Filtres -->
|
||||
<div class="card">
|
||||
<h:form id="formFiltres">
|
||||
<h5>Filtres de Recherche</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateDebut" />
|
||||
<ui:param name="label" value="Date Début" />
|
||||
<ui:param name="value" value="#{auditBean.dateDebut}" />
|
||||
<ui:param name="update" value=":formTableau:tableauAudit" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateFin" />
|
||||
<ui:param name="label" value="Date Fin" />
|
||||
<ui:param name="value" value="#{auditBean.dateFin}" />
|
||||
<ui:param name="update" value=":formTableau:tableauAudit" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="typeAction" />
|
||||
<ui:param name="label" value="Type d'Action" />
|
||||
<ui:param name="value" value="#{auditBean.typeAction}" />
|
||||
<ui:param name="update" value=":formTableau:tableauAudit" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Connexion" itemValue="CONNEXION" />
|
||||
<f:selectItem itemLabel="Déconnexion" itemValue="DECONNEXION" />
|
||||
<f:selectItem itemLabel="Création" itemValue="CREATION" />
|
||||
<f:selectItem itemLabel="Modification" itemValue="MODIFICATION" />
|
||||
<f:selectItem itemLabel="Suppression" itemValue="SUPPRESSION" />
|
||||
<f:selectItem itemLabel="Consultation" itemValue="CONSULTATION" />
|
||||
<f:selectItem itemLabel="Export" itemValue="EXPORT" />
|
||||
<f:selectItem itemLabel="Configuration" itemValue="CONFIGURATION" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="severite" />
|
||||
<ui:param name="label" value="Sévérité" />
|
||||
<ui:param name="value" value="#{auditBean.severite}" />
|
||||
<ui:param name="update" value=":formTableau:tableauAudit" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Toutes" itemValue="" />
|
||||
<f:selectItem itemLabel="Info" itemValue="INFO" />
|
||||
<f:selectItem itemLabel="Succès" itemValue="SUCCESS" />
|
||||
<f:selectItem itemLabel="Avertissement" itemValue="WARNING" />
|
||||
<f:selectItem itemLabel="Erreur" itemValue="ERROR" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITICAL" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-search-text.xhtml">
|
||||
<ui:param name="id" value="utilisateur" />
|
||||
<ui:param name="label" value="Utilisateur" />
|
||||
<ui:param name="value" value="#{auditBean.utilisateur}" />
|
||||
<ui:param name="placeholder" value="Nom ou email..." />
|
||||
<ui:param name="update" value=":formTableau:tableauAudit" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="module" />
|
||||
<ui:param name="label" value="Module" />
|
||||
<ui:param name="value" value="#{auditBean.module}" />
|
||||
<ui:param name="update" value=":formTableau:tableauAudit" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous les modules" itemValue="" />
|
||||
<f:selectItem itemLabel="Authentification" itemValue="AUTH" />
|
||||
<f:selectItem itemLabel="Membres" itemValue="MEMBRES" />
|
||||
<f:selectItem itemLabel="Cotisations" itemValue="COTISATIONS" />
|
||||
<f:selectItem itemLabel="Événements" itemValue="EVENTS" />
|
||||
<f:selectItem itemLabel="Documents" itemValue="DOCUMENTS" />
|
||||
<f:selectItem itemLabel="Configuration" itemValue="CONFIG" />
|
||||
<f:selectItem itemLabel="Rapports" itemValue="RAPPORTS" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-search-text.xhtml">
|
||||
<ui:param name="id" value="ipAddress" />
|
||||
<ui:param name="label" value="Adresse IP" />
|
||||
<ui:param name="value" value="#{auditBean.ipAddress}" />
|
||||
<ui:param name="placeholder" value="Ex: 192.168.1.1" />
|
||||
<ui:param name="update" value=":formTableau:tableauAudit" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel />
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Rechercher" />
|
||||
<ui:param name="icon" value="pi pi-search" />
|
||||
<ui:param name="action" value="#{auditBean.rechercher}" />
|
||||
<ui:param name="update" value=":formTableau:tableauAudit" />
|
||||
</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="#{auditBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value=":formFiltres :formTableau:tableauAudit" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Tableau du journal d'audit -->
|
||||
<div class="card">
|
||||
<h:form id="formTableau">
|
||||
<h5>Journal d'Audit</h5>
|
||||
|
||||
<p:dataTable id="tableauAudit"
|
||||
value="#{auditBean.evenementsFiltres}"
|
||||
var="log"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
emptyMessage="Aucun événement trouvé"
|
||||
styleClass="p-datatable-sm p-datatable-striped"
|
||||
sortMode="multiple"
|
||||
rowKey="#{log.id}">
|
||||
|
||||
<p:column headerText="Date/Heure" sortBy="#{log.dateHeure}" style="width: 12%">
|
||||
<div>
|
||||
<div class="font-semibold">#{log.dateFormatee}</div>
|
||||
<div class="text-sm text-600">#{log.heureFormatee}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Sévérité" sortBy="#{log.severite}" style="width: 8%" styleClass="text-center">
|
||||
<p:tag value="#{log.severiteLibelle}"
|
||||
severity="#{log.severiteSeverity}"
|
||||
icon="#{log.severiteIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Utilisateur" sortBy="#{log.utilisateur}" style="width: 15%">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-user text-blue-500"></i>
|
||||
<div>
|
||||
<div class="font-semibold">#{log.utilisateur}</div>
|
||||
<div class="text-sm text-600">#{log.role}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Action" sortBy="#{log.typeAction}" style="width: 12%">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="#{log.actionIcon} text-lg"></i>
|
||||
<span class="font-semibold">#{log.actionLibelle}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Module" sortBy="#{log.module}" style="width: 10%">
|
||||
<p:tag value="#{log.moduleLibelle}"
|
||||
severity="info" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Description" style="width: 25%">
|
||||
<div>#{log.description}</div>
|
||||
<div class="text-sm text-600 mt-1" rendered="#{not empty log.details}">
|
||||
<i class="pi pi-info-circle"></i> #{log.details}
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="IP/Appareil" style="width: 12%">
|
||||
<div class="text-sm">
|
||||
<i class="pi pi-globe"></i> #{log.ipAddress}
|
||||
</div>
|
||||
<div class="text-xs text-600">#{log.userAgentCourt}</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width: 6%" styleClass="text-center">
|
||||
<div class="flex justify-content-center gap-1">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="action" value="#{auditBean.selectionnerLog(log)}" />
|
||||
<ui:param name="update" value=":formDetails:dlgDetails" />
|
||||
<ui:param name="oncomplete" value="PF('dlgDetails').show();" />
|
||||
<ui:param name="title" value="Voir les détails" />
|
||||
<ui:param name="styleClass" value="p-button-sm p-button-rounded" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Détails -->
|
||||
<h:form id="formDetails">
|
||||
<p:dialog id="dlgDetails"
|
||||
widgetVar="dlgDetails"
|
||||
header="Détails de l'Événement"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 800px;">
|
||||
<div class="grid" rendered="#{auditBean.evenementSelectionne != null}">
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="title">Informations Générales</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Date/Heure</label>
|
||||
<div>#{auditBean.evenementSelectionne.dateHeureComplete}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Sévérité</label>
|
||||
<div>
|
||||
<p:tag value="#{auditBean.evenementSelectionne.severiteLibelle}"
|
||||
severity="#{auditBean.evenementSelectionne.severiteSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Utilisateur</label>
|
||||
<div>#{auditBean.evenementSelectionne.utilisateur}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Rôle</label>
|
||||
<div>#{auditBean.evenementSelectionne.role}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="title">Détails de l'Action</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Description</label>
|
||||
<div>#{auditBean.evenementSelectionne.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{not empty auditBean.evenementSelectionne.details}">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Détails</label>
|
||||
<div class="surface-50 p-3 border-round">#{auditBean.evenementSelectionne.details}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{not empty auditBean.evenementSelectionne.donneesAvant}">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Données Avant</label>
|
||||
<pre class="surface-200 border-round p-2 text-sm">#{auditBean.evenementSelectionne.donneesAvant}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{not empty auditBean.evenementSelectionne.donneesApres}">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Données Après</label>
|
||||
<pre class="surface-200 border-round p-2 text-sm">#{auditBean.evenementSelectionne.donneesApres}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="title">Informations Techniques</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Adresse IP</label>
|
||||
<div>#{auditBean.evenementSelectionne.ipAddress}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Session ID</label>
|
||||
<div class="text-sm">#{auditBean.evenementSelectionne.sessionId}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-semibold">User Agent</label>
|
||||
<div class="text-sm">#{auditBean.evenementSelectionne.userAgent}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<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('dlgDetails').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
|
||||
<!-- Dialog Export -->
|
||||
<h:form id="formExport">
|
||||
<p:dialog id="exportDialog"
|
||||
widgetVar="exportDialog"
|
||||
header="Exporter le Journal d'Audit"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 500px;">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="formatExport" value="Format d'Export" />
|
||||
<p:selectOneRadio id="formatExport"
|
||||
value="#{auditBean.formatExport}"
|
||||
layout="grid"
|
||||
columns="1">
|
||||
<f:selectItem itemLabel="Excel (.xlsx)" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="PDF" itemValue="PDF" />
|
||||
<f:selectItem itemLabel="CSV" itemValue="CSV" />
|
||||
<f:selectItem itemLabel="JSON" itemValue="JSON" />
|
||||
</p:selectOneRadio>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="inclureFiltres"
|
||||
value="#{auditBean.inclureFiltresExport}"
|
||||
itemLabel="Inclure uniquement les données filtrées" />
|
||||
</div>
|
||||
</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="onclick" value="PF('exportDialog').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<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="#{auditBean.exporter}" />
|
||||
<ui:param name="update" value="none" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
20
target/classes/META-INF/resources/pages/admin/backup.xhtml
Normal file
20
target/classes/META-INF/resources/pages/admin/backup.xhtml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!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">UnionFlow - Administration Backup</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h2>Administration - Backup</h2>
|
||||
<p>Page d'administration en cours de développement...</p>
|
||||
<p:button value="Retour" icon="pi pi-arrow-left" outcome="/pages/secure/dashboard"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,725 @@
|
||||
<!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 Cotisations - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
<!-- En-tête principal avec disposition Freya stricte -->
|
||||
<div class="card">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-8">
|
||||
<h2 class="text-primary font-bold mb-2">
|
||||
<i class="pi pi-dollar mr-2"></i>
|
||||
Gestion des Cotisations
|
||||
</h2>
|
||||
<p class="text-600 mt-0">
|
||||
<span class="font-semibold">127 organisations</span> •
|
||||
<span class="font-semibold">#{cotisationsGestionBean.periodeActuelle}</span> •
|
||||
Recouvrement: <span class="font-semibold text-green-600">#{cotisationsGestionBean.tauxRecouvrement}%</span> •
|
||||
<span class="font-semibold">#{cotisationsGestionBean.totalMembresActifs}</span> membres actifs
|
||||
</p>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-4 text-right">
|
||||
<h:form id="formActionsGlobales">
|
||||
<p:commandButton icon="pi pi-megaphone"
|
||||
title="Nouvelle Campagne"
|
||||
styleClass="ui-button-success ui-button-sm mr-3"
|
||||
onclick="PF('dlgNouvelleCampagne').show();" />
|
||||
<p:commandButton icon="pi pi-send"
|
||||
title="Relances groupées"
|
||||
styleClass="ui-button-warning ui-button-outlined ui-button-sm mr-3"
|
||||
action="#{cotisationsGestionBean.relancesGroupees}" />
|
||||
<p:commandButton icon="pi pi-file-excel"
|
||||
title="Export global"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm"
|
||||
action="#{cotisationsGestionBean.exporterTout}" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- KPIs Financiers avec grille Freya stricte -->
|
||||
<div class="formgrid grid">
|
||||
<!-- KPI 1: Montant Collecté -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Collecté ce mois" />
|
||||
<ui:param name="value" value="#{cotisationsGestionBean.montantCollecte}" />
|
||||
<ui:param name="icon" value="pi-check" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="growthValue" value="#{cotisationsGestionBean.progressionMensuelle}" />
|
||||
<ui:param name="growthLabel" value="de l'objectif" />
|
||||
<ui:param name="progressValue" value="#{cotisationsGestionBean.progressionMensuelle}" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3 xl:col-2" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 2: Membres à jour -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Membres à jour" />
|
||||
<ui:param name="value" value="#{cotisationsGestionBean.membresAJour}" />
|
||||
<ui:param name="icon" value="pi-users" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="statusIcon" value="pi-circle-fill" />
|
||||
<ui:param name="statusLabel" value="Conformes" />
|
||||
<ui:param name="statusValue" value="#{cotisationsGestionBean.pourcentageMembresAJour}%" />
|
||||
<ui:param name="progressValue" value="#{cotisationsGestionBean.pourcentageMembresAJour}" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3 xl:col-2" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 3: En Attente -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="En attente" />
|
||||
<ui:param name="value" value="#{cotisationsGestionBean.montantEnAttente}" />
|
||||
<ui:param name="icon" value="pi-clock" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="statusIcon" value="pi-exclamation-triangle" />
|
||||
<ui:param name="statusLabel" value="Cotisations" />
|
||||
<ui:param name="statusValue" value="#{cotisationsGestionBean.nombreCotisationsEnAttente}" />
|
||||
<ui:param name="noDataLabel" value="À traiter rapidement" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3 xl:col-2" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 4: Impayés -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Impayés" />
|
||||
<ui:param name="value" value="#{cotisationsGestionBean.montantImpayes}" />
|
||||
<ui:param name="icon" value="pi-exclamation-circle" />
|
||||
<ui:param name="iconColor" value="red-600" />
|
||||
<ui:param name="statusIcon" value="pi-arrow-down" />
|
||||
<ui:param name="statusLabel" value="Retard moyen" />
|
||||
<ui:param name="statusValue" value="#{cotisationsGestionBean.joursRetardMoyen}j" />
|
||||
<ui:param name="noDataLabel" value="Action requise" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3 xl:col-2" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 5: Revenus 2024 -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Revenus 2024" />
|
||||
<ui:param name="value" value="#{cotisationsGestionBean.revenus2024}" />
|
||||
<ui:param name="icon" value="pi-chart-line" />
|
||||
<ui:param name="iconColor" value="purple-600" />
|
||||
<ui:param name="growthValue" value="#{cotisationsGestionBean.croissanceAnnuelle}" />
|
||||
<ui:param name="growthLabel" value="Croissance annuelle" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3 xl:col-2" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 6: Wave Money -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Prélèvements Auto" />
|
||||
<ui:param name="value" value="#{cotisationsGestionBean.prelevementsActifs}" />
|
||||
<ui:param name="icon" value="pi-mobile" />
|
||||
<ui:param name="iconColor" value="teal-600" />
|
||||
<ui:param name="statusIcon" value="pi-sync" />
|
||||
<ui:param name="statusLabel" value="Montant/mois" />
|
||||
<ui:param name="statusValue" value="#{cotisationsGestionBean.montantPrelevementsPrevu} FCFA" />
|
||||
<ui:param name="noDataLabel" value="Automatique" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3 xl:col-2" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Section Analytics avec disposition Freya -->
|
||||
<div class="formgrid grid">
|
||||
<!-- Top Organisations -->
|
||||
<div class="field col-12 lg:col-8">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h5 class="m-0">
|
||||
<i class="pi pi-trophy text-yellow-500 mr-2"></i>
|
||||
Top 5 Organisations Performantes
|
||||
</h5>
|
||||
<p:selectOneMenu value="#{cotisationsGestionBean.periodeGraphique}" styleClass="w-8rem">
|
||||
<f:selectItem itemLabel="12 mois" itemValue="12M" />
|
||||
<f:selectItem itemLabel="6 mois" itemValue="6M" />
|
||||
<f:selectItem itemLabel="3 mois" itemValue="3M" />
|
||||
<f:selectItem itemLabel="Ce mois" itemValue="1M" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<p:dataTable value="#{cotisationsGestionBean.topOrganisations}" var="org"
|
||||
styleClass="p-datatable-sm p-datatable-gridlines">
|
||||
<p:column headerText="Organisation" style="width:40%">
|
||||
<div class="flex align-items-center">
|
||||
<div class="flex align-items-center justify-content-center bg-primary-100 border-round mr-2"
|
||||
style="width: 2rem; height: 2rem;">
|
||||
<i class="pi pi-building text-primary-600"></i>
|
||||
</div>
|
||||
<span class="font-semibold">#{org.nom}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Taux" style="width:15%; text-align: center;">
|
||||
<p:progressBar value="#{org.tauxRecouvrement}"
|
||||
labelTemplate="#{org.tauxRecouvrement}%"
|
||||
styleClass="h-1rem" />
|
||||
</p:column>
|
||||
<p:column headerText="Montant" style="width:20%; text-align: right;">
|
||||
<span class="font-bold text-green-600">#{org.montantCollecte} FCFA</span>
|
||||
</p:column>
|
||||
<p:column headerText="Membres" style="width:25%; text-align: center;">
|
||||
<p:tag value="#{org.nombreMembresAJour}/#{org.totalMembres}"
|
||||
severity="info" styleClass="text-xs" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Répartition Paiements -->
|
||||
<div class="field col-12 lg:col-4">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">
|
||||
<i class="pi pi-chart-pie text-blue-500 mr-2"></i>
|
||||
Méthodes de Paiement
|
||||
</h5>
|
||||
|
||||
<div class="surface-50 border-round-lg p-3 mb-2">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-mobile text-blue-500 mr-2"></i>
|
||||
<span class="font-medium">Wave Money</span>
|
||||
</div>
|
||||
<span class="font-bold">#{cotisationsGestionBean.paiementsWave}%</span>
|
||||
</div>
|
||||
<p:progressBar value="#{cotisationsGestionBean.paiementsWave}"
|
||||
showValue="false"
|
||||
styleClass="h-05rem" />
|
||||
</div>
|
||||
|
||||
<div class="surface-50 border-round-lg p-3 mb-2">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-building text-purple-500 mr-2"></i>
|
||||
<span class="font-medium">Virement</span>
|
||||
</div>
|
||||
<span class="font-bold">#{cotisationsGestionBean.paiementsVirement}%</span>
|
||||
</div>
|
||||
<p:progressBar value="#{cotisationsGestionBean.paiementsVirement}"
|
||||
showValue="false"
|
||||
styleClass="h-05rem" />
|
||||
</div>
|
||||
|
||||
<div class="surface-50 border-round-lg p-3">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-money-bill text-green-500 mr-2"></i>
|
||||
<span class="font-medium">Espèces</span>
|
||||
</div>
|
||||
<span class="font-bold">#{cotisationsGestionBean.paiementsEspeces}%</span>
|
||||
</div>
|
||||
<p:progressBar value="#{cotisationsGestionBean.paiementsEspeces}"
|
||||
showValue="false"
|
||||
styleClass="h-05rem" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section Filtrage avec structure Freya -->
|
||||
<div class="card">
|
||||
<h:form id="formFiltres">
|
||||
<div class="formgrid grid">
|
||||
<!-- Filtres principaux -->
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filtreOrganisation" class="block text-900 font-medium mb-2">Organisation</label>
|
||||
<p:selectOneMenu id="filtreOrganisation"
|
||||
value="#{cotisationsGestionBean.filtres.organisation}"
|
||||
filter="true" filterMatchMode="contains"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les organisations" itemValue="" />
|
||||
<f:selectItems value="#{cotisationsGestionBean.listeOrganisations}"
|
||||
var="org"
|
||||
itemLabel="#{org.nom}"
|
||||
itemValue="#{org.id}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-2">
|
||||
<label for="filtrePeriode" class="block text-900 font-medium mb-2">Période</label>
|
||||
<p:selectOneMenu id="filtrePeriode"
|
||||
value="#{cotisationsGestionBean.filtres.periode}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Ce mois" itemValue="MOIS" />
|
||||
<f:selectItem itemLabel="3 derniers mois" itemValue="TRIMESTRE" />
|
||||
<f:selectItem itemLabel="6 derniers mois" itemValue="SEMESTRE" />
|
||||
<f:selectItem itemLabel="Cette année" itemValue="ANNEE" />
|
||||
<f:selectItem itemLabel="Toutes" itemValue="TOUTES" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-2">
|
||||
<label for="filtreStatut" class="block text-900 font-medium mb-2">Statut</label>
|
||||
<p:selectOneMenu id="filtreStatut"
|
||||
value="#{cotisationsGestionBean.filtres.statut}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Payées" itemValue="PAYE" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="En retard" itemValue="EN_RETARD" />
|
||||
<f:selectItem itemLabel="Annulées" itemValue="ANNULE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-2">
|
||||
<label for="filtreType" class="block text-900 font-medium mb-2">Type</label>
|
||||
<p:selectOneMenu id="filtreType"
|
||||
value="#{cotisationsGestionBean.filtres.type}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Mensuelle" itemValue="MENSUELLE" />
|
||||
<f:selectItem itemLabel="Spéciale" itemValue="SPECIALE" />
|
||||
<f:selectItem itemLabel="Adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Événement" itemValue="EVENEMENT" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 lg:col-3">
|
||||
<label for="recherche" class="block text-900 font-medium mb-2">Recherche</label>
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="recherche"
|
||||
value="#{cotisationsGestionBean.filtres.recherche}"
|
||||
placeholder="Membre, numéro, référence..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" delay="300"
|
||||
update=":formTableCotisations:dtCotisations"
|
||||
listener="#{cotisationsGestionBean.appliquerFiltres}" />
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres avancés -->
|
||||
<p:panel header="Filtres Avancés (Business Intelligence)"
|
||||
toggleable="true"
|
||||
collapsed="true"
|
||||
styleClass="mt-3">
|
||||
<div class="formgrid grid mt-3">
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filtreMontantMin" class="block text-900 font-medium mb-2">Montant minimum</label>
|
||||
<p:inputNumber id="filtreMontantMin"
|
||||
value="#{cotisationsGestionBean.filtres.montantMin}"
|
||||
suffix=" FCFA"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filtreMontantMax" class="block text-900 font-medium mb-2">Montant maximum</label>
|
||||
<p:inputNumber id="filtreMontantMax"
|
||||
value="#{cotisationsGestionBean.filtres.montantMax}"
|
||||
suffix=" FCFA"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filtreRetardJours" class="block text-900 font-medium mb-2">Retard (jours)</label>
|
||||
<p:selectOneMenu id="filtreRetardJours"
|
||||
value="#{cotisationsGestionBean.filtres.retardJours}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="0-7 jours" itemValue="7" />
|
||||
<f:selectItem itemLabel="8-30 jours" itemValue="30" />
|
||||
<f:selectItem itemLabel="31-60 jours" itemValue="60" />
|
||||
<f:selectItem itemLabel="Plus de 60 jours" itemValue="60+" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filtreModePaiement" class="block text-900 font-medium mb-2">Mode de paiement</label>
|
||||
<p:selectOneMenu id="filtreModePaiement"
|
||||
value="#{cotisationsGestionBean.filtres.modePaiement}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="Wave Money" itemValue="WAVE" />
|
||||
<f:selectItem itemLabel="Orange Money" itemValue="ORANGE" />
|
||||
<f:selectItem itemLabel="Virement" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end mt-3">
|
||||
<p:commandButton value="Appliquer"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-primary ui-button-sm mr-2"
|
||||
action="#{cotisationsGestionBean.appliquerFiltres}"
|
||||
update="@form :formTableCotisations:dtCotisations" />
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary ui-button-sm"
|
||||
action="#{cotisationsGestionBean.reinitialiserFiltres}"
|
||||
update="@form :formTableCotisations:dtCotisations" />
|
||||
</div>
|
||||
</p:panel>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Table des Cotisations avec structure Freya -->
|
||||
<div class="card">
|
||||
<h:form id="formTableCotisations">
|
||||
<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 Cotisations
|
||||
</h5>
|
||||
<div class="flex gap-3 align-items-center">
|
||||
<p:commandButton value="Actions groupées"
|
||||
icon="pi pi-bars"
|
||||
styleClass="ui-button-warning ui-button-sm"
|
||||
onclick="PF('dlgActionsGroupees').show();"
|
||||
disabled="#{empty cotisationsGestionBean.cotisationsSelectionnees}" />
|
||||
<p:commandButton value="Export Excel"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-success ui-button-outlined ui-button-sm"
|
||||
action="#{cotisationsGestionBean.exporterExcel}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p:dataTable id="dtCotisations"
|
||||
var="cotisation"
|
||||
value="#{cotisationsGestionBean.cotisationsFiltrees}"
|
||||
selection="#{cotisationsGestionBean.cotisationsSelectionnees}"
|
||||
rowKey="#{cotisation.id}"
|
||||
paginator="true"
|
||||
rows="25"
|
||||
paginatorPosition="bottom"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="10,25,50,100"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords} cotisations"
|
||||
styleClass="p-datatable-sm p-datatable-gridlines p-datatable-striped"
|
||||
emptyMessage="Aucune cotisation trouvée">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:3rem" exportable="false"/>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{cotisation.nomOrganisation}" filterBy="#{cotisation.nomOrganisation}">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi #{cotisation.iconeOrganisation} text-primary mr-2"></i>
|
||||
<div>
|
||||
<div class="font-semibold">#{cotisation.nomOrganisation}</div>
|
||||
<div class="text-500 text-xs">#{cotisation.regionOrganisation}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{cotisation.nomCompletMembre}" filterBy="#{cotisation.nomCompletMembre}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="flex align-items-center justify-content-center bg-primary-100 border-circle mr-2"
|
||||
style="width: 2rem; height: 2rem;">
|
||||
<span class="text-primary-700 font-semibold text-sm">#{cotisation.initialesMembre}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.nomCompletMembre}</div>
|
||||
<div class="text-500 text-xs">#{cotisation.numeroMembre} • #{cotisation.typeMembre}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{cotisation.type}" filterBy="#{cotisation.type}" style="width:10rem">
|
||||
<p:tag value="#{cotisation.typeLibelle}"
|
||||
severity="#{cotisation.typeSeverity}"
|
||||
icon="pi #{cotisation.typeIcon}"
|
||||
styleClass="text-xs" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Période" sortBy="#{cotisation.periode}" style="width:10rem">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.periode}</div>
|
||||
<div class="text-500 text-xs">#{cotisation.annee}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{cotisation.montant}" style="width:8rem; text-align:right">
|
||||
<span class="font-bold text-green-600">#{cotisation.montantFormatte} FCFA</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{cotisation.statut}" filterBy="#{cotisation.statut}" style="width:8rem">
|
||||
<p:tag value="#{cotisation.statutLibelle}"
|
||||
severity="#{cotisation.statutSeverity}"
|
||||
icon="pi #{cotisation.statutIcon}"
|
||||
styleClass="text-xs w-full" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Échéance" sortBy="#{cotisation.dateEcheance}" style="width:8rem">
|
||||
<div>
|
||||
<div class="text-xs">#{cotisation.dateEcheanceFormattee}</div>
|
||||
<div class="text-xs #{cotisation.retardCouleur} font-semibold">#{cotisation.retardTexte}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Paiement" style="width:10rem">
|
||||
<div rendered="#{cotisation.datePaiement != null}">
|
||||
<div class="text-xs">#{cotisation.datePaiementFormattee}</div>
|
||||
<div class="flex align-items-center text-xs text-500">
|
||||
<i class="pi #{cotisation.modePaiementIcon} mr-1"></i>
|
||||
#{cotisation.modePaiementLibelle}
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-400 text-xs" rendered="#{cotisation.datePaiement == null}">Non payé</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:8rem" exportable="false">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success ui-button-sm"
|
||||
title="Enregistrer paiement"
|
||||
action="#{cotisationsGestionBean.enregistrerPaiement(cotisation)}"
|
||||
rendered="#{cotisation.statut != 'PAYE'}" />
|
||||
<p:commandButton icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info ui-button-sm"
|
||||
title="Générer reçu"
|
||||
action="#{cotisationsGestionBean.genererRecu(cotisation)}"
|
||||
rendered="#{cotisation.statut == 'PAYE'}" />
|
||||
<p:commandButton icon="pi pi-send"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning ui-button-sm"
|
||||
title="Envoyer rappel"
|
||||
action="#{cotisationsGestionBean.envoyerRappel(cotisation)}"
|
||||
rendered="#{cotisation.statut == 'EN_RETARD'}" />
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary ui-button-sm"
|
||||
title="Voir détails"
|
||||
action="#{cotisationsGestionBean.voirDetails(cotisation)}" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Résumé sélection -->
|
||||
<div class="surface-100 border-round-lg p-3 mt-3" rendered="#{not empty cotisationsGestionBean.cotisationsSelectionnees}">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span class="font-medium">
|
||||
<i class="pi pi-info-circle text-blue-500 mr-2"></i>
|
||||
#{cotisationsGestionBean.cotisationsSelectionnees.size()} cotisation(s) sélectionnée(s)
|
||||
</span>
|
||||
<span class="font-bold text-green-600">
|
||||
Montant total: #{cotisationsGestionBean.montantTotalSelectionne}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Section Wave Money avec structure Freya -->
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">
|
||||
<i class="pi pi-mobile text-teal-500 mr-2"></i>
|
||||
Intégration Wave Money
|
||||
</h5>
|
||||
|
||||
<div class="surface-50 border-round-lg p-3 mb-3">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-6">
|
||||
<div class="text-500 text-sm mb-1">Membres actifs</div>
|
||||
<div class="text-900 font-bold text-xl">#{cotisationsGestionBean.membresPrelevementActif}</div>
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<div class="text-500 text-sm mb-1">Montant mensuel</div>
|
||||
<div class="text-900 font-bold text-xl">#{cotisationsGestionBean.montantPrelevementMensuel}</div>
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<div class="text-500 text-sm mb-1">Prochain prélèvement</div>
|
||||
<div class="text-900 font-bold">#{cotisationsGestionBean.prochainPrelevement}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h:form id="formWaveMoney">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<p:commandButton value="Lancer prélèvements"
|
||||
icon="pi pi-play"
|
||||
styleClass="ui-button-success ui-button-sm"
|
||||
action="#{cotisationsGestionBean.lancerPrelevements}" />
|
||||
<p:commandButton value="Tester API"
|
||||
icon="pi pi-check-circle"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm"
|
||||
action="#{cotisationsGestionBean.testerAPIWave}" />
|
||||
<p:commandButton value="Historique"
|
||||
icon="pi pi-history"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm"
|
||||
action="#{cotisationsGestionBean.voirHistoriquePrelevements}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 lg:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">
|
||||
<i class="pi pi-bolt text-orange-500 mr-2"></i>
|
||||
Actions Rapides
|
||||
</h5>
|
||||
|
||||
<h:form id="formActionsRapides">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:commandButton value="Rapport mensuel"
|
||||
icon="pi pi-chart-bar"
|
||||
styleClass="ui-button-primary ui-button-outlined ui-button-sm w-full mb-2"
|
||||
action="#{cotisationsGestionBean.genererRapportMensuel}" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:commandButton value="Relances auto"
|
||||
icon="pi pi-sync"
|
||||
styleClass="ui-button-warning ui-button-outlined ui-button-sm w-full mb-2"
|
||||
action="#{cotisationsGestionBean.configurerRelancesAuto}" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:commandButton value="Types cotisations"
|
||||
icon="pi pi-tags"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm w-full mb-2"
|
||||
action="#{cotisationsGestionBean.gererTypesCotisations}" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:commandButton value="Tableau de bord"
|
||||
icon="pi pi-desktop"
|
||||
styleClass="ui-button-success ui-button-outlined ui-button-sm w-full mb-2"
|
||||
action="#{cotisationsGestionBean.tableauDeBord}" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialogs avec structure Freya -->
|
||||
|
||||
<!-- Dialog Nouvelle Campagne -->
|
||||
<p:dialog header="Créer une Nouvelle Campagne de Cotisation"
|
||||
widgetVar="dlgNouvelleCampagne"
|
||||
modal="true"
|
||||
width="600"
|
||||
height="auto"
|
||||
resizable="false">
|
||||
<h:form id="formNouvelleCampagne">
|
||||
<div class="ui-fluid formgrid grid">
|
||||
<div class="field col-12">
|
||||
<label for="nomCampagne" class="block text-900 font-medium mb-2">Nom de la campagne *</label>
|
||||
<p:inputText id="nomCampagne"
|
||||
value="#{cotisationsGestionBean.nouvelleCampagne.nom}"
|
||||
required="true"
|
||||
placeholder="Ex: Cotisation Janvier 2025" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="typeCampagne" class="block text-900 font-medium mb-2">Type *</label>
|
||||
<p:selectOneMenu id="typeCampagne"
|
||||
value="#{cotisationsGestionBean.nouvelleCampagne.type}"
|
||||
required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="Mensuelle" itemValue="MENSUELLE" />
|
||||
<f:selectItem itemLabel="Spéciale" itemValue="SPECIALE" />
|
||||
<f:selectItem itemLabel="Événement" itemValue="EVENEMENT" />
|
||||
<f:selectItem itemLabel="Adhésion" itemValue="ADHESION" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="montantCampagne" class="block text-900 font-medium mb-2">Montant (FCFA) *</label>
|
||||
<p:inputNumber id="montantCampagne"
|
||||
value="#{cotisationsGestionBean.nouvelleCampagne.montant}"
|
||||
required="true"
|
||||
symbol=" FCFA"
|
||||
symbolPosition="s"
|
||||
minValue="0" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="dateEcheanceCampagne" class="block text-900 font-medium mb-2">Date d'échéance *</label>
|
||||
<p:datePicker id="dateEcheanceCampagne"
|
||||
value="#{cotisationsGestionBean.nouvelleCampagne.dateEcheance}"
|
||||
required="true"
|
||||
showIcon="true"
|
||||
pattern="dd/MM/yyyy" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="scopeCampagne" class="block text-900 font-medium mb-2">Portée</label>
|
||||
<p:selectOneMenu id="scopeCampagne"
|
||||
value="#{cotisationsGestionBean.nouvelleCampagne.scope}">
|
||||
<f:selectItem itemLabel="Toutes les organisations" itemValue="TOUTES" />
|
||||
<f:selectItem itemLabel="Organisations sélectionnées" itemValue="SELECTION" />
|
||||
<f:selectItem itemLabel="Par région" itemValue="REGION" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<label for="descriptionCampagne" class="block text-900 font-medium mb-2">Description</label>
|
||||
<p:inputTextarea id="descriptionCampagne"
|
||||
value="#{cotisationsGestionBean.nouvelleCampagne.description}"
|
||||
rows="3"
|
||||
placeholder="Description optionnelle de la campagne..." />
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<p:selectBooleanCheckbox id="relanceAuto"
|
||||
value="#{cotisationsGestionBean.nouvelleCampagne.relanceAutomatique}" />
|
||||
<label for="relanceAuto" class="ml-2">Activer les relances automatiques</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm"
|
||||
onclick="PF('dlgNouvelleCampagne').hide();"
|
||||
type="button" />
|
||||
<p:commandButton value="Créer la campagne"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-success ui-button-sm"
|
||||
action="#{cotisationsGestionBean.creerCampagne}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgNouvelleCampagne').hide();" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Actions Groupées -->
|
||||
<p:dialog header="Actions Groupées"
|
||||
widgetVar="dlgActionsGroupees"
|
||||
modal="true"
|
||||
width="400"
|
||||
height="auto"
|
||||
resizable="false">
|
||||
<h:form id="formActionsGroupees">
|
||||
<div class="surface-50 border-round-lg p-3 mb-3">
|
||||
<div class="text-500 text-sm mb-1">Cotisations sélectionnées</div>
|
||||
<div class="text-900 font-bold text-xl">#{cotisationsGestionBean.cotisationsSelectionnees.size()}</div>
|
||||
<div class="text-500 text-sm">Montant total: #{cotisationsGestionBean.montantTotalSelectionne}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-column gap-2">
|
||||
<p:commandButton value="Marquer comme payées"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-success ui-button-sm w-full"
|
||||
action="#{cotisationsGestionBean.marquerPayeesGroupees}"
|
||||
onclick="PF('dlgActionsGroupees').hide();" />
|
||||
|
||||
<p:commandButton value="Envoyer relances"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-warning ui-button-sm w-full"
|
||||
action="#{cotisationsGestionBean.envoyerRelancesGroupees}"
|
||||
onclick="PF('dlgActionsGroupees').hide();" />
|
||||
|
||||
<p:commandButton value="Générer reçus"
|
||||
icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-info ui-button-sm w-full"
|
||||
action="#{cotisationsGestionBean.genererRecusGroupes}"
|
||||
onclick="PF('dlgActionsGroupees').hide();" />
|
||||
|
||||
<p:commandButton value="Annuler cotisations"
|
||||
icon="pi pi-times"
|
||||
styleClass="ui-button-danger ui-button-outlined ui-button-sm w-full"
|
||||
action="#{cotisationsGestionBean.annulerCotisationsGroupees}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler ces cotisations ?');" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,558 @@
|
||||
<!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 Demandes d'Aide - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<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="pi pi-heart text-red-500 mr-2"></i>
|
||||
Gestion des Demandes d'Aide
|
||||
</h3>
|
||||
<p class="text-600 m-0">Traitement et suivi des demandes d'assistance</p>
|
||||
</div>
|
||||
<h:form id="formActionsEntete">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouvelle demande"
|
||||
icon="pi pi-plus"
|
||||
styleClass="ui-button-success"
|
||||
onclick="PF('dlgNouvelleDemande').show();" />
|
||||
<p:commandButton value="Import demandes"
|
||||
icon="pi pi-upload"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
onclick="PF('dlgImportDemandes').show();" />
|
||||
<p:commandButton value="Exporter"
|
||||
icon="pi pi-download"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{demandesAideBean.exporterDemandes}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-blue-100 border-left-3 border-blue-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-blue-900 font-bold text-xl">#{demandesAideBean.statistiques.totalDemandes}</div>
|
||||
<div class="text-blue-700">Total Demandes</div>
|
||||
</div>
|
||||
<div class="bg-blue-500 text-white border-round text-center"
|
||||
style="width: 2.5rem; height: 2.5rem; line-height: 2.5rem;">
|
||||
<i class="pi pi-list text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-orange-100 border-left-3 border-orange-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-orange-900 font-bold text-xl">#{demandesAideBean.statistiques.demandesEnAttente}</div>
|
||||
<div class="text-orange-700">En Attente</div>
|
||||
</div>
|
||||
<div class="bg-orange-500 text-white border-round text-center"
|
||||
style="width: 2.5rem; height: 2.5rem; line-height: 2.5rem;">
|
||||
<i class="pi pi-clock text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-green-100 border-left-3 border-green-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-green-900 font-bold text-xl">#{demandesAideBean.statistiques.demandesApprouvees}</div>
|
||||
<div class="text-green-700">Approuvées</div>
|
||||
</div>
|
||||
<div class="bg-green-500 text-white border-round text-center"
|
||||
style="width: 2.5rem; height: 2.5rem; line-height: 2.5rem;">
|
||||
<i class="pi pi-check text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-purple-100 border-left-3 border-purple-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-purple-900 font-bold text-xl">#{demandesAideBean.statistiques.montantTotalAide}</div>
|
||||
<div class="text-purple-700">Aide Accordée</div>
|
||||
</div>
|
||||
<div class="bg-purple-500 text-white border-round text-center"
|
||||
style="width: 2.5rem; height: 2.5rem; line-height: 2.5rem;">
|
||||
<i class="pi pi-dollar text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Demandes prioritaires -->
|
||||
<div class="card">
|
||||
<h5>🚨 Demandes Prioritaires</h5>
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{demandesAideBean.demandesPrioritaires}" var="demande" varStatus="status">
|
||||
<div class="col-12 md:col-6 lg:col-4">
|
||||
<div class="card border-left-3 border-#{demande.urgenceSeverity} hover:surface-50 transition-colors transition-duration-150">
|
||||
<div class="flex align-items-start justify-content-between mb-3">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-#{demande.urgenceSeverity} text-white border-round flex align-items-center justify-content-center mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi #{demande.typeIcon}"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 m-0 mb-1">#{demande.demandeur}</h6>
|
||||
<p:tag value="#{demande.typeLibelle}" severity="#{demande.typeSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
<p:tag value="#{demande.urgence}" severity="#{demande.urgenceSeverity}" />
|
||||
</div>
|
||||
|
||||
<div class="text-600 mb-3">
|
||||
<div class="flex align-items-center mb-2">
|
||||
<i class="pi pi-calendar mr-2"></i>
|
||||
<span>#{demande.dateDemandeFormatee}</span>
|
||||
</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<i class="pi pi-map-marker mr-2"></i>
|
||||
<span>#{demande.localisation}</span>
|
||||
</div>
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-dollar mr-2"></i>
|
||||
<span>#{demande.montantDemandeFormatte}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-sm text-600 mb-3">
|
||||
#{demande.motif}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-between align-items-center">
|
||||
<span class="text-600 text-sm">#{demande.joursDepuisDemande} jours</span>
|
||||
<h:form>
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
title="Voir détails">
|
||||
<f:setPropertyActionListener target="#{demandesAideBean.demandeSelectionnee}" value="#{demande}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
title="Approuver"
|
||||
action="#{demandesAideBean.approuverDemande}">
|
||||
<f:setPropertyActionListener target="#{demandesAideBean.demandeSelectionnee}" value="#{demande}" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Workflow des demandes -->
|
||||
<div class="card">
|
||||
<h5>📋 Workflow de Traitement</h5>
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{demandesAideBean.etapesWorkflow}" var="etape" varStatus="status">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="text-center p-3">
|
||||
<div class="bg-#{etape.couleur} text-white border-round flex align-items-center justify-content-center mx-auto mb-3"
|
||||
style="width: 3rem; height: 3rem;">
|
||||
<i class="pi #{etape.icon} text-xl"></i>
|
||||
</div>
|
||||
<h6 class="text-900 mb-2">#{etape.libelle}</h6>
|
||||
<div class="text-2xl font-bold text-#{etape.couleur} mb-1">#{etape.nombre}</div>
|
||||
<div class="text-600 text-sm">demandes</div>
|
||||
</div>
|
||||
<div class="text-center" rendered="#{status.index lt demandesAideBean.etapesWorkflow.size() - 1}">
|
||||
<i class="pi pi-arrow-right text-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et recherche -->
|
||||
<div class="card">
|
||||
<h5>Filtres et Recherche</h5>
|
||||
<h:form id="formFiltres">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchDemandeur" value="Demandeur" />
|
||||
<p:inputText id="searchDemandeur" value="#{demandesAideBean.filtres.demandeur}"
|
||||
placeholder="Rechercher par nom...">
|
||||
<p:ajax event="keyup" update="dtDemandes @(.stats-summary)" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filterType" value="Type d'aide" />
|
||||
<p:selectOneMenu id="filterType" value="#{demandesAideBean.filtres.type}">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Aide Médicale" itemValue="AIDE_MEDICALE" />
|
||||
<f:selectItem itemLabel="Aide Alimentaire" itemValue="AIDE_ALIMENTAIRE" />
|
||||
<f:selectItem itemLabel="Aide Éducative" itemValue="AIDE_EDUCATIVE" />
|
||||
<f:selectItem itemLabel="Aide Logement" itemValue="AIDE_LOGEMENT" />
|
||||
<f:selectItem itemLabel="Aide d'Urgence" itemValue="AIDE_URGENCE" />
|
||||
<p:ajax update="dtDemandes @(.stats-summary)" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filterStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filterStatut" value="#{demandesAideBean.filtres.statut}">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="En évaluation" itemValue="EN_EVALUATION" />
|
||||
<f:selectItem itemLabel="Approuvée" itemValue="APPROUVEE" />
|
||||
<f:selectItem itemLabel="Rejetée" itemValue="REJETEE" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
|
||||
<f:selectItem itemLabel="Terminée" itemValue="TERMINEE" />
|
||||
<p:ajax update="dtDemandes @(.stats-summary)" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filterUrgence" value="Urgence" />
|
||||
<p:selectOneMenu id="filterUrgence" value="#{demandesAideBean.filtres.urgence}">
|
||||
<f:selectItem itemLabel="Toutes les urgences" itemValue="" />
|
||||
<f:selectItem itemLabel="Faible" itemValue="FAIBLE" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Élevée" itemValue="ELEVEE" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
|
||||
<p:ajax update="dtDemandes @(.stats-summary)" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filterDateDebut" value="Date début" />
|
||||
<p:datePicker id="filterDateDebut" value="#{demandesAideBean.filtres.dateDebut}"
|
||||
placeholder="Sélectionner une date">
|
||||
<p:ajax update="dtDemandes @(.stats-summary)" />
|
||||
</p:datePicker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filterDateFin" value="Date fin" />
|
||||
<p:datePicker id="filterDateFin" value="#{demandesAideBean.filtres.dateFin}"
|
||||
placeholder="Sélectionner une date">
|
||||
<p:ajax update="dtDemandes @(.stats-summary)" />
|
||||
</p:datePicker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filterLocalisation" value="Localisation" />
|
||||
<p:inputText id="filterLocalisation" value="#{demandesAideBean.filtres.localisation}"
|
||||
placeholder="Filtrer par zone...">
|
||||
<p:ajax event="keyup" update="dtDemandes @(.stats-summary)" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Rechercher"
|
||||
icon="pi pi-search"
|
||||
styleClass="ui-button-primary"
|
||||
action="#{demandesAideBean.rechercher}"
|
||||
update="dtDemandes @(.stats-summary)" />
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{demandesAideBean.reinitialiserFiltres}"
|
||||
update="@form dtDemandes @(.stats-summary)" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Liste des demandes -->
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h5 class="m-0">Demandes d'Aide (#{demandesAideBean.demandesFiltrees.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 demandesAideBean.demandesSelectionnees}" />
|
||||
</h:form>
|
||||
<span class="text-600 text-sm stats-summary">
|
||||
#{demandesAideBean.demandesFiltrees.size()} sur #{demandesAideBean.toutesLesDemandes.size()} demandes
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p:dataTable id="dtDemandes"
|
||||
value="#{demandesAideBean.demandesFiltrees}"
|
||||
var="demande"
|
||||
selection="#{demandesAideBean.demandesSelectionnees}"
|
||||
rowKey="#{demande.id}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorPosition="both"
|
||||
sortMode="single"
|
||||
styleClass="p-datatable-sm"
|
||||
emptyMessage="Aucune demande trouvée">
|
||||
|
||||
<p:column selectionMode="multiple" width="40" />
|
||||
|
||||
<p:column headerText="Demandeur" sortBy="#{demande.demandeur}" width="200">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-3"
|
||||
style="width: 32px; height: 32px;">
|
||||
<i class="pi pi-user"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{demande.demandeur}</div>
|
||||
<div class="text-600 text-sm">#{demande.telephone}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type d'aide" sortBy="#{demande.type}" width="130">
|
||||
<p:tag value="#{demande.typeLibelle}"
|
||||
severity="#{demande.typeSeverity}"
|
||||
icon="pi #{demande.typeIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Motif" width="250">
|
||||
<div class="text-900 text-sm">#{demande.motif}</div>
|
||||
<div class="text-600 text-xs" rendered="#{demande.description != null and demande.description.length() > 0}">
|
||||
#{demande.description.length() > 50 ? demande.description.substring(0, 50) + '...' : demande.description}
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{demande.montantDemande}" width="100">
|
||||
<div class="text-900 text-sm text-right font-bold">#{demande.montantDemandeFormatte}</div>
|
||||
<div class="text-600 text-xs text-right" rendered="#{demande.montantAccorde != null}">
|
||||
Accordé: #{demande.montantAccordeFormatte}
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date demande" sortBy="#{demande.dateDemande}" width="100">
|
||||
<div class="text-900 text-sm">#{demande.dateDemandeFormatee}</div>
|
||||
<div class="text-600 text-xs">#{demande.joursDepuisDemande} jours</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Localisation" width="120">
|
||||
<div class="text-900 text-sm">#{demande.localisation}</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Urgence" sortBy="#{demande.urgence}" width="80">
|
||||
<p:tag value="#{demande.urgence}"
|
||||
severity="#{demande.urgenceSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{demande.statut}" width="100">
|
||||
<p:tag value="#{demande.statutLibelle}"
|
||||
severity="#{demande.statutSeverity}"
|
||||
icon="pi #{demande.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" width="150">
|
||||
<h:form id="formActions#{demande.id}">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
onclick="PF('dlgDetailsDemande').show();"
|
||||
title="Voir détails">
|
||||
<f:setPropertyActionListener target="#{demandesAideBean.demandeSelectionnee}" value="#{demande}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
title="Approuver"
|
||||
action="#{demandesAideBean.approuverDemande}"
|
||||
rendered="#{demande.statut == 'EN_ATTENTE' or demande.statut == 'EN_EVALUATION'}">
|
||||
<f:setPropertyActionListener target="#{demandesAideBean.demandeSelectionnee}" value="#{demande}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
title="Rejeter"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir rejeter cette demande ?');"
|
||||
action="#{demandesAideBean.rejeterDemande}"
|
||||
rendered="#{demande.statut == 'EN_ATTENTE' or demande.statut == 'EN_EVALUATION'}">
|
||||
<f:setPropertyActionListener target="#{demandesAideBean.demandeSelectionnee}" value="#{demande}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-cog"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
onclick="PF('dlgActionsDemande').show();"
|
||||
title="Actions">
|
||||
<f:setPropertyActionListener target="#{demandesAideBean.demandeSelectionnee}" value="#{demande}" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Demande -->
|
||||
<p:dialog header="Créer une Nouvelle Demande" widgetVar="dlgNouvelleDemande" modal="true" width="900">
|
||||
<h:form id="formNouvelleDemande">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="newDemandeur" value="Nom du demandeur" />
|
||||
<p:inputText id="newDemandeur" value="#{demandesAideBean.nouvelleDemande.demandeur}" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="newTelephone" value="Téléphone" />
|
||||
<p:inputText id="newTelephone" value="#{demandesAideBean.nouvelleDemande.telephone}" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="newEmail" value="Email" />
|
||||
<p:inputText id="newEmail" value="#{demandesAideBean.nouvelleDemande.email}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="newType" value="Type d'aide" />
|
||||
<p:selectOneMenu id="newType" value="#{demandesAideBean.nouvelleDemande.type}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner un type" itemValue="" />
|
||||
<f:selectItem itemLabel="Aide Médicale" itemValue="AIDE_MEDICALE" />
|
||||
<f:selectItem itemLabel="Aide Alimentaire" itemValue="AIDE_ALIMENTAIRE" />
|
||||
<f:selectItem itemLabel="Aide Éducative" itemValue="AIDE_EDUCATIVE" />
|
||||
<f:selectItem itemLabel="Aide Logement" itemValue="AIDE_LOGEMENT" />
|
||||
<f:selectItem itemLabel="Aide d'Urgence" itemValue="AIDE_URGENCE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="newLocalisation" value="Localisation" />
|
||||
<p:inputText id="newLocalisation" value="#{demandesAideBean.nouvelleDemande.localisation}" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="newMontant" value="Montant demandé" />
|
||||
<p:inputNumber id="newMontant" value="#{demandesAideBean.nouvelleDemande.montantDemande}"
|
||||
mode="currency" currency="XOF" locale="fr-CI" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="newUrgence" value="Niveau d'urgence" />
|
||||
<p:selectOneMenu id="newUrgence" value="#{demandesAideBean.nouvelleDemande.urgence}">
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Faible" itemValue="FAIBLE" />
|
||||
<f:selectItem itemLabel="Élevée" itemValue="ELEVEE" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="newDateLimite" value="Date limite souhaitée" />
|
||||
<p:datePicker id="newDateLimite" value="#{demandesAideBean.nouvelleDemande.dateLimite}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="newMotif" value="Motif de la demande" />
|
||||
<p:inputText id="newMotif" value="#{demandesAideBean.nouvelleDemande.motif}" required="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="newDescription" value="Description détaillée" />
|
||||
<p:inputTextarea id="newDescription" value="#{demandesAideBean.nouvelleDemande.description}" rows="4" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Créer" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{demandesAideBean.creerDemande}"
|
||||
update="@form dtDemandes @(.stats-summary)"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgNouvelleDemande').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgNouvelleDemande').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Actions Demande -->
|
||||
<p:dialog header="Actions sur la Demande" widgetVar="dlgActionsDemande" modal="true" width="400">
|
||||
<h:form id="formActionsDemande">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<p:commandButton value="Assigner à un responsable"
|
||||
icon="pi pi-user-plus"
|
||||
styleClass="ui-button-outlined ui-button-info w-full mb-2"
|
||||
onclick="PF('dlgAssignerResponsable').show();" />
|
||||
|
||||
<p:commandButton value="Programmer une visite"
|
||||
icon="pi pi-calendar-plus"
|
||||
styleClass="ui-button-outlined ui-button-success w-full mb-2"
|
||||
onclick="PF('dlgProgrammerVisite').show();" />
|
||||
|
||||
<p:commandButton value="Ajouter des documents"
|
||||
icon="pi pi-file-plus"
|
||||
styleClass="ui-button-outlined ui-button-warning w-full mb-2"
|
||||
onclick="PF('dlgAjouterDocuments').show();" />
|
||||
|
||||
<p:commandButton value="Historique du traitement"
|
||||
icon="pi pi-history"
|
||||
styleClass="ui-button-outlined ui-button-secondary w-full mb-2"
|
||||
action="#{demandesAideBean.voirHistorique}" />
|
||||
|
||||
<p:commandButton value="Envoyer notification"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-outlined ui-button-primary w-full mb-2"
|
||||
action="#{demandesAideBean.envoyerNotification}" />
|
||||
|
||||
<p:commandButton value="Dupliquer la demande"
|
||||
icon="pi pi-copy"
|
||||
styleClass="ui-button-outlined ui-button-help w-full"
|
||||
action="#{demandesAideBean.dupliquerDemande}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end mt-3">
|
||||
<p:commandButton value="Fermer" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgActionsDemande').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,561 @@
|
||||
<!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 Demandes d'Aide - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<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="pi pi-heart text-red-500 mr-2"></i>
|
||||
Gestion des Demandes d'Aide
|
||||
</h3>
|
||||
<p class="text-600 m-0">Traitement et suivi des demandes d'assistance</p>
|
||||
</div>
|
||||
<h:form id="formActionsEntete">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouvelle demande"
|
||||
icon="pi pi-plus"
|
||||
styleClass="ui-button-success"
|
||||
onclick="PF('dlgNouvelleDemande').show();" />
|
||||
<p:commandButton value="Import demandes"
|
||||
icon="pi pi-upload"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
onclick="PF('dlgImportDemandes').show();" />
|
||||
<p:commandButton value="Exporter"
|
||||
icon="pi pi-download"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{demandesBean.exporterDemandes}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-orange-100 border-left-3 border-orange-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-orange-900 font-bold text-2xl">#{demandeBean.enAttente}</div>
|
||||
<div class="text-orange-700">En Attente</div>
|
||||
</div>
|
||||
<div class="bg-orange-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-clock text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-red-100 border-left-3 border-red-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-red-900 font-bold text-2xl">#{demandeBean.urgentes}</div>
|
||||
<div class="text-red-700">Urgentes</div>
|
||||
</div>
|
||||
<div class="bg-red-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-exclamation-triangle text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-green-100 border-left-3 border-green-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-green-900 font-bold text-2xl">#{demandeBean.traitees}</div>
|
||||
<div class="text-green-700">Traitées</div>
|
||||
</div>
|
||||
<div class="bg-green-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-check text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-blue-100 border-left-3 border-blue-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-blue-900 font-bold text-2xl">#{demandeBean.delaiMoyenTraitement}</div>
|
||||
<div class="text-blue-700">Délai Moyen (jours)</div>
|
||||
</div>
|
||||
<div class="bg-blue-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-calendar text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Demandes urgentes et récentes -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-exclamation-triangle text-red-500 mr-2"></i>
|
||||
Demandes Urgentes
|
||||
</h5>
|
||||
<ui:repeat value="#{demandeBean.demandesUrgentes}" var="demande" varStatus="status">
|
||||
<div class="flex align-items-start p-3 mb-2 border-round border-left-3 border-red-500"
|
||||
style="background: var(--red-50);">
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="font-medium text-900">#{demande.objet}</span>
|
||||
<p:tag value="#{demande.type}" severity="danger" />
|
||||
</div>
|
||||
<div class="text-600 mb-2">
|
||||
<i class="pi pi-user mr-1"></i>
|
||||
#{demande.demandeur} • #{demande.numeroMembre}
|
||||
</div>
|
||||
<div class="text-sm text-600">
|
||||
Déposée #{demande.dateDepotRelative} • Échéance: #{demande.dateEcheance}
|
||||
</div>
|
||||
</div>
|
||||
<h:form id="formActionsUrgentes">
|
||||
<div class="flex gap-1 ml-3">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{demandeBean.voirDemande(demande)}" />
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{demandeBean.traiterDemande(demande)}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<h:form id="formVoirUrgentes">
|
||||
<p:commandButton value="Voir toutes les urgentes"
|
||||
icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-outlined ui-button-danger w-full mt-2"
|
||||
action="#{demandeBean.filtrerUrgentes}" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-clock text-blue-500 mr-2"></i>
|
||||
Dernières Demandes
|
||||
</h5>
|
||||
<ui:repeat value="#{demandeBean.dernieresDemandes}" var="demande" varStatus="status">
|
||||
<div class="flex align-items-start p-3 mb-2 border-round"
|
||||
style="background: var(--surface-50);">
|
||||
<div class="border-round p-2 mr-3 #{demande.typeColorClass}">
|
||||
<i class="pi #{demande.typeIcon} text-white"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center justify-content-between mb-1">
|
||||
<span class="font-medium text-900">#{demande.objet}</span>
|
||||
<small class="text-600">#{demande.dateDepotRelative}</small>
|
||||
</div>
|
||||
<div class="text-600 text-sm mb-1">
|
||||
#{demande.demandeur} • #{demande.numeroMembre}
|
||||
</div>
|
||||
<p:tag value="#{demande.statut}" severity="#{demande.statutSeverity}" />
|
||||
</div>
|
||||
<h:form id="formActionsRecentes">
|
||||
<div class="flex gap-1 ml-2">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-sm"
|
||||
action="#{demandeBean.voirDemande(demande)}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Graphiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<div class="card">
|
||||
<h5>Évolution des Demandes</h5>
|
||||
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique temporaire</div></div><!--chart
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="card">
|
||||
<h5>Répartition par Type</h5>
|
||||
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique temporaire</div></div><!--chart
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste complète des demandes -->
|
||||
<div class="card">
|
||||
<h:form id="formDemandes">
|
||||
<h5>Toutes les Demandes</h5>
|
||||
|
||||
<!-- Filtres -->
|
||||
<p:toolbar>
|
||||
<p:toolbarGroup>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText placeholder="Rechercher..."
|
||||
value="#{demandeBean.searchFilter}">
|
||||
<p:ajax event="keyup" update="dtDemandes" />
|
||||
</p:inputText>
|
||||
</span>
|
||||
|
||||
<p:selectOneMenu value="#{demandeBean.statutFilter}">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
|
||||
<f:selectItem itemLabel="Approuvée" itemValue="APPROUVEE" />
|
||||
<f:selectItem itemLabel="Rejetée" itemValue="REJETEE" />
|
||||
<f:selectItem itemLabel="Annulée" itemValue="ANNULEE" />
|
||||
<p:ajax update="dtDemandes" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{demandeBean.typeFilter}">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Aide financière" itemValue="AIDE_FINANCIERE" />
|
||||
<f:selectItem itemLabel="Certificat" itemValue="CERTIFICAT" />
|
||||
<f:selectItem itemLabel="Mutation" itemValue="MUTATION" />
|
||||
<f:selectItem itemLabel="Réclamation" itemValue="RECLAMATION" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
<p:ajax update="dtDemandes" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{demandeBean.prioriteFilter}">
|
||||
<f:selectItem itemLabel="Toutes priorités" itemValue="" />
|
||||
<f:selectItem itemLabel="Urgente" itemValue="URGENTE" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Basse" itemValue="BASSE" />
|
||||
<p:ajax update="dtDemandes" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:calendar value="#{demandeBean.dateFilter}"
|
||||
pattern="dd/MM/yyyy" showIcon="true"
|
||||
placeholder="Filtrer par date">
|
||||
<p:ajax event="dateSelect" update="dtDemandes" />
|
||||
</p:calendar>
|
||||
</div>
|
||||
</p:toolbarGroup>
|
||||
|
||||
<p:toolbarGroup align="right">
|
||||
<p:commandButton icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{demandeBean.actualiser}"
|
||||
update="@form"
|
||||
title="Actualiser" />
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtDemandes"
|
||||
var="demande"
|
||||
value="#{demandeBean.demandes}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="10,15,25,50"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{demandeBean.selectedDemandes}"
|
||||
rowKey="#{demande.id}"
|
||||
selectionMode="multiple"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{demande.reference}" style="width:120px">
|
||||
<h:outputText value="#{demande.reference}" styleClass="font-mono font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Demandeur" sortBy="#{demande.nomDemandeur}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-2"
|
||||
style="width: 30px; height: 30px;">
|
||||
<span style="font-size: 0.8rem;">#{demande.initialesDemandeur}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-900">#{demande.nomCompletDemandeur}</div>
|
||||
<small class="text-600">#{demande.numeroMembre} • #{demande.telephoneDemandeur}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{demande.type}" style="width:140px">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-round p-2 mr-2 #{demande.typeColorClass}">
|
||||
<i class="pi #{demande.typeIcon} text-white text-sm"></i>
|
||||
</div>
|
||||
<span>#{demande.type}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Objet" sortBy="#{demande.objet}">
|
||||
<h:outputText value="#{demande.objet}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Priorité" sortBy="#{demande.priorite}" style="width:100px">
|
||||
<p:tag value="#{demande.priorite}"
|
||||
severity="#{demande.prioriteSeverity}"
|
||||
icon="pi #{demande.prioriteIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{demande.statut}" style="width:120px">
|
||||
<p:tag value="#{demande.statut}"
|
||||
severity="#{demande.statutSeverity}"
|
||||
icon="pi #{demande.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date dépôt" sortBy="#{demande.dateDepot}" style="width:120px">
|
||||
<div>
|
||||
<div class="font-medium">#{demande.dateDepot}</div>
|
||||
<small class="text-600">#{demande.heureDepot}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Échéance" sortBy="#{demande.dateEcheance}" style="width:120px">
|
||||
<h:outputText value="#{demande.dateEcheance}"
|
||||
styleClass="#{demande.echeanceClass}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Assignée à" sortBy="#{demande.assigneA}" style="width:120px">
|
||||
<h:outputText value="#{demande.assigneA}" rendered="#{demande.assigneA != null}" />
|
||||
<span class="text-400" rendered="#{demande.assigneA == null}">Non assignée</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{demandeBean.voirDemande(demande)}"
|
||||
title="Voir détails" />
|
||||
<p:commandButton icon="pi pi-user"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
action="#{demandeBean.assignerDemande(demande)}"
|
||||
title="Assigner"
|
||||
rendered="#{demande.assigneA == null}" />
|
||||
<p:commandButton icon="pi pi-cog"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
action="#{demandeBean.traiterDemande(demande)}"
|
||||
title="Traiter"
|
||||
rendered="#{demande.statut == 'EN_ATTENTE' or demande.statut == 'EN_COURS'}" />
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{demandeBean.approuverDemande(demande)}"
|
||||
title="Approuver"
|
||||
rendered="#{demande.statut == 'EN_COURS'}" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
action="#{demandeBean.rejeterDemande(demande)}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir rejeter cette demande ?');"
|
||||
title="Rejeter"
|
||||
rendered="#{demande.statut == 'EN_COURS'}" />
|
||||
<p:commandButton icon="pi pi-file"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
action="#{demandeBean.voirPiecesJointes(demande)}"
|
||||
title="Pièces jointes"
|
||||
rendered="#{demande.hasPiecesJointes}" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Actions groupées -->
|
||||
<div class="mt-3 flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<span class="text-600">#{demandeBean.selectedDemandes.size()} demande(s) sélectionnée(s)</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Assigner en lot"
|
||||
icon="pi pi-users"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
onclick="PF('dlgAssignationLot').show();"
|
||||
disabled="#{empty demandeBean.selectedDemandes}" />
|
||||
<p:commandButton value="Marquer traitées"
|
||||
icon="pi pi-check-circle"
|
||||
styleClass="ui-button-outlined ui-button-success"
|
||||
action="#{demandeBean.marquerTraitees}"
|
||||
disabled="#{empty demandeBean.selectedDemandes}" />
|
||||
<p:commandButton value="Exporter sélection"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{demandeBean.exporterSelection}"
|
||||
disabled="#{empty demandeBean.selectedDemandes}" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Demande -->
|
||||
<p:dialog header="Nouvelle Demande" widgetVar="dlgNouvelleDemande" modal="true" width="700">
|
||||
<h:form id="formNouvelleDemande">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="demandeurSelect" value="Demandeur" />
|
||||
<p:autoComplete id="demandeurSelect"
|
||||
value="#{demandeBean.membreDemandeur}"
|
||||
completeMethod="#{demandeBean.rechercherMembres}"
|
||||
var="membre" itemLabel="#{membre.nomComplet}" itemValue="#{membre}"
|
||||
converter="membreConverter"
|
||||
placeholder="Rechercher un membre...">
|
||||
<p:column>
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-2"
|
||||
style="width: 30px; height: 30px;">
|
||||
<span style="font-size: 0.8rem;">#{membre.initiales}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium">#{membre.nomComplet}</div>
|
||||
<small class="text-600">#{membre.numeroMembre}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:autoComplete>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="typeDemande" value="Type de demande" />
|
||||
<p:selectOneMenu id="typeDemande" value="#{demandeBean.nouvelleDemande.type}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="📋 Adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="💰 Aide financière" itemValue="AIDE_FINANCIERE" />
|
||||
<f:selectItem itemLabel="📄 Certificat" itemValue="CERTIFICAT" />
|
||||
<f:selectItem itemLabel="🔄 Mutation" itemValue="MUTATION" />
|
||||
<f:selectItem itemLabel="⚠️ Réclamation" itemValue="RECLAMATION" />
|
||||
<f:selectItem itemLabel="🔧 Autre" itemValue="AUTRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="prioriteDemande" value="Priorité" />
|
||||
<p:selectOneMenu id="prioriteDemande" value="#{demandeBean.nouvelleDemande.priorite}">
|
||||
<f:selectItem itemLabel="🔴 Urgente" itemValue="URGENTE" />
|
||||
<f:selectItem itemLabel="🟡 Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="🟢 Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="⚪ Basse" itemValue="BASSE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="objetDemande" value="Objet" />
|
||||
<p:inputText id="objetDemande" value="#{demandeBean.nouvelleDemande.objet}"
|
||||
required="true" placeholder="Résumé de la demande" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="dateEcheanceDemande" value="Date d'échéance" />
|
||||
<p:calendar id="dateEcheanceDemande" value="#{demandeBean.nouvelleDemande.dateEcheance}"
|
||||
pattern="dd/MM/yyyy" showIcon="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="assignerA" value="Assigner à" />
|
||||
<p:selectOneMenu id="assignerA" value="#{demandeBean.nouvelleDemande.assigneA}">
|
||||
<f:selectItem itemLabel="Non assigné" itemValue="" />
|
||||
<f:selectItems value="#{demandeBean.gestionnairesDisponibles}"
|
||||
var="gestionnaire"
|
||||
itemLabel="#{gestionnaire.nom}"
|
||||
itemValue="#{gestionnaire.id}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="descriptionDemande" value="Description détaillée" />
|
||||
<p:inputTextarea id="descriptionDemande" value="#{demandeBean.nouvelleDemande.description}"
|
||||
rows="4" placeholder="Décrivez la demande en détail..." />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="piecesJointes" value="Pièces jointes" />
|
||||
<p:fileUpload id="piecesJointes" mode="advanced"
|
||||
multiple="true" dragDropSupport="true"
|
||||
uploadLabel="Télécharger" cancelLabel="Annuler" chooseLabel="Sélectionner"
|
||||
sizeLimit="5000000" fileLimit="5" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Créer la demande" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{demandeBean.creerDemande}"
|
||||
update="@form :formDemandes"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgNouvelleDemande').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgNouvelleDemande').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Assignation en Lot -->
|
||||
<p:dialog header="Assignation en Lot" widgetVar="dlgAssignationLot" modal="true" width="400">
|
||||
<h:form id="formAssignationLot">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="gestionnaireAssignation" value="Assigner à" />
|
||||
<p:selectOneMenu id="gestionnaireAssignation" value="#{demandeBean.gestionnaireAssignation}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItems value="#{demandeBean.gestionnairesDisponibles}"
|
||||
var="gestionnaire"
|
||||
itemLabel="#{gestionnaire.nom}"
|
||||
itemValue="#{gestionnaire.id}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="commentaireAssignation" value="Commentaire" />
|
||||
<p:inputTextarea id="commentaireAssignation" value="#{demandeBean.commentaireAssignation}"
|
||||
rows="3" placeholder="Commentaire optionnel..." />
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Demandes sélectionnées :</div>
|
||||
<div class="text-600">#{demandeBean.selectedDemandes.size()} demande(s) seront assignées</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Assigner" icon="pi pi-check"
|
||||
styleClass="ui-button-warning"
|
||||
action="#{demandeBean.effectuerAssignationLot}"
|
||||
update="@form :formDemandes"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgAssignationLot').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgAssignationLot').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,714 @@
|
||||
<!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 Demandes d'Aide - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
<!-- En-tête principal avec composant réutilisable -->
|
||||
<ui:include src="/templates/components/layout/page-header.xhtml">
|
||||
<ui:param name="icon" value="pi pi-heart text-red-500" />
|
||||
<ui:param name="title" value="Gestion des Demandes d'Aide" />
|
||||
<ui:param name="description" value="Traitement et suivi des demandes d'assistance • #{demandeBean.demandes.size()} demandes • #{demandeBean.enAttente} en attente" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsEntete">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="title" value="Nouvelle demande" />
|
||||
<ui:param name="onclick" value="PF('dlgNouvelleDemande').show();" />
|
||||
<ui:param name="styleClass" value="ui-button-sm mr-3" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="title" value="Import demandes" />
|
||||
<ui:param name="onclick" value="PF('dlgImportDemandes').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm mr-3" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="title" value="Exporter" />
|
||||
<ui:param name="action" value="#{demandeBean.exporterDemandes}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- KPIs avec composant réutilisable -->
|
||||
<div class="formgrid grid">
|
||||
<!-- KPI 1: En Attente -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="En Attente" />
|
||||
<ui:param name="value" value="#{demandeBean.enAttente}" />
|
||||
<ui:param name="icon" value="pi-clock" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 2: Demandes Urgentes -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Urgentes" />
|
||||
<ui:param name="value" value="#{demandeBean.urgentes}" />
|
||||
<ui:param name="icon" value="pi-exclamation-triangle" />
|
||||
<ui:param name="iconColor" value="red-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 3: Traitées -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Traitées" />
|
||||
<ui:param name="value" value="#{demandeBean.traitees}" />
|
||||
<ui:param name="icon" value="pi-check" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 4: Délai Moyen -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Délai Moyen" />
|
||||
<ui:param name="value" value="#{demandeBean.delaiMoyenTraitement} jours" />
|
||||
<ui:param name="icon" value="pi-calendar" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-6 lg:col-3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Demandes urgentes et récentes -->
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-8">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-3">
|
||||
<h5 class="text-900 font-bold mb-3">
|
||||
<i class="pi pi-exclamation-triangle text-red-500 mr-2"></i>
|
||||
Demandes Urgentes
|
||||
</h5>
|
||||
|
||||
<ui:repeat value="#{demandeBean.demandesUrgentes}" var="demande" varStatus="status">
|
||||
<div class="surface-100 border-round-lg p-3 mb-3 border-left-3 border-red-500 hover:surface-200 transition-colors transition-duration-150">
|
||||
<div class="flex align-items-start justify-content-between">
|
||||
<div class="flex align-items-start">
|
||||
<div class="flex align-items-center justify-content-center surface-100 border-round-lg mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi #{demande.typeIcon} text-red-600"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<h6 class="text-900 font-medium m-0">#{demande.objet}</h6>
|
||||
<p:tag value="#{demande.priorite}"
|
||||
severity="#{demande.prioriteSeverity}"
|
||||
styleClass="text-xs" />
|
||||
</div>
|
||||
<div class="text-600 mb-2 text-sm">
|
||||
<i class="pi pi-user mr-2"></i>
|
||||
<span class="font-medium">#{demande.demandeur}</span> • #{demande.numeroMembre}
|
||||
</div>
|
||||
<div class="flex align-items-center text-xs text-500">
|
||||
<i class="pi pi-clock mr-1"></i>
|
||||
<span>Déposée #{demande.dateDepotRelative}</span>
|
||||
<span class="mx-2">•</span>
|
||||
<i class="pi pi-calendar mr-1"></i>
|
||||
<span>Échéance: #{demande.dateEcheance}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h:form>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="title" value="Voir détails" />
|
||||
<ui:param name="action" value="#{demandeBean.voirDemande(demande)}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="title" value="Traiter" />
|
||||
<ui:param name="action" value="#{demandeBean.traiterDemande(demande)}" />
|
||||
<ui:param name="update" value=":formDemandes:dtDemandes" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<div class="mt-3">
|
||||
<h:form>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Voir toutes les urgentes" />
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{demandeBean.filtrerUrgentes}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-danger ui-button-sm w-full" />
|
||||
</ui:include>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-4">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-3">
|
||||
<h5 class="text-900 font-bold mb-3">
|
||||
<i class="pi pi-clock text-blue-500 mr-2"></i>
|
||||
Dernières Demandes
|
||||
</h5>
|
||||
|
||||
<ui:repeat value="#{demandeBean.dernieresDemandes}" var="demande" varStatus="status">
|
||||
<div class="surface-100 border-round-lg p-3 mb-3 hover:surface-200 transition-colors transition-duration-150">
|
||||
<div class="flex align-items-start justify-content-between">
|
||||
<div class="flex align-items-start">
|
||||
<div class="flex align-items-center justify-content-center border-round-lg mr-3 #{demande.typeColorClass}"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi #{demande.typeIcon} text-white"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<h6 class="text-900 font-medium m-0">#{demande.objet}</h6>
|
||||
<small class="text-500 text-xs">#{demande.dateDepotRelative}</small>
|
||||
</div>
|
||||
<div class="text-600 mb-2 text-sm">
|
||||
<i class="pi pi-user mr-2"></i>
|
||||
<span class="font-medium">#{demande.demandeur}</span> • #{demande.numeroMembre}
|
||||
</div>
|
||||
<p:tag value="#{demande.statut}"
|
||||
severity="#{demande.statutSeverity}"
|
||||
icon="pi #{demande.statutIcon}"
|
||||
styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
<h:form>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="title" value="Voir détails" />
|
||||
<ui:param name="action" value="#{demandeBean.voirDemande(demande)}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section Filtres avec composant réutilisable -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres et Recherche" />
|
||||
<ui:define name="filters">
|
||||
<h:form id="formFiltres">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-search-text.xhtml">
|
||||
<ui:param name="id" value="searchFilter" />
|
||||
<ui:param name="label" value="Rechercher" />
|
||||
<ui:param name="value" value="#{demandeBean.searchFilter}" />
|
||||
<ui:param name="placeholder" value="Rechercher..." />
|
||||
<ui:param name="update" value=":formDemandes:dtDemandes" />
|
||||
<ui:param name="event" value="keyup" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<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="#{demandeBean.statutFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
|
||||
<f:selectItem itemLabel="Approuvée" itemValue="APPROUVEE" />
|
||||
<f:selectItem itemLabel="Rejetée" itemValue="REJETEE" />
|
||||
<f:selectItem itemLabel="Annulée" itemValue="ANNULEE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax update=":formDemandes:dtDemandes" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<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="#{demandeBean.typeFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Aide financière" itemValue="AIDE_FINANCIERE" />
|
||||
<f:selectItem itemLabel="Certificat" itemValue="CERTIFICAT" />
|
||||
<f:selectItem itemLabel="Mutation" itemValue="MUTATION" />
|
||||
<f:selectItem itemLabel="Réclamation" itemValue="RECLAMATION" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax update=":formDemandes:dtDemandes" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="prioriteFilter" />
|
||||
<ui:param name="label" value="Priorité" />
|
||||
<ui:param name="value" value="#{demandeBean.prioriteFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Toutes priorités" itemValue="" />
|
||||
<f:selectItem itemLabel="Urgente" itemValue="URGENTE" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Basse" itemValue="BASSE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax update=":formDemandes:dtDemandes" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateFilter" />
|
||||
<ui:param name="label" value="Date" />
|
||||
<ui:param name="value" value="#{demandeBean.dateFilter}" />
|
||||
<ui:param name="update" value=":formDemandes:dtDemandes" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="field col-12 md:col-6 lg:col-8">
|
||||
<h:form id="formActionsFiltres">
|
||||
<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="#{demandeBean.actualiser}" />
|
||||
<ui:param name="update" value=":formFiltres :formDemandes:dtDemandes" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Liste complète des demandes -->
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="p-4">
|
||||
<h:form id="formDemandes">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<h5 class="m-0">
|
||||
<i class="pi pi-list text-primary mr-2"></i>
|
||||
Toutes les Demandes
|
||||
</h5>
|
||||
<div class="flex gap-3 align-items-center">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Assigner en lot" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="onclick" value="PF('dlgAssignationLot').show();" />
|
||||
<ui:param name="disabled" value="#{empty demandeBean.selectedDemandes}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Marquer traitées" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="action" value="#{demandeBean.marquerTraitees}" />
|
||||
<ui:param name="update" value=":formDemandes:dtDemandes" />
|
||||
<ui:param name="disabled" value="#{empty demandeBean.selectedDemandes}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Exporter sélection" />
|
||||
<ui:param name="icon" value="pi pi-file-excel" />
|
||||
<ui:param name="action" value="#{demandeBean.exporterSelection}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="disabled" value="#{empty demandeBean.selectedDemandes}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtDemandes"
|
||||
var="demande"
|
||||
value="#{demandeBean.demandes}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="10,15,25,50"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{demandeBean.selectedDemandes}"
|
||||
rowKey="#{demande.id}"
|
||||
styleClass="p-datatable-sm p-datatable-gridlines p-datatable-striped"
|
||||
emptyMessage="Aucune demande trouvée">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:3rem" exportable="false"/>
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{demande.reference}" style="width:120px">
|
||||
<h:outputText value="#{demande.reference}" styleClass="font-mono font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Demandeur" sortBy="#{demande.nomDemandeur}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-2 flex-shrink-0"
|
||||
style="width: 2.5rem; height: 2.5rem; min-width: 2.5rem;">
|
||||
<span class="text-sm font-semibold">#{demande.initialesDemandeur}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-900">#{demande.nomCompletDemandeur}</div>
|
||||
<small class="text-600">#{demande.numeroMembre} • #{demande.telephoneDemandeur}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{demande.type}" style="width:140px">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-round-lg flex align-items-center justify-content-center mr-2 flex-shrink-0 #{demande.typeColorClass}"
|
||||
style="width: 2.5rem; height: 2.5rem; min-width: 2.5rem;">
|
||||
<i class="pi #{demande.typeIcon} text-white"></i>
|
||||
</div>
|
||||
<span class="text-sm font-medium">#{demande.type}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Objet" sortBy="#{demande.objet}">
|
||||
<h:outputText value="#{demande.objet}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Priorité" sortBy="#{demande.priorite}" style="width:100px">
|
||||
<p:tag value="#{demande.priorite}"
|
||||
severity="#{demande.prioriteSeverity}"
|
||||
icon="pi #{demande.prioriteIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{demande.statut}" style="width:120px">
|
||||
<p:tag value="#{demande.statut}"
|
||||
severity="#{demande.statutSeverity}"
|
||||
icon="pi #{demande.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date dépôt" sortBy="#{demande.dateDepot}" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-medium text-900 text-sm">
|
||||
<h:outputText value="#{demande.dateDepot}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</div>
|
||||
<small class="text-600">#{demande.heureDepot}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Échéance" sortBy="#{demande.dateEcheance}" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-medium text-sm #{demande.echeanceClass}">
|
||||
<h:outputText value="#{demande.dateEcheance}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</div>
|
||||
<small class="text-500 text-xs">#{demande.dateDepotRelative}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Assignée à" sortBy="#{demande.assigneA}" style="width:120px">
|
||||
<h:outputText value="#{demande.assigneA}" rendered="#{demande.assigneA != null}" />
|
||||
<span class="text-400" rendered="#{demande.assigneA == null}">Non assignée</span>
|
||||
</p:column>
|
||||
|
||||
<!-- Colonne Actions -->
|
||||
<p:column headerText="Actions" style="width:200px" exportable="false">
|
||||
<div class="flex gap-1 justify-content-center">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="title" value="Voir détails" />
|
||||
<ui:param name="action" value="#{demandeBean.voirDemande(demande)}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-user" />
|
||||
<ui:param name="title" value="Assigner" />
|
||||
<ui:param name="action" value="#{demandeBean.assignerDemande(demande)}" />
|
||||
<ui:param name="update" value=":formDemandes:dtDemandes" />
|
||||
<ui:param name="rendered" value="#{demande.assigneA == null}" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-cog" />
|
||||
<ui:param name="title" value="Traiter" />
|
||||
<ui:param name="action" value="#{demandeBean.traiterDemande(demande)}" />
|
||||
<ui:param name="update" value=":formDemandes:dtDemandes" />
|
||||
<ui:param name="rendered" value="#{demande.statut == 'EN_ATTENTE' or demande.statut == 'EN_COURS'}" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="title" value="Approuver" />
|
||||
<ui:param name="action" value="#{demandeBean.approuverDemande(demande)}" />
|
||||
<ui:param name="update" value=":formDemandes:dtDemandes" />
|
||||
<ui:param name="rendered" value="#{demande.statut == 'EN_COURS'}" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="title" value="Rejeter" />
|
||||
<ui:param name="action" value="#{demandeBean.rejeterDemande(demande)}" />
|
||||
<ui:param name="onclick" value="return confirm('Êtes-vous sûr de vouloir rejeter cette demande ?');" />
|
||||
<ui:param name="update" value=":formDemandes:dtDemandes" />
|
||||
<ui:param name="rendered" value="#{demande.statut == 'EN_COURS'}" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-danger ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-file" />
|
||||
<ui:param name="title" value="Pièces jointes" />
|
||||
<ui:param name="action" value="#{demandeBean.voirPiecesJointes(demande)}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="rendered" value="#{demande.hasPiecesJointes}" />
|
||||
<ui:param name="styleClass" value="ui-button-rounded ui-button-text ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Demande avec composant réutilisable -->
|
||||
<ui:decorate template="/templates/components/dialogs/form-dialog.xhtml">
|
||||
<ui:param name="dialogId" value="dlgNouvelleDemande" />
|
||||
<ui:param name="header" value="Nouvelle Demande" />
|
||||
<ui:param name="widgetVar" value="dlgNouvelleDemande" />
|
||||
<ui:param name="formId" value="formNouvelleDemande" />
|
||||
<ui:param name="width" value="800" />
|
||||
<ui:define name="content">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="demandeurSelect" class="block text-900 font-medium mb-2">Demandeur *</label>
|
||||
<p:autoComplete id="demandeurSelect"
|
||||
value="#{demandeBean.membreDemandeur}"
|
||||
completeMethod="#{demandeBean.rechercherMembres}"
|
||||
var="membre" itemLabel="#{membre.nomComplet}" itemValue="#{membre}"
|
||||
converter="membreConverter"
|
||||
placeholder="Rechercher un membre..."
|
||||
styleClass="w-full">
|
||||
<p:column>
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-2"
|
||||
style="width: 30px; height: 30px;">
|
||||
<span style="font-size: 0.8rem;">#{membre.initiales}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium">#{membre.nomComplet}</div>
|
||||
<small class="text-600">#{membre.numeroMembre}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:autoComplete>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="typeDemande" />
|
||||
<ui:param name="label" value="Type de demande *" />
|
||||
<ui:param name="value" value="#{demandeBean.nouvelleDemande.type}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="Adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Aide financière" itemValue="AIDE_FINANCIERE" />
|
||||
<f:selectItem itemLabel="Certificat" itemValue="CERTIFICAT" />
|
||||
<f:selectItem itemLabel="Mutation" itemValue="MUTATION" />
|
||||
<f:selectItem itemLabel="Réclamation" itemValue="RECLAMATION" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="objetDemande" />
|
||||
<ui:param name="label" value="Objet *" />
|
||||
<ui:param name="value" value="#{demandeBean.nouvelleDemande.objet}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="placeholder" value="Résumé de la demande" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="prioriteDemande" />
|
||||
<ui:param name="label" value="Priorité" />
|
||||
<ui:param name="value" value="#{demandeBean.nouvelleDemande.priorite}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Urgente" itemValue="URGENTE" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Basse" itemValue="BASSE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateEcheanceDemande" />
|
||||
<ui:param name="label" value="Date d'échéance" />
|
||||
<ui:param name="value" value="#{demandeBean.nouvelleDemande.dateEcheance}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="assignerA" />
|
||||
<ui:param name="label" value="Assigner à" />
|
||||
<ui:param name="value" value="#{demandeBean.nouvelleDemande.assigneA}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Non assigné" itemValue="" />
|
||||
<f:selectItems value="#{demandeBean.gestionnairesDisponibles}"
|
||||
var="gestionnaire"
|
||||
itemLabel="#{gestionnaire.nom}"
|
||||
itemValue="#{gestionnaire.id}" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="descriptionDemande" />
|
||||
<ui:param name="label" value="Description détaillée" />
|
||||
<ui:param name="value" value="#{demandeBean.nouvelleDemande.description}" />
|
||||
<ui:param name="rows" value="4" />
|
||||
<ui:param name="placeholder" value="Décrivez la demande en détail..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<label for="piecesJointes" class="block text-900 font-medium mb-2">Pièces jointes</label>
|
||||
<p:fileUpload id="piecesJointes" mode="advanced"
|
||||
multiple="true" dragDropSupport="true"
|
||||
uploadLabel="Télécharger" cancelLabel="Annuler" chooseLabel="Sélectionner"
|
||||
sizeLimit="5000000" fileLimit="5" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="footer">
|
||||
<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('dlgNouvelleDemande').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Créer la demande" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{demandeBean.creerDemande}" />
|
||||
<ui:param name="update" value=":formNouvelleDemande :formDemandes" />
|
||||
<ui:param name="oncomplete" value="if(!args.validationFailed) PF('dlgNouvelleDemande').hide();" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Dialog Assignation en Lot avec composant réutilisable -->
|
||||
<ui:decorate template="/templates/components/dialogs/form-dialog.xhtml">
|
||||
<ui:param name="dialogId" value="dlgAssignationLot" />
|
||||
<ui:param name="header" value="Assignation en Lot" />
|
||||
<ui:param name="widgetVar" value="dlgAssignationLot" />
|
||||
<ui:param name="formId" value="formAssignationLot" />
|
||||
<ui:param name="width" value="500" />
|
||||
<ui:define name="content">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="gestionnaireAssignation" />
|
||||
<ui:param name="label" value="Assigner à *" />
|
||||
<ui:param name="value" value="#{demandeBean.gestionnaireAssignation}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItems value="#{demandeBean.gestionnairesDisponibles}"
|
||||
var="gestionnaire"
|
||||
itemLabel="#{gestionnaire.nom}"
|
||||
itemValue="#{gestionnaire.id}" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="commentaireAssignation" />
|
||||
<ui:param name="label" value="Commentaire" />
|
||||
<ui:param name="value" value="#{demandeBean.commentaireAssignation}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
<ui:param name="placeholder" value="Commentaire optionnel..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<div class="surface-50 border-round-lg p-3">
|
||||
<div class="font-medium mb-2">Demandes sélectionnées :</div>
|
||||
<div class="text-600">#{demandeBean.selectedDemandes.size()} demande(s) seront assignées</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="footer">
|
||||
<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('dlgAssignationLot').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Assigner" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{demandeBean.effectuerAssignationLot}" />
|
||||
<ui:param name="update" value=":formAssignationLot :formDemandes" />
|
||||
<ui:param name="oncomplete" value="if(!args.validationFailed) PF('dlgAssignationLot').hide();" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,613 @@
|
||||
<!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 Documents - 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-folder text-blue-500 mr-2"></i>
|
||||
Gestion des Documents
|
||||
</h2>
|
||||
<p class="text-600 mt-0">Centralisation et organisation documentaire</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="Télécharger"
|
||||
icon="pi pi-upload"
|
||||
styleClass="ui-button-success ui-button-sm w-full"
|
||||
onclick="PF('dlgTelechargerDocument').show();" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:commandButton value="Dossier"
|
||||
icon="pi pi-folder-plus"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm w-full"
|
||||
onclick="PF('dlgCreerDossier').show();" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:commandButton value="Modèle"
|
||||
icon="pi pi-file-plus"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm w-full"
|
||||
onclick="PF('dlgGenererModele').show();" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques stockage 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 Documents</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-file text-blue-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{documentsBean.statistiques.totalDocuments}</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">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">Dossiers</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-folder text-green-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{documentsBean.statistiques.totalDossiers}</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">Organisé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">Espace Utilisé</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-database text-orange-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{documentsBean.statistiques.espaceUtilise}</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">Stockage</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">Partages</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-share-alt text-purple-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{documentsBean.statistiques.partagesMois}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<div class="bg-purple-500 border-circle mr-2" style="width: 8px; height: 8px;"></div>
|
||||
<span class="text-500 text-xs">ce mois</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation des dossiers 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-folder-open text-blue-500 mr-2"></i>
|
||||
Navigation
|
||||
</h5>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<p:breadCrumb value="#{documentsBean.cheminNavigation}" var="niveau">
|
||||
<p:menuitem value="#{niveau.nom}" />
|
||||
</p:breadCrumb>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Vue dossiers -->
|
||||
<div class="formgrid grid">
|
||||
<ui:repeat value="#{documentsBean.dossiersAffichage}" var="dossier" varStatus="status">
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-3 hover:surface-200 transition-colors transition-duration-150 cursor-pointer"
|
||||
onclick="#{documentsBean.naviguerVersDossier(dossier)}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="surface-200 border-round-lg flex align-items-center justify-content-center mr-3"
|
||||
style="width: 3rem; height: 3rem;">
|
||||
<i class="pi pi-folder text-#{dossier.couleur} text-xl"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 m-0 mb-1">#{dossier.nom}</h6>
|
||||
<div class="text-600 text-sm mb-1">#{dossier.nombreDocuments} documents</div>
|
||||
<div class="text-500 text-xs">Modifié #{dossier.derniereModificationRelative}</div>
|
||||
</div>
|
||||
<h:form>
|
||||
<p:commandButton icon="pi pi-ellipsis-v"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary ui-button-sm"
|
||||
onclick="PF('dlgActionsDossier').show();"
|
||||
title="Actions">
|
||||
<f:setPropertyActionListener target="#{documentsBean.dossierSelectionne}" value="#{dossier}" />
|
||||
</p:commandButton>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</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>
|
||||
Filtres et Recherche
|
||||
</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 du document" />
|
||||
<p:inputText id="searchNom" value="#{documentsBean.filtres.nom}"
|
||||
placeholder="Rechercher par nom...">
|
||||
<p:ajax event="keyup" update="dtDocuments @(.stats-summary)" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="filterType" value="Type" />
|
||||
<p:selectOneMenu id="filterType" value="#{documentsBean.filtres.type}">
|
||||
<f:selectItem itemLabel="Tous types" itemValue="" />
|
||||
<f:selectItem itemLabel="PDF" itemValue="PDF" />
|
||||
<f:selectItem itemLabel="Word" itemValue="WORD" />
|
||||
<f:selectItem itemLabel="Excel" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="Image" itemValue="IMAGE" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
<p:ajax update="dtDocuments @(.stats-summary)" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="filterCategorie" value="Catégorie" />
|
||||
<p:selectOneMenu id="filterCategorie" value="#{documentsBean.filtres.categorie}">
|
||||
<f:selectItem itemLabel="Toutes" itemValue="" />
|
||||
<f:selectItem itemLabel="Administratif" itemValue="ADMINISTRATIF" />
|
||||
<f:selectItem itemLabel="Financier" itemValue="FINANCIER" />
|
||||
<f:selectItem itemLabel="Juridique" itemValue="JURIDIQUE" />
|
||||
<f:selectItem itemLabel="Communication" itemValue="COMMUNICATION" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<p:ajax update="dtDocuments @(.stats-summary)" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="filterStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filterStatut" value="#{documentsBean.filtres.statut}">
|
||||
<f:selectItem itemLabel="Tous statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Brouillon" itemValue="BROUILLON" />
|
||||
<f:selectItem itemLabel="Validé" itemValue="VALIDE" />
|
||||
<f:selectItem itemLabel="Archivé" itemValue="ARCHIVE" />
|
||||
<f:selectItem itemLabel="Expiré" itemValue="EXPIRE" />
|
||||
<p:ajax update="dtDocuments @(.stats-summary)" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-2">
|
||||
<p:outputLabel for="filterAuteur" value="Auteur" />
|
||||
<p:inputText id="filterAuteur" value="#{documentsBean.filtres.auteur}"
|
||||
placeholder="Filtrer par auteur...">
|
||||
<p:ajax event="keyup" update="dtDocuments @(.stats-summary)" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="filterDateDebut" value="Date début" />
|
||||
<p:datePicker id="filterDateDebut" value="#{documentsBean.filtres.dateDebut}"
|
||||
placeholder="Date de début">
|
||||
<p:ajax update="dtDocuments @(.stats-summary)" />
|
||||
</p:datePicker>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="filterDateFin" value="Date fin" />
|
||||
<p:datePicker id="filterDateFin" value="#{documentsBean.filtres.dateFin}"
|
||||
placeholder="Date de fin">
|
||||
<p:ajax update="dtDocuments @(.stats-summary)" />
|
||||
</p:datePicker>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="filterTaille" value="Taille max (MB)" />
|
||||
<p:inputNumber id="filterTaille" value="#{documentsBean.filtres.tailleMax}"
|
||||
placeholder="Taille maximum">
|
||||
<p:ajax update="dtDocuments @(.stats-summary)" />
|
||||
</p:inputNumber>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="filterMots" value="Mots-clés" />
|
||||
<p:inputText id="filterMots" value="#{documentsBean.filtres.motsCles}"
|
||||
placeholder="Tags, mots-clés...">
|
||||
<p:ajax event="keyup" update="dtDocuments @(.stats-summary)" />
|
||||
</p:inputText>
|
||||
</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="#{documentsBean.rechercher}"
|
||||
update="dtDocuments @(.stats-summary)" />
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm"
|
||||
action="#{documentsBean.reinitialiserFiltres}"
|
||||
update="@form dtDocuments @(.stats-summary)" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des documents 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-file-o text-blue-500 mr-2"></i>
|
||||
Documents (#{documentsBean.documentsFiltres.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 documentsBean.documentsSelectionnes}" />
|
||||
</h:form>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<h:form>
|
||||
<p:commandButton icon="pi pi-th-large"
|
||||
styleClass="ui-button-rounded ui-button-outlined #{documentsBean.modeAffichage == 'GRID' ? 'ui-button-primary' : 'ui-button-secondary'}"
|
||||
action="#{documentsBean.changerModeAffichage('GRID')}"
|
||||
update="@form"
|
||||
title="Vue grille" />
|
||||
<p:commandButton icon="pi pi-list"
|
||||
styleClass="ui-button-rounded ui-button-outlined #{documentsBean.modeAffichage == 'LIST' ? 'ui-button-primary' : 'ui-button-secondary'}"
|
||||
action="#{documentsBean.changerModeAffichage('LIST')}"
|
||||
update="@form"
|
||||
title="Vue liste" />
|
||||
</h:form>
|
||||
</div>
|
||||
<span class="text-600 text-sm stats-summary">
|
||||
#{documentsBean.documentsFiltres.size()} sur #{documentsBean.tousLesDocuments.size()} documents
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Vue grille -->
|
||||
<div class="formgrid grid" rendered="#{documentsBean.modeAffichage == 'GRID'}">
|
||||
<ui:repeat value="#{documentsBean.documentsFiltres}" var="document" varStatus="status">
|
||||
<div class="field col-12 md:col-6 lg:col-4 xl:col-3">
|
||||
<div class="surface-100 border-round-lg p-3 hover:surface-200 transition-colors transition-duration-150">
|
||||
<div class="flex align-items-start justify-content-between mb-3">
|
||||
<div class="surface-200 border-round-lg flex align-items-center justify-content-center"
|
||||
style="width: 3rem; height: 3rem;">
|
||||
<i class="pi #{document.typeIcon} text-#{document.typeCouleur} text-lg"></i>
|
||||
</div>
|
||||
<h:form>
|
||||
<p:selectBooleanCheckbox value="#{documentsBean.estSelectionne(document)}"
|
||||
onchange="#{documentsBean.toggleSelection(document)}" />
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<h6 class="text-900 mb-2 line-height-3">#{document.nom}</h6>
|
||||
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<p:tag value="#{document.categorieLibelle}" severity="#{document.categorieSeverity}" />
|
||||
<span class="text-600 text-sm">#{document.taille}</span>
|
||||
</div>
|
||||
|
||||
<div class="text-600 text-sm mb-3">
|
||||
<div class="flex align-items-center mb-1">
|
||||
<i class="pi pi-user mr-2"></i>
|
||||
<span>#{document.auteur}</span>
|
||||
</div>
|
||||
<div class="flex align-items-center mb-1">
|
||||
<i class="pi pi-calendar mr-2"></i>
|
||||
<span>#{document.dateCreationFormatee}</span>
|
||||
</div>
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-eye mr-2"></i>
|
||||
<span>#{document.nombreVues} vues</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-between align-items-center">
|
||||
<p:tag value="#{document.statutLibelle}" severity="#{document.statutSeverity}" />
|
||||
<h:form>
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info ui-button-sm"
|
||||
title="Prévisualiser"
|
||||
onclick="PF('dlgPrevisualiser').show();">
|
||||
<f:setPropertyActionListener target="#{documentsBean.documentSelectionne}" value="#{document}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-download"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success ui-button-sm"
|
||||
title="Télécharger"
|
||||
action="#{documentsBean.telechargerDocument(document)}" />
|
||||
<p:commandButton icon="pi pi-ellipsis-v"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary ui-button-sm"
|
||||
title="Actions"
|
||||
onclick="PF('dlgActionsDocument').show();">
|
||||
<f:setPropertyActionListener target="#{documentsBean.documentSelectionne}" value="#{document}" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
|
||||
<!-- Vue liste -->
|
||||
<p:dataTable id="dtDocuments"
|
||||
value="#{documentsBean.documentsFiltres}"
|
||||
var="document"
|
||||
selection="#{documentsBean.documentsSelectionnes}"
|
||||
rowKey="#{document.id}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorPosition="both"
|
||||
sortMode="single"
|
||||
styleClass="p-datatable-sm"
|
||||
emptyMessage="Aucun document trouvé"
|
||||
rendered="#{documentsBean.modeAffichage == 'LIST'}">
|
||||
|
||||
<p:column selectionMode="multiple" width="40" />
|
||||
|
||||
<p:column headerText="Document" sortBy="#{document.nom}" width="300">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-#{document.typeCouleur} text-white border-round flex align-items-center justify-content-center mr-3"
|
||||
style="width: 32px; height: 32px;">
|
||||
<i class="pi #{document.typeIcon}"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{document.nom}</div>
|
||||
<div class="text-600 text-sm">#{document.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{document.type}" width="80">
|
||||
<span class="text-900 font-bold">#{document.type}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Catégorie" sortBy="#{document.categorie}" width="120">
|
||||
<p:tag value="#{document.categorieLibelle}" severity="#{document.categorieSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Taille" sortBy="#{document.tailleBytes}" width="80">
|
||||
<span class="text-900">#{document.taille}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Auteur" sortBy="#{document.auteur}" width="120">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-300 mr-2" style="width: 24px; height: 24px;"></div>
|
||||
<span class="text-900">#{document.auteur}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date création" sortBy="#{document.dateCreation}" width="100">
|
||||
<div class="text-900 text-sm">#{document.dateCreationFormatee}</div>
|
||||
<div class="text-600 text-xs">#{document.dateCreationRelative}</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Vues" sortBy="#{document.nombreVues}" width="60">
|
||||
<div class="text-center">
|
||||
<span class="text-900 font-bold">#{document.nombreVues}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{document.statut}" width="100">
|
||||
<p:tag value="#{document.statutLibelle}" severity="#{document.statutSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" width="150">
|
||||
<h:form id="formActions#{document.id}">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
title="Prévisualiser"
|
||||
onclick="PF('dlgPrevisualiser').show();">
|
||||
<f:setPropertyActionListener target="#{documentsBean.documentSelectionne}" value="#{document}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-download"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
title="Télécharger"
|
||||
action="#{documentsBean.telechargerDocument(document)}" />
|
||||
<p:commandButton icon="pi pi-share-alt"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-primary"
|
||||
title="Partager"
|
||||
onclick="PF('dlgPartagerDocument').show();">
|
||||
<f:setPropertyActionListener target="#{documentsBean.documentSelectionne}" value="#{document}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
title="Modifier"
|
||||
onclick="PF('dlgModifierDocument').show();">
|
||||
<f:setPropertyActionListener target="#{documentsBean.documentSelectionne}" value="#{document}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
title="Supprimer"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir supprimer ce document ?');"
|
||||
action="#{documentsBean.supprimerDocument(document)}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Télécharger Document avec Freya stricte -->
|
||||
<p:dialog header="Télécharger un Document" widgetVar="dlgTelechargerDocument" modal="true" width="600">
|
||||
<h:form id="formTelechargerDocument" enctype="multipart/form-data">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="uploadFile" value="Fichier" />
|
||||
<p:fileUpload id="uploadFile"
|
||||
mode="advanced"
|
||||
dragDropSupport="true"
|
||||
multiple="true"
|
||||
uploadLabel="Télécharger"
|
||||
cancelLabel="Annuler"
|
||||
chooseLabel="Sélectionner"
|
||||
sizeLimit="10000000"
|
||||
fileLimit="10"
|
||||
allowTypes="/\.(pdf|doc|docx|xls|xlsx|ppt|pptx|txt|jpg|jpeg|png|gif)$/" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newCategorie" value="Catégorie" />
|
||||
<p:selectOneMenu id="newCategorie" value="#{documentsBean.nouveauDocument.categorie}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="Administratif" itemValue="ADMINISTRATIF" />
|
||||
<f:selectItem itemLabel="Financier" itemValue="FINANCIER" />
|
||||
<f:selectItem itemLabel="Juridique" itemValue="JURIDIQUE" />
|
||||
<f:selectItem itemLabel="Communication" itemValue="COMMUNICATION" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newDossier" value="Dossier de destination" />
|
||||
<p:selectOneMenu id="newDossier" value="#{documentsBean.nouveauDocument.dossierId}">
|
||||
<f:selectItem itemLabel="Racine" itemValue="" />
|
||||
<f:selectItems value="#{documentsBean.dossiersDisponibles}"
|
||||
var="dossier"
|
||||
itemLabel="#{dossier.cheminComplet}"
|
||||
itemValue="#{dossier.id}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="newDescription" value="Description" />
|
||||
<p:inputTextarea id="newDescription" value="#{documentsBean.nouveauDocument.description}"
|
||||
rows="3" placeholder="Description du document..." />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newMotsCles" value="Mots-clés" />
|
||||
<p:inputText id="newMotsCles" value="#{documentsBean.nouveauDocument.motsCles}"
|
||||
placeholder="Séparer par des virgules..." />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="newAccesRestreint" value="Accès restreint" />
|
||||
<p:selectBooleanCheckbox id="newAccesRestreint" value="#{documentsBean.nouveauDocument.accesRestreint}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Télécharger" icon="pi pi-upload"
|
||||
styleClass="ui-button-success ui-button-sm"
|
||||
action="#{documentsBean.telechargerNouveauDocument}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgTelechargerDocument').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary ui-button-sm"
|
||||
onclick="PF('dlgTelechargerDocument').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Actions Document avec Freya stricte -->
|
||||
<p:dialog header="Actions sur le Document" widgetVar="dlgActionsDocument" modal="true" width="400">
|
||||
<h:form id="formActionsDocument">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12">
|
||||
<p:commandButton value="Créer une copie"
|
||||
icon="pi pi-copy"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm w-full mb-2"
|
||||
action="#{documentsBean.dupliquerDocument}" />
|
||||
|
||||
<p:commandButton value="Déplacer vers..."
|
||||
icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-warning ui-button-outlined ui-button-sm w-full mb-2"
|
||||
onclick="PF('dlgDeplacerDocument').show();" />
|
||||
|
||||
<p:commandButton value="Gérer les permissions"
|
||||
icon="pi pi-lock"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm w-full mb-2"
|
||||
onclick="PF('dlgPermissionsDocument').show();" />
|
||||
|
||||
<p:commandButton value="Historique des versions"
|
||||
icon="pi pi-history"
|
||||
styleClass="ui-button-primary ui-button-outlined ui-button-sm w-full mb-2"
|
||||
action="#{documentsBean.voirHistoriqueVersions}" />
|
||||
|
||||
<p:commandButton value="Archiver le document"
|
||||
icon="pi pi-archive"
|
||||
styleClass="ui-button-help ui-button-outlined ui-button-sm w-full mb-2"
|
||||
action="#{documentsBean.archiverDocument}"
|
||||
rendered="#{documentsBean.documentSelectionne.statut != 'ARCHIVE'}" />
|
||||
|
||||
<p:commandButton value="Supprimer définitivement"
|
||||
icon="pi pi-trash"
|
||||
styleClass="ui-button-danger ui-button-outlined ui-button-sm w-full"
|
||||
onclick="return confirm('ATTENTION: Cette action est irréversible. Confirmer la suppression ?');"
|
||||
action="#{documentsBean.supprimerDefinitivement}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end mt-3">
|
||||
<p:commandButton value="Fermer" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary ui-button-sm"
|
||||
onclick="PF('dlgActionsDocument').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,541 @@
|
||||
<!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">Créer un Événement - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<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="pi pi-calendar-plus text-green-500 mr-2"></i>
|
||||
Créer un Nouvel Événement
|
||||
</h3>
|
||||
<p class="text-600 m-0">Planifiez et organisez vos événements avec tous les détails nécessaires</p>
|
||||
</div>
|
||||
<div>
|
||||
<p:commandButton value="Retour à la liste"
|
||||
icon="pi pi-arrow-left"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="/pages/admin/evenements/liste?faces-redirect=true" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Progression -->
|
||||
<div class="card">
|
||||
<h5>Progression de création</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="text-center p-3">
|
||||
<i class="pi pi-info-circle text-2xl text-primary mb-2"></i>
|
||||
<div class="text-sm font-medium">Informations de base</div>
|
||||
<i class="pi pi-check-circle text-green-500 mt-1" style="display: #{creationEvenementBean.etapeInformationsComplete ? 'inline' : 'none'};"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="text-center p-3">
|
||||
<i class="pi pi-calendar text-2xl text-primary mb-2"></i>
|
||||
<div class="text-sm font-medium">Date et lieu</div>
|
||||
<i class="pi pi-check-circle text-green-500 mt-1" style="display: #{creationEvenementBean.etapeDateLieuComplete ? 'inline' : 'none'};"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="text-center p-3">
|
||||
<i class="pi pi-users text-2xl text-primary mb-2"></i>
|
||||
<div class="text-sm font-medium">Participants</div>
|
||||
<i class="pi pi-check-circle text-green-500 mt-1" style="display: #{creationEvenementBean.etapeParticipantsComplete ? 'inline' : 'none'};"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="text-center p-3">
|
||||
<i class="pi pi-dollar text-2xl text-primary mb-2"></i>
|
||||
<div class="text-sm font-medium">Tarification</div>
|
||||
<i class="pi pi-check-circle text-green-500 mt-1" style="display: #{creationEvenementBean.etapeTarificationComplete ? 'inline' : 'none'};"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="text-center p-3">
|
||||
<i class="pi pi-bell text-2xl text-primary mb-2"></i>
|
||||
<div class="text-sm font-medium">Notifications</div>
|
||||
<i class="pi pi-check-circle text-green-500 mt-1" style="display: #{creationEvenementBean.etapeNotificationsComplete ? 'inline' : 'none'};"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="text-center p-3">
|
||||
<i class="pi pi-check text-2xl text-primary mb-2"></i>
|
||||
<div class="text-sm font-medium">Validation</div>
|
||||
<i class="pi pi-check-circle text-green-500 mt-1" style="display: #{creationEvenementBean.etapeValidationComplete ? 'inline' : 'none'};"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p:progressBar value="#{creationEvenementBean.progressionPourcentage}"
|
||||
labelTemplate="{value}% complété"
|
||||
styleClass="mb-3" />
|
||||
</div>
|
||||
|
||||
<h:form id="formCreation" styleClass="ui-fluid">
|
||||
<p:messages id="messages" showDetail="true" closable="true" />
|
||||
|
||||
<div class="grid">
|
||||
<!-- Informations de base -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-info-circle mr-2"></i>
|
||||
Informations de Base
|
||||
</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="titre" value="Titre de l'événement" />
|
||||
<p:inputText id="titre" value="#{creationEvenementBean.evenement.titre}"
|
||||
required="true" placeholder="Ex: Assemblée Générale 2024" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="type" value="Type d'événement" />
|
||||
<p:selectOneMenu id="type" value="#{creationEvenementBean.evenement.typeEvenement}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="🏛️ Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
|
||||
<f:selectItem itemLabel="📋 Réunion" itemValue="REUNION" />
|
||||
<f:selectItem itemLabel="🎓 Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="🎉 Événement social" itemValue="SOCIAL" />
|
||||
<f:selectItem itemLabel="🏆 Cérémonie" itemValue="CEREMONIE" />
|
||||
<f:selectItem itemLabel="🚌 Sortie/Voyage" itemValue="SORTIE" />
|
||||
<f:selectItem itemLabel="🍽️ Repas" itemValue="REPAS" />
|
||||
<f:selectItem itemLabel="🔧 Autre" itemValue="AUTRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="description" value="Description" />
|
||||
<p:inputTextarea id="description" value="#{creationEvenementBean.evenement.description}"
|
||||
rows="4" placeholder="Décrivez l'événement, son objectif et son déroulement..." />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="organisateur" value="Organisateur" />
|
||||
<p:inputText id="organisateur" value="#{creationEvenementBean.evenement.organisateur}"
|
||||
placeholder="Nom de l'organisateur principal" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="priorite" value="Priorité" />
|
||||
<p:selectOneMenu id="priorite" value="#{creationEvenementBean.evenement.priorite}">
|
||||
<f:selectItem itemLabel="🔴 Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="🟡 Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="🟢 Basse" itemValue="BASSE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Date, heure et lieu -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-calendar mr-2"></i>
|
||||
Date, Heure et Lieu
|
||||
</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="dateDebut" value="Date de début" />
|
||||
<p:calendar id="dateDebut" value="#{creationEvenementBean.evenement.dateDebut}"
|
||||
pattern="dd/MM/yyyy" showIcon="true" required="true"
|
||||
locale="fr" />
|
||||
</div>
|
||||
|
||||
<div class="formgrid grid">
|
||||
<div class="field col">
|
||||
<p:outputLabel for="heureDebut" value="Heure début" />
|
||||
<p:calendar id="heureDebut" value="#{creationEvenementBean.evenement.heureDebut}"
|
||||
pattern="HH:mm" timeOnly="true" showIcon="true" />
|
||||
</div>
|
||||
<div class="field col">
|
||||
<p:outputLabel for="heureFin" value="Heure fin" />
|
||||
<p:calendar id="heureFin" value="#{creationEvenementBean.evenement.heureFin}"
|
||||
pattern="HH:mm" timeOnly="true" showIcon="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="evenementRecurrent" value="#{creationEvenementBean.evenement.recurrent}" />
|
||||
<p:outputLabel for="evenementRecurrent" value=" Événement récurrent" />
|
||||
</div>
|
||||
|
||||
<div class="field" style="display: #{creationEvenementBean.evenement.recurrent ? 'block' : 'none'};">
|
||||
<p:outputLabel for="frequenceRecurrence" value="Fréquence" />
|
||||
<p:selectOneMenu id="frequenceRecurrence" value="#{creationEvenementBean.evenement.frequenceRecurrence}">
|
||||
<f:selectItem itemLabel="Hebdomadaire" itemValue="HEBDOMADAIRE" />
|
||||
<f:selectItem itemLabel="Mensuel" itemValue="MENSUEL" />
|
||||
<f:selectItem itemLabel="Trimestriel" itemValue="TRIMESTRIEL" />
|
||||
<f:selectItem itemLabel="Annuel" itemValue="ANNUEL" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="lieu" value="Lieu" />
|
||||
<p:inputText id="lieu" value="#{creationEvenementBean.evenement.lieu}"
|
||||
required="true" placeholder="Ex: Salle de réunion, Hôtel..." />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="adresse" value="Adresse complète" />
|
||||
<p:inputTextarea id="adresse" value="#{creationEvenementBean.evenement.adresse}"
|
||||
rows="3" placeholder="Adresse précise avec ville et points de repère" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration des participants -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-users mr-2"></i>
|
||||
Participants et Inscription
|
||||
</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="placesMax" value="Nombre maximum de places" />
|
||||
<p:inputNumber id="placesMax" value="#{creationEvenementBean.evenement.placesMax}"
|
||||
symbol="" min="1" max="10000" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="inscriptionRequise" value="#{creationEvenementBean.evenement.inscriptionRequise}" />
|
||||
<p:outputLabel for="inscriptionRequise" value=" Inscription obligatoire" />
|
||||
</div>
|
||||
|
||||
<div class="field" style="display: #{creationEvenementBean.evenement.inscriptionRequise ? 'block' : 'none'};">
|
||||
<p:outputLabel for="dateLimiteInscription" value="Date limite d'inscription" />
|
||||
<p:calendar id="dateLimiteInscription" value="#{creationEvenementBean.evenement.dateLimiteInscription}"
|
||||
pattern="dd/MM/yyyy HH:mm" showIcon="true" locale="fr" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="publicCible" value="Public cible" />
|
||||
<p:selectCheckboxMenu id="publicCible" value="#{creationEvenementBean.evenement.publicCible}"
|
||||
multiple="true" filter="true" filterMatchMode="contains">
|
||||
<f:selectItem itemLabel="Tous les membres" itemValue="TOUS" />
|
||||
<f:selectItem itemLabel="Membres actifs" itemValue="ACTIFS" />
|
||||
<f:selectItem itemLabel="Membres bienfaiteurs" itemValue="BIENFAITEURS" />
|
||||
<f:selectItem itemLabel="Membres honoraires" itemValue="HONORAIRES" />
|
||||
<f:selectItem itemLabel="Bureau exécutif" itemValue="BUREAU" />
|
||||
<f:selectItem itemLabel="Invités externes" itemValue="INVITES" />
|
||||
</p:selectCheckboxMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="listeAttente" value="#{creationEvenementBean.evenement.listeAttente}" />
|
||||
<p:outputLabel for="listeAttente" value=" Activer liste d'attente si complet" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="accompagnateurs" value="Nombre d'accompagnateurs autorisés" />
|
||||
<p:inputNumber id="accompagnateurs" value="#{creationEvenementBean.evenement.accompagnateursMax}"
|
||||
symbol="" min="0" max="10" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tarification -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-dollar mr-2"></i>
|
||||
Tarification et Paiement
|
||||
</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="evenementPayant" value="#{creationEvenementBean.evenement.payant}" />
|
||||
<p:outputLabel for="evenementPayant" value=" Événement payant" />
|
||||
</div>
|
||||
|
||||
<div class="field" style="display: #{creationEvenementBean.evenement.payant ? 'block' : 'none'};">
|
||||
<p:outputLabel for="prix" value="Prix par personne" />
|
||||
<p:inputNumber id="prix" value="#{creationEvenementBean.evenement.prix}"
|
||||
symbol=" FCFA" symbolPosition="s" min="0" />
|
||||
</div>
|
||||
|
||||
<div class="field" style="display: #{creationEvenementBean.evenement.payant ? 'block' : 'none'};">
|
||||
<p:outputLabel for="tarificationDifferenciee" value="Tarification différenciée" />
|
||||
<p:selectBooleanCheckbox id="tarificationDifferenciee" value="#{creationEvenementBean.evenement.tarificationDifferenciee}" />
|
||||
<p:outputLabel for="tarificationDifferenciee" value=" Activer tarifs différents selon le type de membre" />
|
||||
</div>
|
||||
|
||||
<div class="field" style="display: #{creationEvenementBean.evenement.tarificationDifferenciee ? 'block' : 'none'};">
|
||||
<h6>Tarifs par catégorie</h6>
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-6">
|
||||
<p:outputLabel value="Membres actifs" />
|
||||
<p:inputNumber value="#{creationEvenementBean.evenement.prixMembresActifs}"
|
||||
symbol=" FCFA" symbolPosition="s" />
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<p:outputLabel value="Membres associés" />
|
||||
<p:inputNumber value="#{creationEvenementBean.evenement.prixMembresAssocies}"
|
||||
symbol=" FCFA" symbolPosition="s" />
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<p:outputLabel value="Invités externes" />
|
||||
<p:inputNumber value="#{creationEvenementBean.evenement.prixInvites}"
|
||||
symbol=" FCFA" symbolPosition="s" />
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<p:outputLabel value="Accompagnateurs" />
|
||||
<p:inputNumber value="#{creationEvenementBean.evenement.prixAccompagnateurs}"
|
||||
symbol=" FCFA" symbolPosition="s" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" style="display: #{creationEvenementBean.evenement.payant ? 'block' : 'none'};">
|
||||
<p:outputLabel for="modesPaiement" value="Modes de paiement acceptés" />
|
||||
<p:selectCheckboxMenu id="modesPaiement" value="#{creationEvenementBean.evenement.modesPaiement}"
|
||||
multiple="true">
|
||||
<f:selectItem itemLabel="💰 Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="📱 Wave Money" itemValue="WAVE" />
|
||||
<f:selectItem itemLabel="🏦 Virement bancaire" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="💳 Chèque" itemValue="CHEQUE" />
|
||||
<f:selectItem itemLabel="💸 Prélèvement automatique" itemValue="PRELEVEMENT" />
|
||||
</p:selectCheckboxMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notifications et communication -->
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-bell mr-2"></i>
|
||||
Notifications et Communication
|
||||
</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="notifierCreation" value="#{creationEvenementBean.evenement.notifierCreation}" />
|
||||
<p:outputLabel for="notifierCreation" value=" Notifier immédiatement la création" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="canauxNotification" value="Canaux de notification" />
|
||||
<p:selectCheckboxMenu id="canauxNotification" value="#{creationEvenementBean.evenement.canauxNotification}"
|
||||
multiple="true">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="messagePersonnalise" value="Message personnalisé" />
|
||||
<p:inputTextarea id="messagePersonnalise" value="#{creationEvenementBean.evenement.messagePersonnalise}"
|
||||
rows="4" placeholder="Message d'invitation personnalisé..." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h6>Rappels automatiques</h6>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="rappelJ7" value="#{creationEvenementBean.evenement.rappelJ7}" />
|
||||
<p:outputLabel for="rappelJ7" value=" Rappel 7 jours avant" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="rappelJ3" value="#{creationEvenementBean.evenement.rappelJ3}" />
|
||||
<p:outputLabel for="rappelJ3" value=" Rappel 3 jours avant" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="rappelJ1" value="#{creationEvenementBean.evenement.rappelJ1}" />
|
||||
<p:outputLabel for="rappelJ1" value=" Rappel 1 jour avant" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="rappelH2" value="#{creationEvenementBean.evenement.rappelH2}" />
|
||||
<p:outputLabel for="rappelH2" value=" Rappel 2 heures avant" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="notificationSuivi" value="#{creationEvenementBean.evenement.notificationSuivi}" />
|
||||
<p:outputLabel for="notificationSuivi" value=" Envoyer bilan après l'événement" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Documents et pièces jointes -->
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-file mr-2"></i>
|
||||
Documents et Pièces Jointes
|
||||
</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="programme" value="Programme détaillé" />
|
||||
<p:fileUpload id="programme" mode="simple" skinSimple="true"
|
||||
accept="application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="invitation" value="Carte d'invitation" />
|
||||
<p:fileUpload id="invitation" mode="simple" skinSimple="true"
|
||||
accept="image/*,application/pdf" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="documentsComplementaires" value="Documents complémentaires" />
|
||||
<p:fileUpload id="documentsComplementaires" mode="advanced"
|
||||
multiple="true" dragDropSupport="true"
|
||||
uploadLabel="Télécharger" cancelLabel="Annuler" chooseLabel="Sélectionner"
|
||||
sizeLimit="10000000" fileLimit="5" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="card">
|
||||
<h5>Finalisation</h5>
|
||||
<div class="surface-50 p-4 border-round mb-4">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-info-circle text-blue-500 mr-3"></i>
|
||||
<div>
|
||||
<div class="font-medium text-900">Vérifiez toutes les informations</div>
|
||||
<div class="text-600">L'événement sera créé avec le statut "Planifié" et pourra être modifié ultérieurement</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<p:commandButton value="🎯 Créer l'événement" icon="pi pi-check"
|
||||
styleClass="ui-button ui-button-success"
|
||||
action="#{creationEvenementBean.creerEvenement}"
|
||||
update="messages"
|
||||
disabled="#{!creationEvenementBean.formulaireValide}" />
|
||||
|
||||
<p:commandButton value="💾 Enregistrer brouillon" icon="pi pi-save"
|
||||
styleClass="ui-button ui-button-outlined ui-button-info"
|
||||
action="#{creationEvenementBean.enregistrerBrouillon}"
|
||||
update="messages" />
|
||||
|
||||
<p:commandButton value="👁️ Prévisualiser" icon="pi pi-eye"
|
||||
styleClass="ui-button ui-button-outlined ui-button-warning"
|
||||
onclick="PF('dlgPreview').show();"
|
||||
type="button" />
|
||||
|
||||
<p:commandButton value="🔄 Réinitialiser" icon="pi pi-refresh"
|
||||
styleClass="ui-button ui-button-outlined ui-button-secondary"
|
||||
type="reset"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir réinitialiser le formulaire ?');" />
|
||||
|
||||
<p:commandButton value="❌ Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button ui-button-outlined ui-button-danger"
|
||||
action="/pages/admin/evenements/liste?faces-redirect=true"
|
||||
immediate="true"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler la création ?');" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-600">
|
||||
<small>
|
||||
<i class="pi pi-shield mr-1"></i>
|
||||
Les données de l'événement sont sécurisées et conformes RGPD
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
<!-- Dialog Prévisualisation -->
|
||||
<p:dialog header="Prévisualisation de l'événement" widgetVar="dlgPreview" modal="true" width="800" height="600">
|
||||
<h:form id="formPreview">
|
||||
<div class="card border-none p-0">
|
||||
<div class="flex align-items-start mb-4">
|
||||
<div class="border-round p-3 mr-3" style="background: var(--primary-color);">
|
||||
<i class="pi pi-calendar text-white text-2xl"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h4 class="mt-0 mb-2">#{creationEvenementBean.evenement.titre}</h4>
|
||||
<div class="text-600 mb-2">#{creationEvenementBean.evenement.typeEvenementLibelle}</div>
|
||||
<p:tag value="#{creationEvenementBean.evenement.priorite}"
|
||||
severity="#{creationEvenementBean.evenement.prioriteSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<h6>📅 Date et Heure</h6>
|
||||
<p>#{creationEvenementBean.evenement.dateCompleteFormatee}</p>
|
||||
|
||||
<h6>📍 Lieu</h6>
|
||||
<p>#{creationEvenementBean.evenement.lieu}</p>
|
||||
<small class="text-600">#{creationEvenementBean.evenement.adresse}</small>
|
||||
|
||||
<h6>👥 Participants</h6>
|
||||
<p>Maximum #{creationEvenementBean.evenement.placesMax} places</p>
|
||||
<p>Public: #{creationEvenementBean.evenement.publicCibleFormate}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h6>💰 Tarification</h6>
|
||||
<p>
|
||||
<span class="text-green-500 font-bold" rendered="#{!creationEvenementBean.evenement.payant}">Gratuit</span>
|
||||
<span rendered="#{creationEvenementBean.evenement.payant}">
|
||||
Prix: #{creationEvenementBean.evenement.prix} FCFA
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<h6>🔔 Notifications</h6>
|
||||
<p>Canaux: #{creationEvenementBean.evenement.canauxNotificationFormates}</p>
|
||||
|
||||
<h6>👨💼 Organisateur</h6>
|
||||
<p>#{creationEvenementBean.evenement.organisateur}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<h6>📝 Description</h6>
|
||||
<p class="line-height-3">#{creationEvenementBean.evenement.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-4">
|
||||
<p:commandButton value="Modifier" icon="pi pi-pencil"
|
||||
styleClass="ui-button-warning"
|
||||
onclick="PF('dlgPreview').hide();"
|
||||
type="button" />
|
||||
<p:commandButton value="Créer maintenant" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{creationEvenementBean.creerEvenement}"
|
||||
update=":formCreation:messages"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgPreview').hide();" />
|
||||
<p:commandButton value="Fermer" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgPreview').hide();"
|
||||
type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,588 @@
|
||||
<!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 Événements - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
<!-- En-tête principal avec disposition Freya stricte -->
|
||||
<div class="card">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-8">
|
||||
<h2 class="text-primary font-bold mb-2">
|
||||
<i class="pi pi-calendar text-blue-500 mr-2"></i>
|
||||
Gestion des Événements
|
||||
</h2>
|
||||
<p class="text-600 mt-0">
|
||||
Planification et suivi des activités associatives •
|
||||
<span class="font-semibold">#{evenementsBean.statistiques.totalEvenements} événements</span> •
|
||||
<span class="font-semibold text-green-600">#{evenementsBean.statistiques.evenementsActifs} actifs</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-4 text-right">
|
||||
<h:form id="formActionsEntete">
|
||||
<p:commandButton icon="pi pi-plus"
|
||||
title="Nouvel événement"
|
||||
styleClass="ui-button-success ui-button-sm mr-3"
|
||||
onclick="PF('dlgNouvelEvenement').show();" />
|
||||
<p:commandButton icon="pi pi-calendar"
|
||||
title="Planning mensuel"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm mr-3"
|
||||
onclick="PF('dlgPlanningMensuel').show();" />
|
||||
<p:commandButton icon="pi pi-download"
|
||||
title="Exporter"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm"
|
||||
action="#{evenementsBean.exporterEvenements}" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- KPIs avec grille Freya stricte -->
|
||||
<div class="formgrid grid">
|
||||
<!-- KPI 1: Total Événements -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Total Événements" />
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.totalEvenements}" />
|
||||
<ui:param name="icon" value="pi-calendar" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="growthValue" value="#{evenementsBean.statistiques.evenementsCeMois}" />
|
||||
<ui:param name="growthLabel" value="ce mois" />
|
||||
<ui:param name="growthType" value="number" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 2: Événements Actifs -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Événements Actifs" />
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.evenementsActifs}" />
|
||||
<ui:param name="icon" value="pi-check" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="progressValue" value="#{evenementsBean.statistiques.tauxParticipationMoyen}" />
|
||||
<ui:param name="noDataLabel" value="#{evenementsBean.statistiques.tauxParticipationMoyen}% de participation" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 3: Participants Inscrits -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Participants" />
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.participantsTotal}" />
|
||||
<ui:param name="icon" value="pi-users" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="statusIcon" value="pi-info-circle" />
|
||||
<ui:param name="statusLabel" value="Moyenne" />
|
||||
<ui:param name="statusValue" value="#{evenementsBean.statistiques.moyenneParticipants}/événement" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<!-- KPI 4: Budget Total -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Budget Total" />
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.budgetTotal}" />
|
||||
<ui:param name="icon" value="pi-dollar" />
|
||||
<ui:param name="iconColor" value="purple-600" />
|
||||
<ui:param name="statusIcon" value="pi-trending-up" />
|
||||
<ui:param name="statusLabel" value="Suivi budgétaire" />
|
||||
<ui:param name="statusValue" value="optimal" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Calendrier visuel des événements avec structure Freya -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">
|
||||
<i class="pi pi-calendar text-blue-500 mr-2"></i>
|
||||
Événements à Venir
|
||||
</h5>
|
||||
<div class="formgrid grid">
|
||||
<ui:repeat value="#{evenementsBean.evenementsProchains}" var="event" varStatus="status">
|
||||
<div class="field col-12 md:col-6 lg:col-4">
|
||||
<div class="surface-50 border-round-lg p-3 hover:surface-100 transition-colors transition-duration-150">
|
||||
<div class="flex align-items-start justify-content-between mb-3">
|
||||
<div class="flex align-items-center">
|
||||
<div class="flex align-items-center justify-content-center bg-primary-100 border-round-lg mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi #{event.typeIcon} text-primary-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-medium m-0 mb-1">#{event.titre}</h6>
|
||||
<p:tag value="#{event.typeLibelle}"
|
||||
severity="#{event.typeSeverity}"
|
||||
styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-500 text-sm font-semibold">#{event.joursRestants}j</span>
|
||||
</div>
|
||||
|
||||
<div class="text-600 mb-3">
|
||||
<div class="flex align-items-center mb-2">
|
||||
<i class="pi pi-calendar text-blue-500 mr-2"></i>
|
||||
<span class="text-sm">#{event.dateDebutFormatee}</span>
|
||||
</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<i class="pi pi-map-marker text-orange-500 mr-2"></i>
|
||||
<span class="text-sm">#{event.lieu}</span>
|
||||
</div>
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-users text-green-500 mr-2"></i>
|
||||
<span class="text-sm">#{event.participantsInscrits}/#{event.capaciteMax} participants</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-between align-items-center">
|
||||
<div class="flex-1 mr-3">
|
||||
<p:progressBar value="#{event.tauxInscription}"
|
||||
showValue="false"
|
||||
styleClass="surface-200"
|
||||
style="height: 0.5rem;" />
|
||||
<div class="text-500 text-xs mt-1">#{event.tauxInscription}% rempli</div>
|
||||
</div>
|
||||
<h:form>
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info ui-button-sm"
|
||||
title="Voir détails">
|
||||
<f:setPropertyActionListener target="#{evenementsBean.evenementSelectionne}" value="#{event}" />
|
||||
</p:commandButton>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Section Filtres avec structure Freya -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">
|
||||
<i class="pi pi-filter text-blue-500 mr-2"></i>
|
||||
Filtres et Recherche
|
||||
</h5>
|
||||
<h:form id="formFiltres">
|
||||
<div class="formgrid grid">
|
||||
<!-- Ligne 1: 4 champs principaux -->
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="searchTitre" class="block text-900 font-medium mb-2">Titre de l'événement</label>
|
||||
<p:inputText id="searchTitre"
|
||||
value="#{evenementsBean.filtres.titre}"
|
||||
placeholder="Rechercher par titre..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" delay="300"
|
||||
update=":formTableEvenements:dtEvenements" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filterType" class="block text-900 font-medium mb-2">Type d'événement</label>
|
||||
<p:selectOneMenu id="filterType"
|
||||
value="#{evenementsBean.filtres.type}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Réunion" itemValue="REUNION" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Action Sociale" itemValue="ACTION_SOCIALE" />
|
||||
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
|
||||
<f:selectItem itemLabel="Événement Festif" itemValue="EVENEMENT_FESTIF" />
|
||||
<p:ajax update=":formTableEvenements:dtEvenements" />
|
||||
</p:selectOneMenu>
|
||||
</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="#{evenementsBean.filtres.statut}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Planifié" itemValue="PLANIFIE" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
|
||||
<f:selectItem itemLabel="Terminé" itemValue="TERMINE" />
|
||||
<f:selectItem itemLabel="Annulé" itemValue="ANNULE" />
|
||||
<p:ajax update=":formTableEvenements:dtEvenements" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-3">
|
||||
<label for="filterPriorite" class="block text-900 font-medium mb-2">Priorité</label>
|
||||
<p:selectOneMenu id="filterPriorite"
|
||||
value="#{evenementsBean.filtres.priorite}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les priorités" itemValue="" />
|
||||
<f:selectItem itemLabel="Faible" itemValue="FAIBLE" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Élevée" itemValue="ELEVEE" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
|
||||
<p:ajax update=":formTableEvenements:dtEvenements" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<!-- Ligne 2: Période et Organisateur -->
|
||||
<div class="field col-12 md:col-6 lg:col-4">
|
||||
<label for="filterDateDebut" class="block text-900 font-medium mb-2">Période</label>
|
||||
<div class="flex gap-2">
|
||||
<p:datePicker id="filterDateDebut"
|
||||
value="#{evenementsBean.filtres.dateDebut}"
|
||||
placeholder="Date début"
|
||||
styleClass="w-full">
|
||||
<p:ajax update=":formTableEvenements:dtEvenements" />
|
||||
</p:datePicker>
|
||||
<p:datePicker id="filterDateFin"
|
||||
value="#{evenementsBean.filtres.dateFin}"
|
||||
placeholder="Date fin"
|
||||
styleClass="w-full">
|
||||
<p:ajax update=":formTableEvenements:dtEvenements" />
|
||||
</p:datePicker>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6 lg:col-4">
|
||||
<label for="filterOrganisateur" class="block text-900 font-medium mb-2">Organisateur</label>
|
||||
<p:inputText id="filterOrganisateur"
|
||||
value="#{evenementsBean.filtres.organisateur}"
|
||||
placeholder="Filtrer par organisateur..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" delay="300"
|
||||
update=":formTableEvenements:dtEvenements" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-12 lg:col-4">
|
||||
<label class="block text-900 font-medium mb-2"> </label>
|
||||
<div class="flex justify-content-start">
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary ui-button-sm"
|
||||
action="#{evenementsBean.reinitialiserFiltres}"
|
||||
update="@form :formTableEvenements:dtEvenements" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Table des Événements avec structure Freya -->
|
||||
<div class="card">
|
||||
<h:form id="formTableEvenements">
|
||||
<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 Événements
|
||||
</h5>
|
||||
<div class="flex gap-3 align-items-center">
|
||||
<p:commandButton value="Actions groupées"
|
||||
icon="pi pi-bars"
|
||||
styleClass="ui-button-warning ui-button-sm"
|
||||
onclick="PF('dlgActionsGroupees').show();"
|
||||
disabled="#{empty evenementsBean.evenementsSelectionnes}" />
|
||||
<p:commandButton value="Export Excel"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-success ui-button-outlined ui-button-sm"
|
||||
action="#{evenementsBean.exporterExcel}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p:dataTable id="dtEvenements"
|
||||
value="#{evenementsBean.evenementsFiltres}"
|
||||
var="evenement"
|
||||
selection="#{evenementsBean.evenementsSelectionnes}"
|
||||
rowKey="#{evenement.id}"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
paginatorPosition="bottom"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords} événements"
|
||||
styleClass="p-datatable-sm p-datatable-gridlines p-datatable-striped"
|
||||
emptyMessage="Aucun événement trouvé">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:3rem" exportable="false"/>
|
||||
|
||||
<p:column headerText="Événement" sortBy="#{evenement.titre}" filterBy="#{evenement.titre}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="flex align-items-center justify-content-center bg-primary-100 border-circle mr-2"
|
||||
style="width: 2rem; height: 2rem;">
|
||||
<i class="pi #{evenement.typeEvenementIcon} text-primary-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{evenement.titre}</div>
|
||||
<div class="text-500 text-xs">#{evenement.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{evenement.typeEvenement}" filterBy="#{evenement.typeEvenement}" style="width:8rem">
|
||||
<p:tag value="#{evenement.typeEvenementLibelle}"
|
||||
severity="#{evenement.typeEvenementSeverity}"
|
||||
icon="pi #{evenement.typeEvenementIcon}"
|
||||
styleClass="text-xs" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date et Heure" sortBy="#{evenement.dateDebut}" style="width:10rem">
|
||||
<div>
|
||||
<div class="text-900 font-medium text-sm">#{evenement.dateDebutFormatee}</div>
|
||||
<div class="text-500 text-xs">#{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Lieu" style="width:10rem">
|
||||
<div>
|
||||
<div class="text-900 font-medium text-sm">#{evenement.lieu}</div>
|
||||
<div class="text-500 text-xs">#{evenement.adresse}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisateur">
|
||||
<div class="flex align-items-center" rendered="#{evenement.organisateur != null}">
|
||||
<div class="bg-300 border-circle mr-2" style="width: 1.5rem; height: 1.5rem;"></div>
|
||||
<div>
|
||||
<div class="text-900 text-sm">#{evenement.organisateur}</div>
|
||||
<div class="text-500 text-xs">#{evenement.organisateurEmail}</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-400 text-xs" rendered="#{evenement.organisateur == null}">
|
||||
Aucun organisateur
|
||||
</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Participants" sortBy="#{evenement.participantsInscrits}" style="width:8rem; text-align:center">
|
||||
<div class="text-center">
|
||||
<div class="text-900 font-bold">#{evenement.participantsInscrits}</div>
|
||||
<div class="text-500 text-xs mb-1">/#{evenement.capaciteMax} places</div>
|
||||
<p:progressBar value="#{evenement.tauxInscription}"
|
||||
showValue="false"
|
||||
styleClass="surface-200"
|
||||
style="height: 0.3rem;" />
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Budget" sortBy="#{evenement.budget}" style="width:8rem">
|
||||
<div class="text-900 font-bold text-right">#{evenement.budgetFormatte}</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Priorité" sortBy="#{evenement.priorite}" filterBy="#{evenement.priorite}" style="width:7rem">
|
||||
<p:tag value="#{evenement.priorite}"
|
||||
severity="#{evenement.prioriteSeverity}"
|
||||
styleClass="text-xs w-full" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{evenement.statut}" filterBy="#{evenement.statut}" style="width:8rem">
|
||||
<p:tag value="#{evenement.statut}"
|
||||
severity="#{evenement.statutSeverity}"
|
||||
icon="pi #{evenement.statutIcon}"
|
||||
styleClass="text-xs w-full" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:8rem" exportable="false">
|
||||
<h:form id="formActions#{evenement.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"
|
||||
onclick="PF('dlgDetailsEvenement').show();"
|
||||
title="Voir détails">
|
||||
<f:setPropertyActionListener target="#{evenementsBean.evenementSelectionne}" value="#{evenement}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning ui-button-sm"
|
||||
onclick="PF('dlgModifierEvenement').show();"
|
||||
title="Modifier">
|
||||
<f:setPropertyActionListener target="#{evenementsBean.evenementSelectionne}" value="#{evenement}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-cog"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary ui-button-sm"
|
||||
onclick="PF('dlgActionsEvenement').show();"
|
||||
title="Actions">
|
||||
<f:setPropertyActionListener target="#{evenementsBean.evenementSelectionne}" value="#{evenement}" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Dialogs avec structure Freya -->
|
||||
|
||||
<!-- Dialog Nouvel Événement -->
|
||||
<p:dialog header="Créer un Nouvel Événement"
|
||||
widgetVar="dlgNouvelEvenement"
|
||||
modal="true"
|
||||
width="800"
|
||||
height="auto"
|
||||
resizable="false">
|
||||
<h:form id="formNouvelEvenement">
|
||||
<div class="ui-fluid formgrid grid">
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="newTitre" class="block text-900 font-medium mb-2">Titre de l'événement *</label>
|
||||
<p:inputText id="newTitre"
|
||||
value="#{evenementsBean.nouvelEvenement.titre}"
|
||||
required="true"
|
||||
placeholder="Ex: Assemblée Générale 2024" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="newType" class="block text-900 font-medium mb-2">Type d'événement *</label>
|
||||
<p:selectOneMenu id="newType"
|
||||
value="#{evenementsBean.nouvelEvenement.typeEvenement}"
|
||||
required="true">
|
||||
<f:selectItem itemLabel="Sélectionner un type" itemValue="" />
|
||||
<f:selectItem itemLabel="Réunion" itemValue="REUNION" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Action Sociale" itemValue="ACTION_SOCIALE" />
|
||||
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
|
||||
<f:selectItem itemLabel="Événement Festif" itemValue="EVENEMENT_FESTIF" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="newDateDebut" class="block text-900 font-medium mb-2">Date de début *</label>
|
||||
<p:datePicker id="newDateDebut"
|
||||
value="#{evenementsBean.nouvelEvenement.dateDebut}"
|
||||
required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="newDateFin" class="block text-900 font-medium mb-2">Date de fin</label>
|
||||
<p:datePicker id="newDateFin"
|
||||
value="#{evenementsBean.nouvelEvenement.dateFin}" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="newLieu" class="block text-900 font-medium mb-2">Lieu *</label>
|
||||
<p:inputText id="newLieu"
|
||||
value="#{evenementsBean.nouvelEvenement.lieu}"
|
||||
required="true"
|
||||
placeholder="Ex: Salle de conférence" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<label for="newCapacite" class="block text-900 font-medium mb-2">Capacité maximum</label>
|
||||
<p:inputNumber id="newCapacite"
|
||||
value="#{evenementsBean.nouvelEvenement.capaciteMax}"
|
||||
placeholder="100" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<label for="newAdresse" class="block text-900 font-medium mb-2">Adresse complète</label>
|
||||
<p:inputTextarea id="newAdresse"
|
||||
value="#{evenementsBean.nouvelEvenement.adresse}"
|
||||
rows="2"
|
||||
placeholder="Adresse complète de l'événement..." />
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<label for="newDescription" class="block text-900 font-medium mb-2">Description</label>
|
||||
<p:inputTextarea id="newDescription"
|
||||
value="#{evenementsBean.nouvelEvenement.description}"
|
||||
rows="3"
|
||||
placeholder="Description détaillée de l'événement..." />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-4">
|
||||
<label for="newPriorite" class="block text-900 font-medium mb-2">Priorité</label>
|
||||
<p:selectOneMenu id="newPriorite"
|
||||
value="#{evenementsBean.nouvelEvenement.priorite}">
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Faible" itemValue="FAIBLE" />
|
||||
<f:selectItem itemLabel="Élevée" itemValue="ELEVEE" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-4">
|
||||
<label for="newOrganisateur" class="block text-900 font-medium mb-2">Organisateur</label>
|
||||
<p:inputText id="newOrganisateur"
|
||||
value="#{evenementsBean.nouvelEvenement.organisateur}"
|
||||
placeholder="Nom de l'organisateur" />
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-4">
|
||||
<label for="newBudget" class="block text-900 font-medium mb-2">Budget estimé</label>
|
||||
<p:inputNumber id="newBudget"
|
||||
value="#{evenementsBean.nouvelEvenement.budget}"
|
||||
mode="currency"
|
||||
currency="XOF"
|
||||
locale="fr-CI"
|
||||
placeholder="50000" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm"
|
||||
onclick="PF('dlgNouvelEvenement').hide();"
|
||||
type="button" />
|
||||
<p:commandButton value="Créer l'événement"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-success ui-button-sm"
|
||||
action="#{evenementsBean.creerEvenement}"
|
||||
update="@form :formTableEvenements:dtEvenements"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgNouvelEvenement').hide();" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
|
||||
<!-- Dialog Actions Événement -->
|
||||
<p:dialog header="Actions sur l'Événement"
|
||||
widgetVar="dlgActionsEvenement"
|
||||
modal="true"
|
||||
width="400"
|
||||
height="auto"
|
||||
resizable="false">
|
||||
<h:form id="formActionsEvenement">
|
||||
<div class="surface-50 border-round-lg p-3 mb-3">
|
||||
<div class="text-500 text-sm mb-1">Événement sélectionné</div>
|
||||
<div class="text-900 font-bold">#{evenementsBean.evenementSelectionne.titre}</div>
|
||||
<div class="text-500 text-sm">#{evenementsBean.evenementSelectionne.dateDebutFormatee}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-column gap-2">
|
||||
<p:commandButton value="Gérer les participants"
|
||||
icon="pi pi-users"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm w-full"
|
||||
action="#{evenementsBean.gererParticipants}" />
|
||||
|
||||
<p:commandButton value="Envoyer invitations"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-success ui-button-outlined ui-button-sm w-full"
|
||||
action="#{evenementsBean.envoyerInvitations}" />
|
||||
|
||||
<p:commandButton value="Rapports de participation"
|
||||
icon="pi pi-chart-bar"
|
||||
styleClass="ui-button-secondary ui-button-outlined ui-button-sm w-full"
|
||||
action="#{evenementsBean.voirRapports}" />
|
||||
|
||||
<p:commandButton value="Planning mensuel"
|
||||
icon="pi pi-calendar"
|
||||
styleClass="ui-button-warning ui-button-outlined ui-button-sm w-full"
|
||||
onclick="PF('dlgPlanningMensuel').show();" />
|
||||
|
||||
<p:commandButton value="Dupliquer l'événement"
|
||||
icon="pi pi-copy"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm w-full"
|
||||
action="#{evenementsBean.dupliquerEvenement}" />
|
||||
|
||||
<hr class="surface-border" />
|
||||
|
||||
<p:commandButton value="Annuler l'événement"
|
||||
icon="pi pi-ban"
|
||||
styleClass="ui-button-danger ui-button-sm w-full"
|
||||
onclick="return confirm('ATTENTION: Confirmer l\'annulation ?');"
|
||||
action="#{evenementsBean.annulerEvenement}"
|
||||
rendered="#{evenementsBean.evenementSelectionne.statut != 'ANNULE'}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,430 @@
|
||||
<!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 Événements - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<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="pi pi-calendar text-blue-500 mr-2"></i>
|
||||
Gestion des Événements
|
||||
</h3>
|
||||
<p class="text-600 m-0">#{evenementBean.totalEvenements} événements • #{evenementBean.evenementsActifs} actifs • #{evenementBean.prochainEvenement}</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouvel événement"
|
||||
icon="pi pi-plus"
|
||||
styleClass="ui-button-success"
|
||||
action="/pages/admin/evenements/creation?faces-redirect=true" />
|
||||
<p:commandButton value="Calendrier"
|
||||
icon="pi pi-calendar-plus"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{evenementBean.voirCalendrier}" />
|
||||
<p:commandButton value="Import/Export"
|
||||
icon="pi pi-download"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{evenementBean.importExport}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-blue-100 border-left-3 border-blue-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-blue-900 font-bold text-2xl">#{evenementBean.evenementsActifs}</div>
|
||||
<div class="text-blue-700">Événements Actifs</div>
|
||||
</div>
|
||||
<div class="bg-blue-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-calendar text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-green-100 border-left-3 border-green-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-green-900 font-bold text-2xl">#{evenementBean.totalParticipants}</div>
|
||||
<div class="text-green-700">Participants Inscrits</div>
|
||||
</div>
|
||||
<div class="bg-green-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-users text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-purple-100 border-left-3 border-purple-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-purple-900 font-bold text-2xl">#{evenementBean.revenusEvenements}</div>
|
||||
<div class="text-purple-700">Revenus Événements</div>
|
||||
</div>
|
||||
<div class="bg-purple-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-dollar text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-orange-100 border-left-3 border-orange-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-orange-900 font-bold text-2xl">#{evenementBean.tauxParticipation}%</div>
|
||||
<div class="text-orange-700">Taux Participation</div>
|
||||
</div>
|
||||
<div class="bg-orange-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-chart-pie text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prochains événements (aperçu rapide) -->
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-clock mr-2"></i>
|
||||
Prochains Événements
|
||||
</h5>
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{evenementBean.prochainsEvenements}" var="event" varStatus="status">
|
||||
<div class="col-12 md:col-6 lg:col-4">
|
||||
<div class="surface-card border-round p-3 border-left-3 #{event.prioriteColor}">
|
||||
<div class="flex align-items-start justify-content-between mb-2">
|
||||
<div>
|
||||
<span class="text-500 font-medium">#{event.dateFormatee}</span>
|
||||
<div class="text-900 font-medium text-xl mt-1">#{event.titre}</div>
|
||||
</div>
|
||||
<p:tag value="#{event.statut}" severity="#{event.statutSeverity}" />
|
||||
</div>
|
||||
<div class="text-600 mb-3">
|
||||
<i class="pi pi-map-marker mr-1"></i>
|
||||
#{event.lieu}
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span class="text-green-500 font-bold">
|
||||
#{event.inscrits}/#{event.placesMax} inscrits
|
||||
</span>
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-sm"
|
||||
action="#{evenementBean.voirEvenement(event)}" />
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-sm"
|
||||
action="#{evenementBean.modifierEvenement(event)}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste complète des événements -->
|
||||
<div class="card">
|
||||
<h:form id="formEvenements">
|
||||
<h5>Tous les Événements</h5>
|
||||
|
||||
<!-- Filtres -->
|
||||
<p:toolbar>
|
||||
<p:toolbarGroup>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText placeholder="Rechercher..."
|
||||
value="#{evenementBean.searchFilter}">
|
||||
<p:ajax event="keyup" update="dtEvenements" />
|
||||
</p:inputText>
|
||||
</span>
|
||||
|
||||
<p:selectOneMenu value="#{evenementBean.statutFilter}">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Planifié" itemValue="PLANIFIE" />
|
||||
<f:selectItem itemLabel="Ouvert aux inscriptions" itemValue="OUVERT" />
|
||||
<f:selectItem itemLabel="Complet" itemValue="COMPLET" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
|
||||
<f:selectItem itemLabel="Terminé" itemValue="TERMINE" />
|
||||
<f:selectItem itemLabel="Annulé" itemValue="ANNULE" />
|
||||
<p:ajax update="dtEvenements" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{evenementBean.typeFilter}">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Réunion" itemValue="REUNION" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Loisir" itemValue="LOISIR" />
|
||||
<f:selectItem itemLabel="Cérémonie" itemValue="CEREMONIE" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
<p:ajax update="dtEvenements" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:calendar value="#{evenementBean.dateFilter}"
|
||||
pattern="dd/MM/yyyy" showIcon="true"
|
||||
placeholder="Filtrer par date">
|
||||
<p:ajax event="dateSelect" update="dtEvenements" />
|
||||
</p:calendar>
|
||||
</div>
|
||||
</p:toolbarGroup>
|
||||
|
||||
<p:toolbarGroup align="right">
|
||||
<p:commandButton icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{evenementBean.actualiser}"
|
||||
update="@form"
|
||||
title="Actualiser" />
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtEvenements"
|
||||
var="evenement"
|
||||
value="#{evenementBean.evenements}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25,50"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{evenementBean.selectedEvenements}"
|
||||
rowKey="#{evenement.id}"
|
||||
selectionMode="multiple"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="Titre" sortBy="#{evenement.titre}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-round p-2 mr-3" style="background: #{evenement.couleurCategorie};">
|
||||
<i class="pi #{evenement.iconeType} text-white"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-900">#{evenement.titre}</div>
|
||||
<small class="text-600">#{evenement.typeEvenementLibelle}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date/Heure" sortBy="#{evenement.dateDebut}" style="width:180px">
|
||||
<div>
|
||||
<div class="font-medium">#{evenement.dateDebut}</div>
|
||||
<small class="text-600">#{evenement.heureDebut} - #{evenement.heureFin}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Lieu" sortBy="#{evenement.lieu}">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-map-marker text-500 mr-2"></i>
|
||||
<span>#{evenement.lieu}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{evenement.statut}" style="width:120px">
|
||||
<p:tag value="#{evenement.statut}"
|
||||
severity="#{evenement.statutSeverity}"
|
||||
icon="pi #{evenement.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Participants" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold">#{evenement.nombreInscrits}/#{evenement.placesMax}</div>
|
||||
<p:progressBar value="#{evenement.tauxRemplissage}"
|
||||
labelTemplate=""
|
||||
styleClass="h-1rem" />
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Prix" sortBy="#{evenement.prix}" style="width:100px">
|
||||
<h:outputText value="#{evenement.prix}" styleClass="font-bold" rendered="#{evenement.prix > 0}">
|
||||
<f:convertNumber type="currency" currencySymbol="FCFA " />
|
||||
</h:outputText>
|
||||
<span class="text-green-500 font-medium" rendered="#{evenement.prix == 0}">Gratuit</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisateur" sortBy="#{evenement.organisateur}">
|
||||
<h:outputText value="#{evenement.organisateur}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{evenementBean.voirEvenement(evenement)}"
|
||||
title="Voir détails" />
|
||||
<p:commandButton icon="pi pi-users"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{evenementBean.gererParticipants(evenement)}"
|
||||
title="Gérer participants" />
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
action="#{evenementBean.modifierEvenement(evenement)}"
|
||||
title="Modifier" />
|
||||
<p:commandButton icon="pi pi-copy"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
action="#{evenementBean.dupliquerEvenement(evenement)}"
|
||||
title="Dupliquer" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
action="#{evenementBean.annulerEvenement(evenement)}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler cet événement ?');"
|
||||
title="Annuler"
|
||||
disabled="#{evenement.statut == 'TERMINE' or evenement.statut == 'ANNULE'}" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Actions groupées -->
|
||||
<div class="mt-3 flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<span class="text-600">#{evenementBean.selectedEvenements.size()} événement(s) sélectionné(s)</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Notification groupée"
|
||||
icon="pi pi-bell"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{evenementBean.notificationGroupee}"
|
||||
disabled="#{empty evenementBean.selectedEvenements}" />
|
||||
<p:commandButton value="Exporter sélection"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-outlined ui-button-success"
|
||||
action="#{evenementBean.exporterSelection}"
|
||||
disabled="#{empty evenementBean.selectedEvenements}" />
|
||||
<p:commandButton value="Annuler sélection"
|
||||
icon="pi pi-ban"
|
||||
styleClass="ui-button-outlined ui-button-danger"
|
||||
action="#{evenementBean.annulerSelection}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler les événements sélectionnés ?');"
|
||||
disabled="#{empty evenementBean.selectedEvenements}" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Calendrier intégré (optionnel) -->
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-calendar mr-2"></i>
|
||||
Vue Calendrier
|
||||
</h5>
|
||||
<p:schedule value="#{evenementBean.eventModel}"
|
||||
widgetVar="schedule"
|
||||
timeZone="GMT+0"
|
||||
clientTimeZone="GMT+0"
|
||||
locale="fr"
|
||||
style="height: 600px;"
|
||||
view="month">
|
||||
|
||||
<p:ajax event="eventSelect" listener="#{evenementBean.onEventSelect}" />
|
||||
<p:ajax event="dateSelect" listener="#{evenementBean.onDateSelect}" />
|
||||
<p:ajax event="eventMove" listener="#{evenementBean.onEventMove}" />
|
||||
<p:ajax event="eventResize" listener="#{evenementBean.onEventResize}" />
|
||||
</p:schedule>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Détails événement -->
|
||||
<p:dialog header="Détails de l'événement" widgetVar="dlgDetails" modal="true" width="700" height="500">
|
||||
<h:form id="formDetails" rendered="#{evenementBean.evenementSelectionne != null}">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Titre</label>
|
||||
<div class="text-900">#{evenementBean.evenementSelectionne.titre}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium">Type</label>
|
||||
<div class="text-900">#{evenementBean.evenementSelectionne.typeEvenementLibelle}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium">Date et heure</label>
|
||||
<div class="text-900">
|
||||
#{evenementBean.evenementSelectionne.dateComplete}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium">Lieu</label>
|
||||
<div class="text-900">#{evenementBean.evenementSelectionne.lieu}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Statut</label>
|
||||
<div>
|
||||
<p:tag value="#{evenementBean.evenementSelectionne.statut}"
|
||||
severity="#{evenementBean.evenementSelectionne.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium">Participants</label>
|
||||
<div class="text-900">
|
||||
#{evenementBean.evenementSelectionne.nombreInscrits}/#{evenementBean.evenementSelectionne.placesMax}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium">Prix</label>
|
||||
<div class="text-900">
|
||||
<h:outputText value="#{evenementBean.evenementSelectionne.prix}" rendered="#{evenementBean.evenementSelectionne.prix > 0}">
|
||||
<f:convertNumber type="currency" currencySymbol="FCFA " />
|
||||
</h:outputText>
|
||||
<span class="text-green-500" rendered="#{evenementBean.evenementSelectionne.prix == 0}">Gratuit</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium">Organisateur</label>
|
||||
<div class="text-900">#{evenementBean.evenementSelectionne.organisateur}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Description</label>
|
||||
<div class="text-900 line-height-3">#{evenementBean.evenementSelectionne.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-4">
|
||||
<p:commandButton value="Modifier" icon="pi pi-pencil"
|
||||
styleClass="ui-button-warning"
|
||||
action="#{evenementBean.modifierEvenement(evenementBean.evenementSelectionne)}"
|
||||
oncomplete="PF('dlgDetails').hide();" />
|
||||
<p:commandButton value="Gérer participants" icon="pi pi-users"
|
||||
styleClass="ui-button-success"
|
||||
action="#{evenementBean.gererParticipants(evenementBean.evenementSelectionne)}"
|
||||
oncomplete="PF('dlgDetails').hide();" />
|
||||
<p:commandButton value="Fermer" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgDetails').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,517 @@
|
||||
<!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 Participants - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<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="pi pi-users text-blue-500 mr-2"></i>
|
||||
Gestion des Participants
|
||||
</h3>
|
||||
<p class="text-600 m-0">#{participantBean.evenement.titre} • #{participantBean.dateEvenement} • #{participantBean.nombreInscrits}/#{participantBean.placesMax} places</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Inscrire membre"
|
||||
icon="pi pi-user-plus"
|
||||
styleClass="ui-button-success"
|
||||
onclick="PF('dlgInscrireMembre').show();" />
|
||||
<p:commandButton value="Liste d'attente"
|
||||
icon="pi pi-clock"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
action="#{participantBean.gererListeAttente}" />
|
||||
<p:commandButton value="Retour à l'événement"
|
||||
icon="pi pi-arrow-left"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{participantBean.retourEvenement}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-blue-100 border-left-3 border-blue-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-blue-900 font-bold text-2xl">#{participantBean.nombreInscrits}</div>
|
||||
<div class="text-blue-700">Inscrits Confirmés</div>
|
||||
</div>
|
||||
<div class="bg-blue-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-check text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<p:progressBar value="#{participantBean.tauxRemplissage}"
|
||||
labelTemplate=""
|
||||
styleClass="h-1rem" />
|
||||
<small class="text-600">#{participantBean.tauxRemplissage}% de remplissage</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-orange-100 border-left-3 border-orange-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-orange-900 font-bold text-2xl">#{participantBean.enAttente}</div>
|
||||
<div class="text-orange-700">En Attente</div>
|
||||
</div>
|
||||
<div class="bg-orange-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-clock text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-green-100 border-left-3 border-green-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-green-900 font-bold text-2xl">#{participantBean.montantCollecte}</div>
|
||||
<div class="text-green-700">Collecté</div>
|
||||
</div>
|
||||
<div class="bg-green-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-dollar text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="card bg-purple-100 border-left-3 border-purple-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-purple-900 font-bold text-2xl">#{participantBean.accompagnateurs}</div>
|
||||
<div class="text-purple-700">Accompagnateurs</div>
|
||||
</div>
|
||||
<div class="bg-purple-500 text-white border-round text-center"
|
||||
style="width: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-user-plus text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions rapides -->
|
||||
<div class="card">
|
||||
<h5>Actions Rapides</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-50 p-3 border-round text-center">
|
||||
<i class="pi pi-envelope text-blue-500 text-2xl mb-2"></i>
|
||||
<div class="font-medium mb-2">Notifications</div>
|
||||
<p:commandButton value="Envoyer rappel général"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-outlined ui-button-info w-full mb-2"
|
||||
action="#{participantBean.envoyerRappelGeneral}" />
|
||||
<p:commandButton value="Info dernière minute"
|
||||
icon="pi pi-exclamation-triangle"
|
||||
styleClass="ui-button-outlined ui-button-warning w-full"
|
||||
onclick="PF('dlgInfoDernierMinute').show();" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-50 p-3 border-round text-center">
|
||||
<i class="pi pi-qrcode text-green-500 text-2xl mb-2"></i>
|
||||
<div class="font-medium mb-2">Check-in</div>
|
||||
<p:commandButton value="Scanner QR Code"
|
||||
icon="pi pi-camera"
|
||||
styleClass="ui-button-outlined ui-button-success w-full mb-2"
|
||||
onclick="PF('dlgScannerQR').show();" />
|
||||
<p:commandButton value="Check-in manuel"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-outlined ui-button-secondary w-full"
|
||||
onclick="PF('dlgCheckinManuel').show();" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-50 p-3 border-round text-center">
|
||||
<i class="pi pi-file text-purple-500 text-2xl mb-2"></i>
|
||||
<div class="font-medium mb-2">Rapports</div>
|
||||
<p:commandButton value="Feuille d'émargement"
|
||||
icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-outlined ui-button-danger w-full mb-2"
|
||||
action="#{participantBean.genererEmargement}" />
|
||||
<p:commandButton value="Liste participants"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-outlined ui-button-success w-full"
|
||||
action="#{participantBean.exporterListe}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des participants -->
|
||||
<div class="card">
|
||||
<h:form id="formParticipants">
|
||||
<h5>Liste des Participants</h5>
|
||||
|
||||
<!-- Filtres -->
|
||||
<p:toolbar>
|
||||
<p:toolbarGroup>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText placeholder="Rechercher..."
|
||||
value="#{participantBean.searchFilter}">
|
||||
<p:ajax event="keyup" update="dtParticipants" />
|
||||
</p:inputText>
|
||||
</span>
|
||||
|
||||
<p:selectOneMenu value="#{participantBean.statutFilter}">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Confirmé" itemValue="CONFIRME" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="Présent" itemValue="PRESENT" />
|
||||
<f:selectItem itemLabel="Absent" itemValue="ABSENT" />
|
||||
<f:selectItem itemLabel="Annulé" itemValue="ANNULE" />
|
||||
<p:ajax update="dtParticipants" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{participantBean.typeFilter}">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Membres" itemValue="MEMBRE" />
|
||||
<f:selectItem itemLabel="Accompagnateurs" itemValue="ACCOMPAGNATEUR" />
|
||||
<f:selectItem itemLabel="Invités" itemValue="INVITE" />
|
||||
<p:ajax update="dtParticipants" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{participantBean.paiementFilter}">
|
||||
<f:selectItem itemLabel="Tous paiements" itemValue="" />
|
||||
<f:selectItem itemLabel="Payé" itemValue="PAYE" />
|
||||
<f:selectItem itemLabel="Non payé" itemValue="NON_PAYE" />
|
||||
<f:selectItem itemLabel="Gratuit" itemValue="GRATUIT" />
|
||||
<p:ajax update="dtParticipants" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</p:toolbarGroup>
|
||||
|
||||
<p:toolbarGroup align="right">
|
||||
<p:commandButton icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{participantBean.actualiser}"
|
||||
update="@form"
|
||||
title="Actualiser" />
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtParticipants"
|
||||
var="participant"
|
||||
value="#{participantBean.participants}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="10,15,25,50"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{participantBean.selectedParticipants}"
|
||||
rowKey="#{participant.id}"
|
||||
selectionMode="multiple"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="Participant" sortBy="#{participant.nom}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle overflow-hidden mr-3"
|
||||
style="width: 40px; height: 40px;">
|
||||
<h:graphicImage value="#{participant.photoUrl}"
|
||||
style="width: 100%; height: 100%; object-fit: cover;"
|
||||
rendered="#{participant.photoUrl != null}" />
|
||||
<div class="bg-primary text-white flex align-items-center justify-content-center w-full h-full"
|
||||
rendered="#{participant.photoUrl == null}">
|
||||
<span style="font-size: 0.9rem;">#{participant.initiales}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-900">#{participant.nomComplet}</div>
|
||||
<div class="text-600 text-sm">
|
||||
<span>#{participant.numeroMembre}</span>
|
||||
<span class="mx-2">•</span>
|
||||
<span>#{participant.telephone}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{participant.type}" style="width:120px">
|
||||
<p:tag value="#{participant.type}"
|
||||
severity="#{participant.typeSeverity}"
|
||||
icon="pi #{participant.typeIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{participant.statut}" style="width:120px">
|
||||
<p:tag value="#{participant.statut}"
|
||||
severity="#{participant.statutSeverity}"
|
||||
icon="pi #{participant.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Inscription" sortBy="#{participant.dateInscription}" style="width:140px">
|
||||
<div>
|
||||
<div class="font-medium">#{participant.dateInscription}</div>
|
||||
<small class="text-600">#{participant.heureInscription}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Paiement" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold #{participant.paiementColor}">#{participant.montantPaye}</div>
|
||||
<p:tag value="#{participant.statutPaiement}"
|
||||
severity="#{participant.paiementSeverity}"
|
||||
styleClass="text-xs" />
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Accomp." style="width:80px; text-align: center;">
|
||||
<span class="bg-purple-100 text-purple-800 border-round px-2 py-1 text-sm font-medium"
|
||||
rendered="#{participant.nombreAccompagnateurs > 0}">
|
||||
#{participant.nombreAccompagnateurs}
|
||||
</span>
|
||||
<span class="text-400" rendered="#{participant.nombreAccompagnateurs == 0}">-</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Check-in" style="width:100px; text-align: center;">
|
||||
<i class="pi pi-check-circle text-green-500 text-xl"
|
||||
rendered="#{participant.presente}"
|
||||
title="Présent depuis #{participant.heureCheckin}" />
|
||||
<i class="pi pi-times-circle text-red-400 text-xl"
|
||||
rendered="#{!participant.presente and participant.statut == 'CONFIRME'}"
|
||||
title="Pas encore arrivé" />
|
||||
<span class="text-400" rendered="#{participant.statut != 'CONFIRME'}">-</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:180px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{participantBean.confirmerParticipant(participant)}"
|
||||
title="Confirmer"
|
||||
rendered="#{participant.statut == 'EN_ATTENTE'}" />
|
||||
<p:commandButton icon="pi pi-qrcode"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{participantBean.checkinParticipant(participant)}"
|
||||
title="Check-in"
|
||||
rendered="#{!participant.presente and participant.statut == 'CONFIRME'}" />
|
||||
<p:commandButton icon="pi pi-undo"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
action="#{participantBean.annulerCheckin(participant)}"
|
||||
title="Annuler check-in"
|
||||
rendered="#{participant.presente}" />
|
||||
<p:commandButton icon="pi pi-envelope"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
action="#{participantBean.envoyerNotification(participant)}"
|
||||
title="Notifier" />
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
onclick="#{participantBean.preparerModification(participant)}; PF('dlgModifierParticipant').show();"
|
||||
title="Modifier" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
action="#{participantBean.annulerInscription(participant)}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler cette inscription ?');"
|
||||
title="Annuler inscription" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Actions groupées -->
|
||||
<div class="mt-3 flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<span class="text-600">#{participantBean.selectedParticipants.size()} participant(s) sélectionné(s)</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Check-in groupé"
|
||||
icon="pi pi-check-circle"
|
||||
styleClass="ui-button-outlined ui-button-success"
|
||||
action="#{participantBean.checkinGroupe}"
|
||||
disabled="#{empty participantBean.selectedParticipants}" />
|
||||
<p:commandButton value="Notification groupée"
|
||||
icon="pi pi-bell"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
onclick="PF('dlgNotificationGroupee').show();"
|
||||
disabled="#{empty participantBean.selectedParticipants}" />
|
||||
<p:commandButton value="Exporter sélection"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{participantBean.exporterSelection}"
|
||||
disabled="#{empty participantBean.selectedParticipants}" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Inscrire Membre -->
|
||||
<p:dialog header="Inscrire un Membre" widgetVar="dlgInscrireMembre" modal="true" width="600">
|
||||
<h:form id="formInscrireMembre">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="membreSelect" value="Sélectionner le membre" />
|
||||
<p:autoComplete id="membreSelect"
|
||||
value="#{participantBean.membreAInscrire}"
|
||||
completeMethod="#{participantBean.rechercherMembres}"
|
||||
var="membre" itemLabel="#{membre.nomComplet}" itemValue="#{membre}"
|
||||
converter="membreConverter"
|
||||
placeholder="Taper le nom du membre..."
|
||||
scrollHeight="200">
|
||||
<p:column>
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-2"
|
||||
style="width: 30px; height: 30px;">
|
||||
<span style="font-size: 0.8rem;">#{membre.initiales}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium">#{membre.nomComplet}</div>
|
||||
<small class="text-600">#{membre.numeroMembre} • #{membre.typeMembre}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:autoComplete>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="accompagnateursNb" value="Nombre d'accompagnateurs" />
|
||||
<p:inputNumber id="accompagnateursNb"
|
||||
value="#{participantBean.nombreAccompagnateursInscription}"
|
||||
symbol="" min="0" max="#{participantBean.maxAccompagnateurs}" />
|
||||
</div>
|
||||
|
||||
<div class="field" rendered="#{participantBean.evenement.payant}">
|
||||
<p:outputLabel value="Montant à payer" />
|
||||
<div class="font-bold text-2xl text-green-500">#{participantBean.montantAPayer} FCFA</div>
|
||||
<small class="text-600">#{participantBean.detailTarification}</small>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="commentaire" value="Commentaire" />
|
||||
<p:inputTextarea id="commentaire"
|
||||
value="#{participantBean.commentaireInscription}"
|
||||
rows="3" placeholder="Commentaire optionnel..." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Inscrire" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{participantBean.inscrireMembre}"
|
||||
update="@form :formParticipants"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgInscrireMembre').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgInscrireMembre').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Check-in Manuel -->
|
||||
<p:dialog header="Check-in Manuel" widgetVar="dlgCheckinManuel" modal="true" width="500">
|
||||
<h:form id="formCheckinManuel">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="participantCheckin" value="Participant" />
|
||||
<p:autoComplete id="participantCheckin"
|
||||
value="#{participantBean.participantCheckin}"
|
||||
completeMethod="#{participantBean.rechercherParticipants}"
|
||||
var="p" itemLabel="#{p.nomComplet}" itemValue="#{p}"
|
||||
converter="participantConverter"
|
||||
placeholder="Taper le nom du participant...">
|
||||
<p:column>
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-2"
|
||||
style="width: 30px; height: 30px;">
|
||||
<span style="font-size: 0.8rem;">#{p.initiales}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium">#{p.nomComplet}</div>
|
||||
<small class="text-600">#{p.numeroMembre}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:autoComplete>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="heureArrivee" value="Heure d'arrivée" />
|
||||
<p:calendar id="heureArrivee"
|
||||
value="#{participantBean.heureCheckin}"
|
||||
pattern="HH:mm" timeOnly="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Confirmer" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{participantBean.effectuerCheckinManuel}"
|
||||
update="@form :formParticipants"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgCheckinManuel').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgCheckinManuel').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Info Dernière Minute -->
|
||||
<p:dialog header="Information Dernière Minute" widgetVar="dlgInfoDernierMinute" modal="true" width="600">
|
||||
<h:form id="formInfoDernierMinute">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="sujetInfo" value="Sujet" />
|
||||
<p:inputText id="sujetInfo" value="#{participantBean.sujetInfo}"
|
||||
placeholder="Ex: Changement de lieu, horaire..." />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="messageInfo" value="Message" />
|
||||
<p:inputTextarea id="messageInfo" value="#{participantBean.messageInfo}"
|
||||
rows="4" placeholder="Votre message d'information..." />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="prioriteInfo" value="Priorité" />
|
||||
<p:selectOneMenu id="prioriteInfo" value="#{participantBean.prioriteInfo}">
|
||||
<f:selectItem itemLabel="🔴 Urgente" itemValue="URGENTE" />
|
||||
<f:selectItem itemLabel="🟡 Importante" itemValue="IMPORTANTE" />
|
||||
<f:selectItem itemLabel="🟢 Normale" itemValue="NORMALE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="envoyerSMS" value="#{participantBean.envoyerSMS}" />
|
||||
<p:outputLabel for="envoyerSMS" value=" Envoyer par SMS (recommandé pour urgent)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Envoyer" icon="pi pi-send"
|
||||
styleClass="ui-button-warning"
|
||||
action="#{participantBean.envoyerInfoDernierMinute}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgInfoDernierMinute').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgInfoDernierMinute').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,385 @@
|
||||
<!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">Caisse de l'Entité - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<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="pi pi-wallet text-purple-500 mr-2"></i>
|
||||
Caisse de l'Entité
|
||||
</h3>
|
||||
<p class="text-600 m-0">#{caisseBean.nomEntite} • Dernière mise à jour: #{caisseBean.derniereMAJ}</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouvelle entrée"
|
||||
icon="pi pi-plus-circle"
|
||||
styleClass="ui-button-success"
|
||||
onclick="PF('dlgNouvelleEntree').show();" />
|
||||
<p:commandButton value="Nouvelle sortie"
|
||||
icon="pi pi-minus-circle"
|
||||
styleClass="ui-button-danger"
|
||||
onclick="PF('dlgNouvelleSortie').show();" />
|
||||
<p:commandButton value="Rapprochement"
|
||||
icon="pi pi-sync"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{caisseBean.rapprochement}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Soldes et Statistiques -->
|
||||
<div class="formgrid grid">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Solde Principal" />
|
||||
<ui:param name="value" value="#{caisseBean.soldePrincipal}" />
|
||||
<ui:param name="icon" value="pi-wallet" />
|
||||
<ui:param name="iconColor" value="purple-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="Entrées (30j)" />
|
||||
<ui:param name="value" value="#{caisseBean.totalEntrees}" />
|
||||
<ui:param name="icon" value="pi-arrow-down" />
|
||||
<ui:param name="iconColor" value="green-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="Sorties (30j)" />
|
||||
<ui:param name="value" value="#{caisseBean.totalSorties}" />
|
||||
<ui:param name="icon" value="pi-arrow-up" />
|
||||
<ui:param name="iconColor" value="red-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="Wave Money" />
|
||||
<ui:param name="value" value="#{caisseBean.soldeWaveMoney}" />
|
||||
<ui:param name="icon" value="pi-mobile" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Graphiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<div class="card">
|
||||
<h5>Évolution du Solde</h5>
|
||||
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique temporaire</div></div><!--chart
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="card">
|
||||
<h5>Répartition par Catégorie</h5>
|
||||
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique temporaire</div></div><!--chart
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Journal de Caisse -->
|
||||
<div class="card">
|
||||
<h:form id="formCaisse">
|
||||
<h5>Journal de Caisse</h5>
|
||||
|
||||
<!-- Filtres -->
|
||||
<p:toolbar>
|
||||
<p:toolbarGroup>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<p:calendar id="dateDebut" value="#{caisseBean.dateDebut}"
|
||||
pattern="dd/MM/yyyy" showIcon="true"
|
||||
placeholder="Date début">
|
||||
<p:ajax event="dateSelect" update="dtMouvements" />
|
||||
</p:calendar>
|
||||
|
||||
<p:calendar id="dateFin" value="#{caisseBean.dateFin}"
|
||||
pattern="dd/MM/yyyy" showIcon="true"
|
||||
placeholder="Date fin">
|
||||
<p:ajax event="dateSelect" update="dtMouvements" />
|
||||
</p:calendar>
|
||||
|
||||
<p:selectOneMenu value="#{caisseBean.typeFilter}">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="Entrées" itemValue="ENTREE" />
|
||||
<f:selectItem itemLabel="Sorties" itemValue="SORTIE" />
|
||||
<p:ajax update="dtMouvements" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{caisseBean.categorieFilter}">
|
||||
<f:selectItem itemLabel="Toutes catégories" itemValue="" />
|
||||
<f:selectItem itemLabel="Cotisations" itemValue="COTISATION" />
|
||||
<f:selectItem itemLabel="Événements" itemValue="EVENEMENT" />
|
||||
<f:selectItem itemLabel="Aides" itemValue="AIDE" />
|
||||
<f:selectItem itemLabel="Frais admin" itemValue="FRAIS_ADMIN" />
|
||||
<f:selectItem itemLabel="Autres" itemValue="AUTRE" />
|
||||
<p:ajax update="dtMouvements" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</p:toolbarGroup>
|
||||
|
||||
<p:toolbarGroup align="right">
|
||||
<p:commandButton value="Imprimer"
|
||||
icon="pi pi-print"
|
||||
styleClass="ui-button-outlined ui-button-secondary mr-2"
|
||||
action="#{caisseBean.imprimer}" />
|
||||
<p:commandButton value="Exporter"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-outlined ui-button-success"
|
||||
action="#{caisseBean.exporter}" />
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
<!-- DataTable Mouvements -->
|
||||
<p:dataTable id="dtMouvements"
|
||||
var="mouvement"
|
||||
value="#{caisseBean.mouvements}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
rowKey="#{mouvement.id}"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column headerText="Date" sortBy="#{mouvement.date}" style="width:120px">
|
||||
<h:outputText value="#{mouvement.date}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy HH:mm" type="localDateTime" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{mouvement.reference}" style="width:120px">
|
||||
<h:outputText value="#{mouvement.reference}" styleClass="font-mono" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Libellé" sortBy="#{mouvement.libelle}">
|
||||
<h:outputText value="#{mouvement.libelle}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Catégorie" sortBy="#{mouvement.categorie}" style="width:150px">
|
||||
<p:tag value="#{mouvement.categorie}" styleClass="#{mouvement.categorieClass}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Entrée" style="width:120px">
|
||||
<h:outputText value="#{mouvement.montantEntree}"
|
||||
styleClass="text-green-600 font-bold"
|
||||
rendered="#{mouvement.type == 'ENTREE'}">
|
||||
<f:convertNumber type="currency" currencySymbol="+" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Sortie" style="width:120px">
|
||||
<h:outputText value="#{mouvement.montantSortie}"
|
||||
styleClass="text-red-600 font-bold"
|
||||
rendered="#{mouvement.type == 'SORTIE'}">
|
||||
<f:convertNumber type="currency" currencySymbol="-" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Solde" style="width:120px">
|
||||
<h:outputText value="#{mouvement.soldeApres}" styleClass="font-bold">
|
||||
<f:convertNumber type="currency" currencySymbol="" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Mode" style="width:100px">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi #{mouvement.modeIcon} mr-2"></i>
|
||||
<span>#{mouvement.modePaiement}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Validé" style="width:80px; text-align: center;">
|
||||
<i class="pi pi-check-circle text-green-500"
|
||||
rendered="#{mouvement.valide}"
|
||||
title="Validé le #{mouvement.dateValidation}" />
|
||||
<i class="pi pi-clock text-orange-500"
|
||||
rendered="#{!mouvement.valide}"
|
||||
title="En attente de validation" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:120px">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{caisseBean.validerMouvement(mouvement)}"
|
||||
title="Valider"
|
||||
rendered="#{!mouvement.valide}" />
|
||||
<p:commandButton icon="pi pi-file"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{caisseBean.voirJustificatif(mouvement)}"
|
||||
title="Justificatif" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
action="#{caisseBean.annulerMouvement(mouvement)}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler ce mouvement ?');"
|
||||
title="Annuler"
|
||||
rendered="#{!mouvement.valide}" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Totaux -->
|
||||
<div class="mt-3 p-3 surface-100 border-round">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="text-center">
|
||||
<div class="text-600">Total Entrées</div>
|
||||
<div class="text-2xl font-bold text-green-600">#{caisseBean.totalEntreesPeriode}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="text-center">
|
||||
<div class="text-600">Total Sorties</div>
|
||||
<div class="text-2xl font-bold text-red-600">#{caisseBean.totalSortiesPeriode}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="text-center">
|
||||
<div class="text-600">Solde Période</div>
|
||||
<div class="text-2xl font-bold text-purple-600">#{caisseBean.soldePeriode}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Entrée -->
|
||||
<p:dialog header="Nouvelle Entrée" widgetVar="dlgNouvelleEntree" modal="true" width="500">
|
||||
<h:form id="formNouvelleEntree">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="libelleEntree" value="Libellé" />
|
||||
<p:inputText id="libelleEntree" value="#{caisseBean.nouvelleEntree.libelle}" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="montantEntree" value="Montant" />
|
||||
<p:inputNumber id="montantEntree" value="#{caisseBean.nouvelleEntree.montant}"
|
||||
symbol=" FCFA" symbolPosition="s" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="categorieEntree" value="Catégorie" />
|
||||
<p:selectOneMenu id="categorieEntree" value="#{caisseBean.nouvelleEntree.categorie}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="Cotisations" itemValue="COTISATION" />
|
||||
<f:selectItem itemLabel="Événements" itemValue="EVENEMENT" />
|
||||
<f:selectItem itemLabel="Dons" itemValue="DON" />
|
||||
<f:selectItem itemLabel="Autres" itemValue="AUTRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="modeEntree" value="Mode de paiement" />
|
||||
<p:selectOneMenu id="modeEntree" value="#{caisseBean.nouvelleEntree.modePaiement}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="Wave Money" itemValue="WAVE" />
|
||||
<f:selectItem itemLabel="Virement" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="justificatifEntree" value="Justificatif" />
|
||||
<p:fileUpload id="justificatifEntree" mode="simple" skinSimple="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Enregistrer" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{caisseBean.enregistrerEntree}"
|
||||
update="@form :formCaisse"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgNouvelleEntree').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgNouvelleEntree').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Nouvelle Sortie -->
|
||||
<p:dialog header="Nouvelle Sortie" widgetVar="dlgNouvelleSortie" modal="true" width="500">
|
||||
<h:form id="formNouvelleSortie">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="libelleSortie" value="Libellé" />
|
||||
<p:inputText id="libelleSortie" value="#{caisseBean.nouvelleSortie.libelle}" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="montantSortie" value="Montant" />
|
||||
<p:inputNumber id="montantSortie" value="#{caisseBean.nouvelleSortie.montant}"
|
||||
symbol=" FCFA" symbolPosition="s" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="categorieSortie" value="Catégorie" />
|
||||
<p:selectOneMenu id="categorieSortie" value="#{caisseBean.nouvelleSortie.categorie}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="Aides" itemValue="AIDE" />
|
||||
<f:selectItem itemLabel="Frais administratifs" itemValue="FRAIS_ADMIN" />
|
||||
<f:selectItem itemLabel="Événements" itemValue="EVENEMENT" />
|
||||
<f:selectItem itemLabel="Autres" itemValue="AUTRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="beneficiaireSortie" value="Bénéficiaire" />
|
||||
<p:inputText id="beneficiaireSortie" value="#{caisseBean.nouvelleSortie.beneficiaire}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="modeSortie" value="Mode de paiement" />
|
||||
<p:selectOneMenu id="modeSortie" value="#{caisseBean.nouvelleSortie.modePaiement}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="Wave Money" itemValue="WAVE" />
|
||||
<f:selectItem itemLabel="Virement" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="justificatifSortie" value="Justificatif" />
|
||||
<p:fileUpload id="justificatifSortie" mode="simple" skinSimple="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Enregistrer" icon="pi pi-check"
|
||||
styleClass="ui-button-danger"
|
||||
action="#{caisseBean.enregistrerSortie}"
|
||||
update="@form :formCaisse"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgNouvelleSortie').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgNouvelleSortie').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,449 @@
|
||||
<!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">Rapports Financiers - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête -->
|
||||
<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="pi pi-chart-bar text-indigo-500 mr-2"></i>
|
||||
Rapports Financiers
|
||||
</h3>
|
||||
<p class="text-600 m-0">Analyse complète de la situation financière • #{rapportBean.periodeAnalyse}</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Générer rapport PDF"
|
||||
icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-danger"
|
||||
action="#{rapportBean.genererPDF}" />
|
||||
<p:commandButton value="Exporter Excel"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-success"
|
||||
action="#{rapportBean.exporterExcel}" />
|
||||
<p:commandButton value="Imprimer"
|
||||
icon="pi pi-print"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
onclick="window.print();" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sélection de période -->
|
||||
<div class="card">
|
||||
<h:form id="formPeriode">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<p:selectOneMenu value="#{rapportBean.typePeriode}" style="width: 200px;">
|
||||
<f:selectItem itemLabel="Cette année" itemValue="ANNEE" />
|
||||
<f:selectItem itemLabel="Ce trimestre" itemValue="TRIMESTRE" />
|
||||
<f:selectItem itemLabel="Ce mois" itemValue="MOIS" />
|
||||
<f:selectItem itemLabel="Période personnalisée" itemValue="CUSTOM" />
|
||||
<p:ajax update="@form :kpiPanel :graphsPanel :detailsPanel" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:calendar id="dateDebut" value="#{rapportBean.dateDebut}"
|
||||
pattern="dd/MM/yyyy" showIcon="true"
|
||||
placeholder="Date début"
|
||||
disabled="#{rapportBean.typePeriode != 'CUSTOM'}">
|
||||
<p:ajax event="dateSelect" update=":kpiPanel :graphsPanel :detailsPanel" />
|
||||
</p:calendar>
|
||||
|
||||
<p:calendar id="dateFin" value="#{rapportBean.dateFin}"
|
||||
pattern="dd/MM/yyyy" showIcon="true"
|
||||
placeholder="Date fin"
|
||||
disabled="#{rapportBean.typePeriode != 'CUSTOM'}">
|
||||
<p:ajax event="dateSelect" update=":kpiPanel :graphsPanel :detailsPanel" />
|
||||
</p:calendar>
|
||||
|
||||
<p:commandButton value="Actualiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{rapportBean.actualiser}"
|
||||
update=":kpiPanel :graphsPanel :detailsPanel" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- KPIs Financiers -->
|
||||
<h:panelGroup id="kpiPanel">
|
||||
<div class="formgrid grid">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Revenus Totaux" />
|
||||
<ui:param name="value" value="#{rapportBean.revenusTotaux}" />
|
||||
<ui:param name="icon" value="pi-dollar" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="growthValue" value="#{rapportBean.croissanceRevenus}" />
|
||||
<ui:param name="growthLabel" value="vs période précédente" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Dépenses Totales" />
|
||||
<ui:param name="value" value="#{rapportBean.depensesTotales}" />
|
||||
<ui:param name="icon" value="pi-shopping-cart" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="growthValue" value="#{rapportBean.croissanceDepenses}" />
|
||||
<ui:param name="growthLabel" value="vs période précédente" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Bénéfice Net" />
|
||||
<ui:param name="value" value="#{rapportBean.beneficeNet}" />
|
||||
<ui:param name="icon" value="pi-chart-line" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="progressValue" value="#{rapportBean.margePercentage}" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Trésorerie" />
|
||||
<ui:param name="value" value="#{rapportBean.tresorerie}" />
|
||||
<ui:param name="icon" value="pi-wallet" />
|
||||
<ui:param name="iconColor" value="purple-600" />
|
||||
<ui:param name="statusIcon" value="pi-info-circle" />
|
||||
<ui:param name="statusLabel" value="Jours d'autonomie" />
|
||||
<ui:param name="statusValue" value="#{rapportBean.joursAutonomie}" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
<!-- Graphiques -->
|
||||
<h:panelGroup id="graphsPanel">
|
||||
<div class="grid">
|
||||
<!-- Évolution Revenus/Dépenses -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Évolution Revenus vs Dépenses</h5>
|
||||
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique en cours de développement</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Répartition des Revenus -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Sources de Revenus</h5>
|
||||
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique en cours de développement</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Répartition des Dépenses -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Catégories de Dépenses</h5>
|
||||
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique en cours de développement</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cash Flow -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Cash Flow Mensuel</h5>
|
||||
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique en cours de développement</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
<!-- Analyse Détaillée -->
|
||||
<h:panelGroup id="detailsPanel">
|
||||
<div class="grid">
|
||||
<!-- Top Contributeurs -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Top 10 Contributeurs</h5>
|
||||
<ui:repeat value="#{rapportBean.topContributeurs}" var="contributeur" varStatus="status">
|
||||
<div class="flex align-items-center justify-content-between p-3 mb-2 border-round"
|
||||
style="background: var(--surface-50);">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-primary text-white border-round text-center mr-3"
|
||||
style="width: 2rem; height: 2rem; line-height: 2rem;">
|
||||
#{status.index + 1}
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium">#{contributeur.nom}</div>
|
||||
<small class="text-600">#{contributeur.numeroMembre}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="font-bold text-primary">#{contributeur.montantTotal}</div>
|
||||
<small class="text-600">#{contributeur.nombreContributions} contributions</small>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prévisions -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Prévisions Financières</h5>
|
||||
<div class="surface-50 p-3 border-round mb-3">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="font-medium">Revenus prévus (3 mois)</span>
|
||||
<span class="font-bold text-green-500">#{rapportBean.revenusPrevus3Mois}</span>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="font-medium">Dépenses prévues (3 mois)</span>
|
||||
<span class="font-bold text-orange-500">#{rapportBean.depensesPrevues3Mois}</span>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span class="font-medium">Solde prévisionnel</span>
|
||||
<span class="font-bold text-primary">#{rapportBean.soldePrevisionnel}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h6>Recommandations</h6>
|
||||
<ui:repeat value="#{rapportBean.recommandations}" var="recommandation">
|
||||
<div class="flex align-items-start mb-2">
|
||||
<i class="pi pi-lightbulb text-yellow-500 mr-2 mt-1"></i>
|
||||
<span>#{recommandation}</span>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tableau Détaillé des Transactions -->
|
||||
<div class="card">
|
||||
<h:form id="formTransactions">
|
||||
<h5>Détail des Transactions</h5>
|
||||
|
||||
<p:tabView>
|
||||
<p:tab title="Revenus">
|
||||
<p:dataTable var="revenu" value="#{rapportBean.detailRevenus}"
|
||||
paginator="true" rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}">
|
||||
|
||||
<p:column headerText="Date" sortBy="#{revenu.date}" style="width:120px">
|
||||
<h:outputText value="#{revenu.date}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Catégorie" sortBy="#{revenu.categorie}">
|
||||
<p:tag value="#{revenu.categorie}" styleClass="#{revenu.categorieClass}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Description" sortBy="#{revenu.description}">
|
||||
<h:outputText value="#{revenu.description}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{revenu.montant}" style="width:150px">
|
||||
<h:outputText value="#{revenu.montant}" styleClass="font-bold text-green-500">
|
||||
<f:convertNumber type="currency" currencySymbol="FCFA " />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Mode" style="width:120px">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi #{revenu.modeIcon} mr-2"></i>
|
||||
<span>#{revenu.modePaiement}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</p:tab>
|
||||
|
||||
<p:tab title="Dépenses">
|
||||
<p:dataTable var="depense" value="#{rapportBean.detailDepenses}"
|
||||
paginator="true" rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}">
|
||||
|
||||
<p:column headerText="Date" sortBy="#{depense.date}" style="width:120px">
|
||||
<h:outputText value="#{depense.date}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Catégorie" sortBy="#{depense.categorie}">
|
||||
<p:tag value="#{depense.categorie}" styleClass="#{depense.categorieClass}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Description" sortBy="#{depense.description}">
|
||||
<h:outputText value="#{depense.description}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Bénéficiaire" sortBy="#{depense.beneficiaire}">
|
||||
<h:outputText value="#{depense.beneficiaire}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{depense.montant}" style="width:150px">
|
||||
<h:outputText value="#{depense.montant}" styleClass="font-bold text-red-500">
|
||||
<f:convertNumber type="currency" currencySymbol="FCFA " />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Justificatif" style="width:100px; text-align:center;">
|
||||
<p:commandButton icon="pi pi-file"
|
||||
styleClass="ui-button-rounded ui-button-text"
|
||||
action="#{rapportBean.voirJustificatif(depense)}"
|
||||
rendered="#{depense.hasJustificatif}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Ratios et Indicateurs -->
|
||||
<div class="card">
|
||||
<h5>Indicateurs Clés de Performance</h5>
|
||||
<div class="formgrid grid">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Taux de Recouvrement" />
|
||||
<ui:param name="value" value="#{rapportBean.tauxRecouvrement}%" />
|
||||
<ui:param name="icon" value="pi-percentage" />
|
||||
<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="Ratio de Couverture" />
|
||||
<ui:param name="value" value="#{rapportBean.ratioCouverture}" />
|
||||
<ui:param name="icon" value="pi-shield" />
|
||||
<ui:param name="iconColor" value="green-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="Coût Moyen/Membre" />
|
||||
<ui:param name="value" value="#{rapportBean.coutMoyenMembre}" />
|
||||
<ui:param name="icon" value="pi-user-minus" />
|
||||
<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="Revenu Moyen/Membre" />
|
||||
<ui:param name="value" value="#{rapportBean.revenuMoyenMembre}" />
|
||||
<ui:param name="icon" value="pi-user-plus" />
|
||||
<ui:param name="iconColor" value="purple-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
<!-- Actions d'export -->
|
||||
<div class="card">
|
||||
<div class="flex justify-content-center gap-3">
|
||||
<p:commandButton value="Envoyer par email"
|
||||
icon="pi pi-envelope"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
onclick="PF('dlgEmail').show();" />
|
||||
<p:commandButton value="Programmer rapport automatique"
|
||||
icon="pi pi-calendar"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
onclick="PF('dlgProgrammer').show();" />
|
||||
<p:commandButton value="Archiver"
|
||||
icon="pi pi-save"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{rapportBean.archiver}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Email -->
|
||||
<p:dialog header="Envoyer le rapport par email" widgetVar="dlgEmail" modal="true" width="500">
|
||||
<h:form id="formEmail">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="destinataires" value="Destinataires" />
|
||||
<p:chips id="destinataires" value="#{rapportBean.destinataires}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="message" value="Message" />
|
||||
<p:inputTextarea id="message" value="#{rapportBean.messageEmail}" rows="5" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="inclurePDF" value="#{rapportBean.inclurePDF}" />
|
||||
<p:outputLabel for="inclurePDF" value=" Inclure le rapport PDF" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="inclureExcel" value="#{rapportBean.inclureExcel}" />
|
||||
<p:outputLabel for="inclureExcel" value=" Inclure le fichier Excel" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Envoyer" icon="pi pi-send"
|
||||
styleClass="ui-button-info"
|
||||
action="#{rapportBean.envoyerEmail}"
|
||||
oncomplete="PF('dlgEmail').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgEmail').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Programmer -->
|
||||
<p:dialog header="Programmer rapport automatique" widgetVar="dlgProgrammer" modal="true" width="500">
|
||||
<h:form id="formProgrammer">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="frequence" value="Fréquence" />
|
||||
<p:selectOneMenu id="frequence" value="#{rapportBean.frequence}">
|
||||
<f:selectItem itemLabel="Quotidien" itemValue="QUOTIDIEN" />
|
||||
<f:selectItem itemLabel="Hebdomadaire" itemValue="HEBDOMADAIRE" />
|
||||
<f:selectItem itemLabel="Mensuel" itemValue="MENSUEL" />
|
||||
<f:selectItem itemLabel="Trimestriel" itemValue="TRIMESTRIEL" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="jourEnvoi" value="Jour d'envoi" />
|
||||
<p:selectOneMenu id="jourEnvoi" value="#{rapportBean.jourEnvoi}">
|
||||
<f:selectItem itemLabel="Lundi" itemValue="1" />
|
||||
<f:selectItem itemLabel="Mardi" itemValue="2" />
|
||||
<f:selectItem itemLabel="Mercredi" itemValue="3" />
|
||||
<f:selectItem itemLabel="Jeudi" itemValue="4" />
|
||||
<f:selectItem itemLabel="Vendredi" itemValue="5" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="heureEnvoi" value="Heure d'envoi" />
|
||||
<p:inputText id="heureEnvoi" value="#{rapportBean.heureEnvoi}" placeholder="09:00" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="destinatairesProg" value="Destinataires" />
|
||||
<p:chips id="destinatairesProg" value="#{rapportBean.destinatairesProgrammes}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Programmer" icon="pi pi-check"
|
||||
styleClass="ui-button-warning"
|
||||
action="#{rapportBean.programmerRapport}"
|
||||
oncomplete="PF('dlgProgrammer').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgProgrammer').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,566 @@
|
||||
<!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">Rapports et Statistiques - 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-chart-bar text-blue-500 mr-2"></i>
|
||||
Rapports et Statistiques
|
||||
</h2>
|
||||
<p class="text-600 mt-0">Analyse des données et indicateurs de performance</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="Générer"
|
||||
icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-success ui-button-sm w-full"
|
||||
onclick="PF('dlgGenererRapport').show();" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:commandButton value="Planifier"
|
||||
icon="pi pi-calendar-plus"
|
||||
styleClass="ui-button-info ui-button-outlined ui-button-sm w-full"
|
||||
onclick="PF('dlgPlanifierRapport').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="#{rapportsBean.exporterDonnees}" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sélecteur de période 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-calendar text-blue-500 mr-2"></i>
|
||||
Période d'Analyse
|
||||
</h5>
|
||||
<h:form id="formPeriode">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="periodeRapide" value="Période rapide" />
|
||||
<p:selectOneMenu id="periodeRapide" value="#{rapportsBean.periodeRapide}">
|
||||
<f:selectItem itemLabel="Personnalisée" itemValue="" />
|
||||
<f:selectItem itemLabel="7 derniers jours" itemValue="7_JOURS" />
|
||||
<f:selectItem itemLabel="30 derniers jours" itemValue="30_JOURS" />
|
||||
<f:selectItem itemLabel="3 derniers mois" itemValue="3_MOIS" />
|
||||
<f:selectItem itemLabel="6 derniers mois" itemValue="6_MOIS" />
|
||||
<f:selectItem itemLabel="Cette année" itemValue="ANNEE_COURANTE" />
|
||||
<f:selectItem itemLabel="Année dernière" itemValue="ANNEE_PRECEDENTE" />
|
||||
<p:ajax update="@form :indicateursGlobaux :graphiquesEvolution" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="dateDebut" value="Date début" />
|
||||
<p:datePicker id="dateDebut" value="#{rapportsBean.dateDebut}"
|
||||
placeholder="Date de début">
|
||||
<p:ajax update=":indicateursGlobaux :graphiquesEvolution" />
|
||||
</p:datePicker>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="dateFin" value="Date fin" />
|
||||
<p:datePicker id="dateFin" value="#{rapportsBean.dateFin}"
|
||||
placeholder="Date de fin">
|
||||
<p:ajax update=":indicateursGlobaux :graphiquesEvolution" />
|
||||
</p:datePicker>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<p:outputLabel for="groupeComparaison" value="Comparer avec" />
|
||||
<p:selectOneMenu id="groupeComparaison" value="#{rapportsBean.groupeComparaison}">
|
||||
<f:selectItem itemLabel="Aucune comparaison" itemValue="" />
|
||||
<f:selectItem itemLabel="Période précédente" itemValue="PERIODE_PRECEDENTE" />
|
||||
<f:selectItem itemLabel="Même période année passée" itemValue="ANNEE_PASSEE" />
|
||||
<f:selectItem itemLabel="Moyenne historique" itemValue="MOYENNE_HISTORIQUE" />
|
||||
<p:ajax update=":indicateursGlobaux" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Indicateurs globaux avec Freya stricte -->
|
||||
<p:outputPanel id="indicateursGlobaux">
|
||||
<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 Membres</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">#{rapportsBean.indicateurs.totalMembres}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<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">+#{rapportsBean.indicateurs.croissanceMembres}%</span>
|
||||
<span class="text-500 text-xs">ce mois</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">Revenus Total</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-dollar text-green-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{rapportsBean.indicateurs.revenus}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<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">+#{rapportsBean.indicateurs.croissanceRevenus}%</span>
|
||||
<span class="text-500 text-xs">ce mois</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">Événements</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-calendar text-orange-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{rapportsBean.indicateurs.totalEvenements}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<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">+#{rapportsBean.indicateurs.croissanceEvenements}%</span>
|
||||
<span class="text-500 text-xs">ce mois</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">Aides Accordées</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-heart text-purple-600 text-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-3">#{rapportsBean.indicateurs.totalAides}</div>
|
||||
<div class="flex align-items-center mb-2">
|
||||
<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">+#{rapportsBean.indicateurs.croissanceAides}%</span>
|
||||
<span class="text-500 text-xs">ce mois</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:outputPanel>
|
||||
|
||||
<!-- Graphiques d'évolution avec Freya stricte -->
|
||||
<p:outputPanel id="graphiquesEvolution">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-8">
|
||||
<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-chart-line text-blue-500 mr-2"></i>
|
||||
Évolution des Membres et Revenus
|
||||
</h5>
|
||||
<div class="surface-100 border-round-lg p-4">
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{rapportsBean.evolutionMensuelle}" var="mois" varStatus="status">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="text-center">
|
||||
<div class="text-600 text-sm mb-2">#{mois.libelle}</div>
|
||||
<div class="flex flex-column align-items-center gap-2">
|
||||
<div class="bg-blue-500 border-round" style="width: 20px; height: #{mois.hauteurMembres}px;"></div>
|
||||
<div class="text-blue-700 font-bold text-sm">#{mois.membres}</div>
|
||||
<div class="bg-green-500 border-round" style="width: 20px; height: #{mois.hauteurRevenus}px;"></div>
|
||||
<div class="text-green-700 font-bold text-xs">#{mois.revenus}M</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
<div class="flex justify-content-center gap-4 mt-3">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-blue-500 border-round mr-2" style="width: 12px; height: 12px;"></div>
|
||||
<span class="text-600 text-sm">Membres</span>
|
||||
</div>
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-green-500 border-round mr-2" style="width: 12px; height: 12px;"></div>
|
||||
<span class="text-600 text-sm">Revenus (M FCFA)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-4">
|
||||
<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-target text-green-500 mr-2"></i>
|
||||
Objectifs vs Réalisations
|
||||
</h5>
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{rapportsBean.objectifs}" var="objectif" varStatus="status">
|
||||
<div class="col-12">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-900 font-medium">#{objectif.libelle}</span>
|
||||
<span class="text-600 text-sm">#{objectif.pourcentage}%</span>
|
||||
</div>
|
||||
<p:progressBar value="#{objectif.pourcentage}" style="height: 8px;"
|
||||
styleClass="mb-3">
|
||||
<f:facet name="label">#{objectif.pourcentage}%</f:facet>
|
||||
</p:progressBar>
|
||||
<div class="flex justify-content-between text-xs text-600 mb-3">
|
||||
<span>Réalisé: #{objectif.realise}</span>
|
||||
<span>Objectif: #{objectif.cible}</span>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:outputPanel>
|
||||
|
||||
<!-- Répartitions et analyses avec Freya stricte -->
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-6">
|
||||
<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-users text-purple-500 mr-2"></i>
|
||||
Répartition des Membres
|
||||
</h5>
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{rapportsBean.repartitionMembres}" var="categorie" varStatus="status">
|
||||
<div class="col-12">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-#{categorie.couleur} border-round mr-3"
|
||||
style="width: 12px; height: 12px;"></div>
|
||||
<span class="text-900">#{categorie.libelle}</span>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-900 font-bold">#{categorie.nombre}</div>
|
||||
<div class="text-600 text-sm">#{categorie.pourcentage}%</div>
|
||||
</div>
|
||||
</div>
|
||||
<p:progressBar value="#{categorie.pourcentage}" style="height: 6px;"
|
||||
styleClass="mb-3" />
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<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-dollar text-green-500 mr-2"></i>
|
||||
Analyse des Revenus
|
||||
</h5>
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{rapportsBean.sourceRevenus}" var="source" varStatus="status">
|
||||
<div class="col-12">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-#{source.couleur} text-white border-round flex align-items-center justify-content-center mr-3"
|
||||
style="width: 2rem; height: 2rem;">
|
||||
<i class="pi #{source.icon} text-sm"></i>
|
||||
</div>
|
||||
<span class="text-900">#{source.libelle}</span>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-900 font-bold">#{source.montant}</div>
|
||||
<div class="text-600 text-sm">#{source.pourcentage}%</div>
|
||||
</div>
|
||||
</div>
|
||||
<p:progressBar value="#{source.pourcentage}" style="height: 6px;"
|
||||
styleClass="mb-3" />
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tableaux de performance avec Freya stricte -->
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-6">
|
||||
<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-trophy text-yellow-500 mr-2"></i>
|
||||
Top Entités Performantes
|
||||
</h5>
|
||||
<p:dataTable value="#{rapportsBean.topEntites}" var="entite"
|
||||
styleClass="p-datatable-sm"
|
||||
emptyMessage="Aucune donnée disponible">
|
||||
|
||||
<p:column headerText="Rang" width="60">
|
||||
<div class="text-center">
|
||||
<p:tag value="#{entite.rang}"
|
||||
severity="#{entite.rang == 1 ? 'warning' : (entite.rang le 3 ? 'info' : 'secondary')}" />
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Entité">
|
||||
<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: 24px; height: 24px;">
|
||||
<i class="pi #{entite.typeIcon} text-xs"></i>
|
||||
</div>
|
||||
<span class="text-900 font-medium">#{entite.nom}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Score" width="80">
|
||||
<div class="text-center">
|
||||
<span class="text-900 font-bold">#{entite.score}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Évolution" width="80">
|
||||
<div class="text-center">
|
||||
<i class="pi #{entite.tendance == 'UP' ? 'pi-arrow-up text-green-500' : (entite.tendance == 'DOWN' ? 'pi-arrow-down text-red-500' : 'pi-minus text-600')}"></i>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<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-chart-bar text-blue-500 mr-2"></i>
|
||||
Indicateurs Clés de Performance
|
||||
</h5>
|
||||
<div class="formgrid grid">
|
||||
<ui:repeat value="#{rapportsBean.kpis}" var="kpi" varStatus="status">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="#{kpi.libelle}" />
|
||||
<ui:param name="value" value="#{kpi.valeur}" />
|
||||
<ui:param name="icon" value="#{kpi.icon}" />
|
||||
<ui:param name="iconColor" value="#{kpi.couleur}" />
|
||||
<ui:param name="growthValue" value="#{kpi.variation}" />
|
||||
<ui:param name="growthLabel" value="variation" />
|
||||
<ui:param name="progressValue" value="#{kpi.progression}" />
|
||||
<ui:param name="colSize" value="col-12" />
|
||||
</ui:include>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alertes et recommandations 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-exclamation-triangle text-orange-500 mr-2"></i>
|
||||
Alertes et Recommandations
|
||||
</h5>
|
||||
<div class="formgrid grid">
|
||||
<ui:repeat value="#{rapportsBean.alertes}" var="alerte" varStatus="status">
|
||||
<div class="field col-12 md:col-6">
|
||||
<div class="surface-100 border-round-lg p-3 hover:surface-200 transition-colors transition-duration-150 border-left-3 border-#{alerte.severiteCouleur}">
|
||||
<div class="flex align-items-start">
|
||||
<div class="bg-#{alerte.severiteCouleur} text-white border-round flex align-items-center justify-content-center mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi #{alerte.icon}"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 m-0 mb-2">#{alerte.titre}</h6>
|
||||
<div class="text-600 mb-2 text-sm">#{alerte.description}</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<p:tag value="#{alerte.priorite}" severity="#{alerte.severite}" />
|
||||
<span class="text-600 text-xs">#{alerte.dateDetection}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historique des rapports 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-file-text text-blue-500 mr-2"></i>
|
||||
Historique des Rapports
|
||||
</h5>
|
||||
<p:dataTable value="#{rapportsBean.historiqueRapports}" var="rapport"
|
||||
paginator="true" rows="10"
|
||||
styleClass="p-datatable-sm"
|
||||
emptyMessage="Aucun rapport généré">
|
||||
|
||||
<p:column headerText="Date génération" sortBy="#{rapport.dateGeneration}" width="150">
|
||||
<span class="text-900">#{rapport.dateGenerationFormatee}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type de rapport">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi #{rapport.typeIcon} text-#{rapport.typeCouleur} mr-2"></i>
|
||||
<span class="text-900">#{rapport.typeLibelle}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Période couverte" width="200">
|
||||
<span class="text-600">#{rapport.periodeCouverte}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Généré par" width="150">
|
||||
<span class="text-900">#{rapport.generePar}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" width="100">
|
||||
<p:tag value="#{rapport.statut}" severity="#{rapport.statutSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" width="120">
|
||||
<h:form>
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
title="Voir le rapport"
|
||||
action="#{rapportsBean.voirRapport(rapport)}" />
|
||||
<p:commandButton icon="pi pi-download"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
title="Télécharger"
|
||||
action="#{rapportsBean.telechargerRapport(rapport)}" />
|
||||
<p:commandButton icon="pi pi-share-alt"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-primary"
|
||||
title="Partager"
|
||||
onclick="PF('dlgPartagerRapport').show();">
|
||||
<f:setPropertyActionListener target="#{rapportsBean.rapportSelectionne}" value="#{rapport}" />
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Générer Rapport avec Freya stricte -->
|
||||
<p:dialog header="Générer un Nouveau Rapport" widgetVar="dlgGenererRapport" modal="true" width="600">
|
||||
<h:form id="formGenererRapport">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="typeRapport" value="Type de rapport" />
|
||||
<p:selectOneMenu id="typeRapport" value="#{rapportsBean.nouveauRapport.type}" required="true">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="📊 Rapport Financier" itemValue="FINANCIER" />
|
||||
<f:selectItem itemLabel="👥 Rapport Membres" itemValue="MEMBRES" />
|
||||
<f:selectItem itemLabel="📅 Rapport Activités" itemValue="ACTIVITES" />
|
||||
<f:selectItem itemLabel="🎯 Rapport Performance" itemValue="PERFORMANCE" />
|
||||
<f:selectItem itemLabel="📈 Rapport Complet" itemValue="COMPLET" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="formatRapport" value="Format de sortie" />
|
||||
<p:selectOneMenu id="formatRapport" value="#{rapportsBean.nouveauRapport.format}">
|
||||
<f:selectItem itemLabel="PDF" itemValue="PDF" />
|
||||
<f:selectItem itemLabel="Excel" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="PowerPoint" itemValue="POWERPOINT" />
|
||||
<f:selectItem itemLabel="HTML" itemValue="HTML" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="periodeRapport" value="Période du rapport" />
|
||||
<p:selectOneMenu id="periodeRapport" value="#{rapportsBean.nouveauRapport.periode}">
|
||||
<f:selectItem itemLabel="7 derniers jours" itemValue="7_JOURS" />
|
||||
<f:selectItem itemLabel="30 derniers jours" itemValue="30_JOURS" />
|
||||
<f:selectItem itemLabel="3 derniers mois" itemValue="3_MOIS" />
|
||||
<f:selectItem itemLabel="6 derniers mois" itemValue="6_MOIS" />
|
||||
<f:selectItem itemLabel="Cette année" itemValue="ANNEE_COURANTE" />
|
||||
<f:selectItem itemLabel="Personnalisée" itemValue="PERSONNALISEE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="niveauDetail" value="Niveau de détail" />
|
||||
<p:selectOneMenu id="niveauDetail" value="#{rapportsBean.nouveauRapport.detail}">
|
||||
<f:selectItem itemLabel="Résumé exécutif" itemValue="RESUME" />
|
||||
<f:selectItem itemLabel="Standard" itemValue="STANDARD" />
|
||||
<f:selectItem itemLabel="Détaillé" itemValue="DETAILLE" />
|
||||
<f:selectItem itemLabel="Complet avec annexes" itemValue="COMPLET" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="commentairesRapport" value="Commentaires et notes" />
|
||||
<p:inputTextarea id="commentairesRapport" value="#{rapportsBean.nouveauRapport.commentaires}"
|
||||
rows="3" placeholder="Ajouter des commentaires ou instructions spécifiques..." />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Générer maintenant" icon="pi pi-play"
|
||||
styleClass="ui-button-success"
|
||||
action="#{rapportsBean.genererRapport}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgGenererRapport').hide();" />
|
||||
<p:commandButton value="Programmer" icon="pi pi-calendar"
|
||||
styleClass="ui-button-info"
|
||||
onclick="PF('dlgGenererRapport').hide(); PF('dlgPlanifierRapport').show();"
|
||||
type="button" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgGenererRapport').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
20
target/classes/META-INF/resources/pages/admin/settings.xhtml
Normal file
20
target/classes/META-INF/resources/pages/admin/settings.xhtml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!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">UnionFlow - Administration Settings</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h2>Administration - Settings</h2>
|
||||
<p>Page d'administration en cours de développement...</p>
|
||||
<p:button value="Retour" icon="pi pi-arrow-left" outcome="/pages/secure/dashboard"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
20
target/classes/META-INF/resources/pages/admin/users.xhtml
Normal file
20
target/classes/META-INF/resources/pages/admin/users.xhtml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!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">UnionFlow - Administration Users</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h2>Administration - Users</h2>
|
||||
<p>Page d'administration en cours de développement...</p>
|
||||
<p:button value="Retour" icon="pi pi-arrow-left" outcome="/pages/secure/dashboard"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,398 @@
|
||||
<!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>
|
||||
Reference in New Issue
Block a user