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>
|
||||
575
target/classes/META-INF/resources/pages/membre/cotisations.xhtml
Normal file
575
target/classes/META-INF/resources/pages/membre/cotisations.xhtml
Normal file
@@ -0,0 +1,575 @@
|
||||
<!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">Mes Cotisations - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête personnalisé -->
|
||||
<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-dollar text-green-500 mr-2"></i>
|
||||
Mes Cotisations
|
||||
</h3>
|
||||
<p class="text-600 m-0">Membre #{membreCotisationBean.numeroMembre} • Statut: #{membreCotisationBean.statutCotisations} • Dernière mise à jour: #{membreCotisationBean.derniereMAJ}</p>
|
||||
</div>
|
||||
<h:form id="formActions">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Payer maintenant"
|
||||
icon="pi pi-credit-card"
|
||||
styleClass="ui-button-success"
|
||||
onclick="PF('dlgPaiement').show();"
|
||||
rendered="#{membreCotisationBean.peutPayer}" />
|
||||
<p:commandButton value="Historique complet"
|
||||
icon="pi pi-history"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{membreCotisationBean.voirHistoriqueComplet}" />
|
||||
<p:commandButton value="Télécharger reçus"
|
||||
icon="pi pi-download"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{membreCotisationBean.telechargerRecus}" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Résumé cotisations -->
|
||||
<div class="grid">
|
||||
<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">#{membreCotisationBean.cotisationsPayees}</div>
|
||||
<div class="text-green-700">Cotisations Payé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 class="mt-2">
|
||||
<p:progressBar value="#{membreCotisationBean.progressionAnnuelle}"
|
||||
labelTemplate="#{membreCotisationBean.progressionAnnuelle}% de l'année"
|
||||
styleClass="h-1rem" />
|
||||
</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">#{membreCotisationBean.cotisationsEnAttente}</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">#{membreCotisationBean.montantDu}</div>
|
||||
<div class="text-red-700">Montant Dû</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-blue-100 border-left-3 border-blue-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-blue-900 font-bold text-2xl">#{membreCotisationBean.totalVerse}</div>
|
||||
<div class="text-blue-700">Total Versé 2024</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-dollar text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prochaines échéances -->
|
||||
<div class="card" rendered="#{not empty membreCotisationBean.prochainesEcheances}">
|
||||
<h5>
|
||||
<i class="pi pi-calendar text-orange-500 mr-2"></i>
|
||||
Prochaines Échéances
|
||||
</h5>
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{membreCotisationBean.prochainesEcheances}" var="echeance" varStatus="status">
|
||||
<div class="col-12 md:col-6 lg:col-4">
|
||||
<div class="surface-card border-round p-3 border-left-3 #{echeance.couleurUrgence}">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<div>
|
||||
<div class="font-medium text-900">#{echeance.libelle}</div>
|
||||
<small class="text-600">#{echeance.periode}</small>
|
||||
</div>
|
||||
<p:tag value="#{echeance.urgence}" severity="#{echeance.urgenceSeverity}" />
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<div class="font-bold text-2xl #{echeance.couleurMontant}">#{echeance.montant}</div>
|
||||
<small class="text-600">Échéance: #{echeance.dateEcheance}</small>
|
||||
</div>
|
||||
<h:form id="formEcheance#{status.index}">
|
||||
<p:commandButton icon="pi pi-credit-card"
|
||||
styleClass="ui-button-rounded ui-button-success"
|
||||
action="#{membreCotisationBean.payerCotisation(echeance)}"
|
||||
title="Payer maintenant" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Graphiques et analyses -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<div class="card">
|
||||
<h5>Historique des Paiements</h5>
|
||||
<div class="grid">
|
||||
<div class="col-3">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-lg font-bold text-green-500 mb-1">Jan-Mar</div>
|
||||
<div class="text-sm text-600">15,000 FCFA</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-lg font-bold text-blue-500 mb-1">Avr-Juin</div>
|
||||
<div class="text-sm text-600">15,000 FCFA</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-lg font-bold text-purple-500 mb-1">Jul-Sep</div>
|
||||
<div class="text-sm text-600">15,000 FCFA</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-lg font-bold text-orange-500 mb-1">Oct-Déc</div>
|
||||
<div class="text-sm text-600">10,000 FCFA</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="surface-100 p-3 border-round mt-3 text-center">
|
||||
<div class="text-2xl font-bold text-primary">55,000 FCFA</div>
|
||||
<div class="text-600">Total versé en 2024</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="card">
|
||||
<h5>Ma Situation</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">Statut Membre</span>
|
||||
<p:tag value="#{membreCotisationBean.statutMembre}"
|
||||
severity="#{membreCotisationBean.statutSeverity}" />
|
||||
</div>
|
||||
<div class="text-sm text-600">Type: #{membreCotisationBean.typeMembre}</div>
|
||||
</div>
|
||||
|
||||
<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">Cotisation Mensuelle</span>
|
||||
<span class="font-bold text-green-500">#{membreCotisationBean.cotisationMensuelle}</span>
|
||||
</div>
|
||||
<div class="text-sm text-600">Basée sur votre type de membre</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="font-medium">Ponctualité</span>
|
||||
<span class="font-bold text-blue-500">#{membreCotisationBean.scorePonctualite}%</span>
|
||||
</div>
|
||||
<p:progressBar value="#{membreCotisationBean.scorePonctualite}"
|
||||
labelTemplate=""
|
||||
styleClass="h-1rem mt-1" />
|
||||
<div class="text-sm text-600 mt-1">#{membreCotisationBean.commentairePonctualite}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Moyens de paiement -->
|
||||
<div class="card">
|
||||
<h5>Moyens de Paiement</h5>
|
||||
|
||||
<div class="flex flex-column gap-2">
|
||||
<div class="surface-50 p-3 border-round flex align-items-center">
|
||||
<i class="pi pi-mobile text-blue-500 text-xl mr-3"></i>
|
||||
<div>
|
||||
<div class="font-medium">Wave Money</div>
|
||||
<small class="text-600">Paiement mobile instantané</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round flex align-items-center">
|
||||
<i class="pi pi-money-bill text-green-500 text-xl mr-3"></i>
|
||||
<div>
|
||||
<div class="font-medium">Espèces</div>
|
||||
<small class="text-600">Paiement auprès du trésorier</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round flex align-items-center">
|
||||
<i class="pi pi-building text-purple-500 text-xl mr-3"></i>
|
||||
<div>
|
||||
<div class="font-medium">Virement Bancaire</div>
|
||||
<small class="text-600">Transfert vers compte association</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historique détaillé -->
|
||||
<div class="card">
|
||||
<h:form id="formCotisations">
|
||||
<h5>Historique de mes Cotisations</h5>
|
||||
|
||||
<!-- Filtres -->
|
||||
<p:toolbar>
|
||||
<p:toolbarGroup>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<p:selectOneMenu value="#{membreCotisationBean.anneeFilter}">
|
||||
<f:selectItem itemLabel="Cette année" itemValue="2024" />
|
||||
<f:selectItem itemLabel="2023" itemValue="2023" />
|
||||
<f:selectItem itemLabel="2022" itemValue="2022" />
|
||||
<f:selectItem itemLabel="Toutes" itemValue="" />
|
||||
<p:ajax update="dtCotisations" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{membreCotisationBean.statutFilter}">
|
||||
<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" />
|
||||
<p:ajax update="dtCotisations" />
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{membreCotisationBean.typeFilter}">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Cotisation mensuelle" itemValue="MENSUELLE" />
|
||||
<f:selectItem itemLabel="Cotisation spéciale" itemValue="SPECIALE" />
|
||||
<f:selectItem itemLabel="Frais adhésion" itemValue="ADHESION" />
|
||||
<p:ajax update="dtCotisations" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</p:toolbarGroup>
|
||||
|
||||
<p:toolbarGroup align="right">
|
||||
<p:commandButton icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{membreCotisationBean.actualiser}"
|
||||
update="@form"
|
||||
title="Actualiser" />
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtCotisations"
|
||||
var="cotisation"
|
||||
value="#{membreCotisationBean.cotisations}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{cotisation.reference}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.reference}" styleClass="font-mono font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Période" sortBy="#{cotisation.periode}">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.libelle}</div>
|
||||
<small class="text-600">#{cotisation.periode}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{cotisation.type}" style="width:140px">
|
||||
<p:tag value="#{cotisation.type}"
|
||||
severity="#{cotisation.typeSeverity}"
|
||||
icon="pi #{cotisation.typeIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{cotisation.montant}" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-green-500">#{cotisation.montant}</div>
|
||||
<small class="text-600">FCFA</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{cotisation.statut}" style="width:120px">
|
||||
<p:tag value="#{cotisation.statut}"
|
||||
severity="#{cotisation.statutSeverity}"
|
||||
icon="pi #{cotisation.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Échéance" sortBy="#{cotisation.dateEcheance}" style="width:120px">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.dateEcheance}</div>
|
||||
<small class="#{cotisation.retardColor}">#{cotisation.statutEcheance}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date paiement" sortBy="#{cotisation.datePaiement}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.datePaiement}" rendered="#{cotisation.datePaiement != null}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
<span class="text-400" rendered="#{cotisation.datePaiement == null}">Non payée</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Mode paiement" style="width:130px">
|
||||
<div class="flex align-items-center" rendered="#{cotisation.modePaiement != null}">
|
||||
<i class="pi #{cotisation.modePaiementIcon} mr-2"></i>
|
||||
<span>#{cotisation.modePaiement}</span>
|
||||
</div>
|
||||
<span class="text-400" rendered="#{cotisation.modePaiement == null}">-</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-credit-card"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{membreCotisationBean.payerCotisation(cotisation)}"
|
||||
title="Payer"
|
||||
rendered="#{cotisation.statut != 'PAYE'}" />
|
||||
<p:commandButton icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{membreCotisationBean.telechargerRecu(cotisation)}"
|
||||
title="Télécharger reçu"
|
||||
rendered="#{cotisation.statut == 'PAYE'}" />
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
action="#{membreCotisationBean.voirDetails(cotisation)}"
|
||||
title="Voir détails" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Résumé en bas -->
|
||||
<div class="mt-3 p-3 surface-100 border-round">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center">
|
||||
<div class="text-600">Total Payé</div>
|
||||
<div class="text-2xl font-bold text-green-600">#{membreCotisationBean.totalPayePeriode}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center">
|
||||
<div class="text-600">En Attente</div>
|
||||
<div class="text-2xl font-bold text-orange-600">#{membreCotisationBean.totalEnAttentePeriode}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center">
|
||||
<div class="text-600">En Retard</div>
|
||||
<div class="text-2xl font-bold text-red-600">#{membreCotisationBean.totalEnRetardPeriode}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center">
|
||||
<div class="text-600">Taux Conformité</div>
|
||||
<div class="text-2xl font-bold text-blue-600">#{membreCotisationBean.tauxConformite}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Paiement -->
|
||||
<p:dialog header="Effectuer un Paiement" widgetVar="dlgPaiement" modal="true" width="600">
|
||||
<h:form id="formPaiement">
|
||||
<div class="ui-fluid">
|
||||
<div class="surface-50 p-3 border-round mb-3">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-info-circle text-blue-500 mr-2"></i>
|
||||
<div>
|
||||
<div class="font-medium">Paiement sécurisé</div>
|
||||
<div class="text-600 text-sm">Toutes les transactions sont cryptées et sécurisées</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="cotisationAPayer" value="Cotisation à payer" />
|
||||
<p:selectOneMenu id="cotisationAPayer" value="#{membreCotisationBean.cotisationSelectionnee}">
|
||||
<f:selectItems value="#{membreCotisationBean.cotisationsImpayees}"
|
||||
var="cot"
|
||||
itemLabel="#{cot.libelle} - #{cot.montant} FCFA (#{cot.dateEcheance})"
|
||||
itemValue="#{cot}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="modePaiement" value="Mode de paiement" />
|
||||
<p:selectOneMenu id="modePaiement" value="#{membreCotisationBean.modePaiementChoisi}">
|
||||
<f:selectItem itemLabel="📱 Wave Money" itemValue="WAVE" />
|
||||
<f:selectItem itemLabel="🏦 Virement bancaire" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="💰 Remise directe" itemValue="ESPECES" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field" rendered="#{membreCotisationBean.modePaiementChoisi == 'WAVE'}">
|
||||
<p:outputLabel for="numeroWave" value="Numéro Wave Money" />
|
||||
<p:inputText id="numeroWave" value="#{membreCotisationBean.numeroWave}"
|
||||
placeholder="77 123 45 67" />
|
||||
</div>
|
||||
|
||||
<div class="field" rendered="#{membreCotisationBean.modePaiementChoisi == 'VIREMENT'}">
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Coordonnées bancaires</div>
|
||||
<div class="text-sm text-600">
|
||||
<div>Banque: #{membreCotisationBean.banqueAssociation}</div>
|
||||
<div>IBAN: #{membreCotisationBean.ibanAssociation}</div>
|
||||
<div>Référence: [Votre numéro membre]</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="commentairePaiement" value="Commentaire (optionnel)" />
|
||||
<p:inputTextarea id="commentairePaiement" value="#{membreCotisationBean.commentairePaiement}"
|
||||
rows="2" placeholder="Remarques sur ce paiement..." />
|
||||
</div>
|
||||
|
||||
<div class="surface-100 p-3 border-round">
|
||||
<div class="flex justify-content-between align-items-center">
|
||||
<span class="font-medium">Montant total:</span>
|
||||
<span class="font-bold text-2xl text-green-500">#{membreCotisationBean.montantAPayer} FCFA</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Confirmer le paiement" icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
action="#{membreCotisationBean.confirmerPaiement}"
|
||||
update="@form :formCotisations"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgPaiement').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgPaiement').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Actions rapides -->
|
||||
<div class="card">
|
||||
<h:form id="formActionsRapides">
|
||||
<div class="flex flex-wrap gap-2 justify-content-center">
|
||||
<p:commandButton value="📱 Paiement Wave Money"
|
||||
icon="pi pi-mobile"
|
||||
styleClass="ui-button-success"
|
||||
action="#{membreCotisationBean.paiementWave}"
|
||||
rendered="#{membreCotisationBean.peutPayerWave}" />
|
||||
<p:commandButton value="📄 Générer attestation"
|
||||
icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{membreCotisationBean.genererAttestation}" />
|
||||
<p:commandButton value="📧 Demander reçu"
|
||||
icon="pi pi-envelope"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{membreCotisationBean.demanderRecu}" />
|
||||
<p:commandButton value="💰 Prélèvement automatique"
|
||||
icon="pi pi-sync"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
onclick="PF('dlgPrelevementAuto').show();" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Prélèvement Automatique -->
|
||||
<p:dialog header="Prélèvement Automatique" widgetVar="dlgPrelevementAuto" modal="true" width="500">
|
||||
<h:form id="formPrelevementAuto">
|
||||
<div class="ui-fluid">
|
||||
<div class="surface-50 p-3 border-round mb-3">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-shield text-green-500 mr-2"></i>
|
||||
<div>
|
||||
<div class="font-medium">Service sécurisé</div>
|
||||
<div class="text-600 text-sm">Vos cotisations seront automatiquement prélevées chaque mois</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="numeroWaveAuto" value="Numéro Wave Money" />
|
||||
<p:inputText id="numeroWaveAuto" value="#{membreCotisationBean.numeroWaveAuto}"
|
||||
placeholder="77 123 45 67" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="jourPrelevement" value="Jour de prélèvement" />
|
||||
<p:selectOneMenu id="jourPrelevement" value="#{membreCotisationBean.jourPrelevement}">
|
||||
<f:selectItem itemLabel="1er du mois" itemValue="1" />
|
||||
<f:selectItem itemLabel="5 du mois" itemValue="5" />
|
||||
<f:selectItem itemLabel="10 du mois" itemValue="10" />
|
||||
<f:selectItem itemLabel="15 du mois" itemValue="15" />
|
||||
<f:selectItem itemLabel="20 du mois" itemValue="20" />
|
||||
<f:selectItem itemLabel="25 du mois" itemValue="25" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="notificationSMS" value="#{membreCotisationBean.notificationSMS}" />
|
||||
<p:outputLabel for="notificationSMS" value=" Recevoir notification SMS avant prélèvement" />
|
||||
</div>
|
||||
|
||||
<div class="surface-100 p-3 border-round">
|
||||
<div class="font-medium mb-2">Conditions:</div>
|
||||
<ul class="text-sm text-600 ml-3">
|
||||
<li>Montant mensuel: #{membreCotisationBean.cotisationMensuelle} FCFA</li>
|
||||
<li>Vous pouvez suspendre à tout moment</li>
|
||||
<li>Notification 24h avant chaque prélèvement</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Activer" icon="pi pi-check"
|
||||
styleClass="ui-button-warning"
|
||||
action="#{membreCotisationBean.activerPrelevementAuto}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgPrelevementAuto').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgPrelevementAuto').hide();" type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
385
target/classes/META-INF/resources/pages/membre/dashboard.xhtml
Normal file
385
target/classes/META-INF/resources/pages/membre/dashboard.xhtml
Normal file
@@ -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">Mon Tableau de Bord - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête personnalisé -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle overflow-hidden mr-4"
|
||||
style="width: 80px; height: 80px;">
|
||||
<h:graphicImage value="#{membreDashboardBean.membre.photoUrl}"
|
||||
style="width: 100%; height: 100%; object-fit: cover;"
|
||||
rendered="#{membreDashboardBean.membre.photoUrl != null}" />
|
||||
<div class="bg-primary text-white flex align-items-center justify-content-center w-full h-full"
|
||||
rendered="#{membreDashboardBean.membre.photoUrl == null}">
|
||||
<span style="font-size: 2rem;">#{membreDashboardBean.membre.initiales}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="mb-1">Bonjour #{membreDashboardBean.membre.prenom} ! 👋</h3>
|
||||
<p class="text-600 m-0">
|
||||
<i class="pi pi-id-card mr-1"></i>
|
||||
#{membreDashboardBean.membre.numeroMembre} • #{membreDashboardBean.membre.typeMembre}
|
||||
</p>
|
||||
<p class="text-600 m-0">
|
||||
<i class="pi pi-calendar mr-1"></i>
|
||||
Membre depuis #{membreDashboardBean.membre.dateAdhesion}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<h:form id="formProfileActions">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Mon profil"
|
||||
icon="pi pi-user"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="/pages/membre/profil?faces-redirect=true" />
|
||||
<p:commandButton value="Mes cotisations"
|
||||
icon="pi pi-dollar"
|
||||
styleClass="ui-button-outlined ui-button-success"
|
||||
action="/pages/membre/cotisations?faces-redirect=true" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Résumé du statut -->
|
||||
<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">#{membreDashboardBean.statutCotisations}</div>
|
||||
<div class="text-blue-700">Statut Cotisations</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-circle 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">#{membreDashboardBean.evenementsInscrits}</div>
|
||||
<div class="text-green-700">Événements à venir</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-calendar 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">#{membreDashboardBean.aidesRecues}</div>
|
||||
<div class="text-purple-700">Aides Reçues</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-heart 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">#{membreDashboardBean.messagesNonLus}</div>
|
||||
<div class="text-orange-700">Messages Non Lus</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-envelope text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alertes et notifications -->
|
||||
<div class="card" rendered="#{not empty membreDashboardBean.alertes}">
|
||||
<h5>
|
||||
<i class="pi pi-bell text-orange-500 mr-2"></i>
|
||||
Notifications Importantes
|
||||
</h5>
|
||||
<ui:repeat value="#{membreDashboardBean.alertes}" var="alerte" varStatus="status">
|
||||
<div class="flex align-items-start p-3 mb-2 border-round border-left-3 #{alerte.couleurBordure}"
|
||||
style="background: #{alerte.couleurFond};">
|
||||
<i class="pi #{alerte.icone} #{alerte.couleurIcone} text-xl mr-3 mt-1"></i>
|
||||
<div class="flex-1">
|
||||
<div class="font-medium text-900 mb-1">#{alerte.titre}</div>
|
||||
<div class="text-600 mb-2">#{alerte.message}</div>
|
||||
<small class="text-500">#{alerte.dateRelative}</small>
|
||||
</div>
|
||||
<h:form id="formAlerte#{status.index}">
|
||||
<div class="flex gap-1 ml-3">
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-sm"
|
||||
action="#{membreDashboardBean.marquerLue(alerte)}"
|
||||
title="Marquer comme lue" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</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-4 border-round text-center h-full">
|
||||
<i class="pi pi-dollar text-green-500 text-3xl mb-3"></i>
|
||||
<div class="font-medium text-900 mb-2">Cotisations</div>
|
||||
<div class="text-600 mb-3 text-sm">Consultez votre situation et payez en ligne</div>
|
||||
<h:form id="formActionCotisations">
|
||||
<p:commandButton value="Voir mes cotisations"
|
||||
icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-outlined ui-button-success w-full"
|
||||
action="/pages/membre/cotisations?faces-redirect=true" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-50 p-4 border-round text-center h-full">
|
||||
<i class="pi pi-calendar text-blue-500 text-3xl mb-3"></i>
|
||||
<div class="font-medium text-900 mb-2">Événements</div>
|
||||
<div class="text-600 mb-3 text-sm">Découvrez et inscrivez-vous aux événements</div>
|
||||
<h:form id="formActionEvenements">
|
||||
<p:commandButton value="Voir les événements"
|
||||
icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-outlined ui-button-info w-full"
|
||||
action="/pages/membre/evenements?faces-redirect=true" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-50 p-4 border-round text-center h-full">
|
||||
<i class="pi pi-file-edit text-purple-500 text-3xl mb-3"></i>
|
||||
<div class="font-medium text-900 mb-2">Demandes</div>
|
||||
<div class="text-600 mb-3 text-sm">Faites une demande d'aide ou de service</div>
|
||||
<h:form id="formActionDemandes">
|
||||
<p:commandButton value="Nouvelle demande"
|
||||
icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-outlined ui-button-warning w-full"
|
||||
action="/pages/membre/demandes?faces-redirect=true" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mes prochains événements -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h5 class="m-0">
|
||||
<i class="pi pi-calendar text-blue-500 mr-2"></i>
|
||||
Mes Prochains Événements
|
||||
</h5>
|
||||
<h:form id="formVoirTousEvenements">
|
||||
<p:commandButton value="Voir tous"
|
||||
icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-text ui-button-sm"
|
||||
action="/pages/membre/evenements?faces-redirect=true" />
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<ui:repeat value="#{membreDashboardBean.prochainsEvenements}" var="evenement" varStatus="status">
|
||||
<div class="flex align-items-start p-3 mb-3 border-round border-left-3 #{evenement.couleurBordure}"
|
||||
style="background: var(--surface-50);">
|
||||
<div class="border-round p-3 mr-3 #{evenement.couleurCategorie}">
|
||||
<i class="pi #{evenement.iconeType} text-white"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="font-medium text-900">#{evenement.titre}</span>
|
||||
<p:tag value="#{evenement.statutInscription}" severity="#{evenement.severityInscription}" />
|
||||
</div>
|
||||
<div class="text-600 mb-1">
|
||||
<i class="pi pi-calendar mr-1"></i>
|
||||
#{evenement.dateComplete}
|
||||
</div>
|
||||
<div class="text-600 mb-2">
|
||||
<i class="pi pi-map-marker mr-1"></i>
|
||||
#{evenement.lieu}
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<span class="text-sm #{evenement.couleurPrix}">#{evenement.prixFormate}</span>
|
||||
<span class="text-sm text-600">#{evenement.nombreParticipants} participants</span>
|
||||
</div>
|
||||
</div>
|
||||
<h:form id="formEvenement#{status.index}">
|
||||
<div class="flex gap-1 ml-3">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-sm"
|
||||
action="#{membreDashboardBean.voirEvenement(evenement)}" />
|
||||
<p:commandButton icon="pi pi-calendar-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger ui-button-sm"
|
||||
action="#{membreDashboardBean.annulerInscription(evenement)}"
|
||||
rendered="#{evenement.peutAnnuler}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler votre inscription ?');" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<div class="text-center p-4" rendered="#{empty membreDashboardBean.prochainsEvenements}">
|
||||
<i class="pi pi-calendar text-6xl text-300 mb-3"></i>
|
||||
<div class="text-600 mb-3">Aucun événement à venir</div>
|
||||
<h:form id="formDecouvrirEvenements">
|
||||
<p:commandButton value="Découvrir les événements"
|
||||
icon="pi pi-search"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="/pages/membre/evenements?faces-redirect=true" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-chart-pie text-green-500 mr-2"></i>
|
||||
Ma Situation
|
||||
</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">Cotisations 2024</span>
|
||||
<span class="font-bold text-green-500">#{membreDashboardBean.cotisationsPayees}/#{membreDashboardBean.cotisationsTotales}</span>
|
||||
</div>
|
||||
<p:progressBar value="#{membreDashboardBean.progressionCotisations}"
|
||||
labelTemplate="#{membreDashboardBean.progressionCotisations}% payé"
|
||||
styleClass="h-1rem" />
|
||||
</div>
|
||||
|
||||
<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">Participation aux événements</span>
|
||||
<span class="font-bold text-blue-500">#{membreDashboardBean.tauxParticipation}%</span>
|
||||
</div>
|
||||
<div class="text-sm text-600">#{membreDashboardBean.evenementsAssistes} événements cette année</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="font-medium">Ancienneté</span>
|
||||
<span class="font-bold text-purple-500">#{membreDashboardBean.anciennete}</span>
|
||||
</div>
|
||||
<div class="text-sm text-600">Membre depuis #{membreDashboardBean.dateAdhesionFormatee}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rappels -->
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-clock text-orange-500 mr-2"></i>
|
||||
Rappels
|
||||
</h5>
|
||||
|
||||
<ui:repeat value="#{membreDashboardBean.rappels}" var="rappel" varStatus="status">
|
||||
<div class="flex align-items-center p-2 mb-2 border-round #{rappel.couleurFond}">
|
||||
<i class="pi #{rappel.icone} #{rappel.couleurIcone} mr-2"></i>
|
||||
<div class="flex-1">
|
||||
<div class="font-medium text-sm">#{rappel.titre}</div>
|
||||
<small class="text-600">#{rappel.echeance}</small>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<div class="text-center p-3" rendered="#{empty membreDashboardBean.rappels}">
|
||||
<i class="pi pi-check-circle text-green-500 text-2xl mb-2"></i>
|
||||
<div class="text-600 text-sm">Tout est à jour !</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historique récent -->
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h5 class="m-0">
|
||||
<i class="pi pi-history text-purple-500 mr-2"></i>
|
||||
Activité Récente
|
||||
</h5>
|
||||
<h:form id="formHistoriqueComplet">
|
||||
<p:commandButton value="Voir l'historique complet"
|
||||
icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-text ui-button-sm"
|
||||
action="/pages/membre/historique?faces-redirect=true" />
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<p:timeline value="#{membreDashboardBean.activiteRecente}" var="activite" align="left">
|
||||
<p:timelineEvent>
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-round p-2 mr-3 #{activite.couleurCategorie}">
|
||||
<i class="pi #{activite.icone} text-white text-sm"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="font-medium text-900">#{activite.titre}</div>
|
||||
<div class="text-600 text-sm">#{activite.description}</div>
|
||||
<small class="text-500">#{activite.dateRelative}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:timelineEvent>
|
||||
</p:timeline>
|
||||
|
||||
<div class="text-center p-4" rendered="#{empty membreDashboardBean.activiteRecente}">
|
||||
<i class="pi pi-info-circle text-3xl text-300 mb-2"></i>
|
||||
<div class="text-600">Aucune activité récente</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Boutons d'action rapide -->
|
||||
<div class="card">
|
||||
<h:form id="formBoutonsAction">
|
||||
<div class="flex flex-wrap gap-2 justify-content-center">
|
||||
<p:commandButton value="Payer mes cotisations"
|
||||
icon="pi pi-credit-card"
|
||||
styleClass="ui-button-success"
|
||||
action="#{membreDashboardBean.payerCotisations}"
|
||||
rendered="#{membreDashboardBean.peutPayerCotisations}" />
|
||||
<p:commandButton value="Faire une demande"
|
||||
icon="pi pi-file-edit"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
action="/pages/membre/demandes/creation?faces-redirect=true" />
|
||||
<p:commandButton value="Contacter l'administration"
|
||||
icon="pi pi-envelope"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="/pages/membre/contact?faces-redirect=true" />
|
||||
<p:commandButton value="Mes documents"
|
||||
icon="pi pi-folder"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="/pages/membre/documents?faces-redirect=true" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
294
target/classes/META-INF/resources/pages/public/formulaires.xhtml
Normal file
294
target/classes/META-INF/resources/pages/public/formulaires.xhtml
Normal file
@@ -0,0 +1,294 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||
xmlns:f="http://java.sun.com/jsf/core"
|
||||
xmlns:h="http://java.sun.com/jsf/html"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/public-template.xhtml">
|
||||
|
||||
<ui:define name="title">Nos Formulaires - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="head">
|
||||
<style>
|
||||
.formulaire-card {
|
||||
transition: all 0.3s ease;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
|
||||
.formulaire-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.formulaire-card.recommande {
|
||||
border-color: #10b981;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.formulaire-card.recommande::before {
|
||||
content: 'RECOMMANDÉ';
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #10b981;
|
||||
color: white;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.prix-badge {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.prix-periode {
|
||||
font-size: 0.9rem;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.fonctionnalite-active {
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.fonctionnalite-inactive {
|
||||
color: #d1d5db;
|
||||
}
|
||||
|
||||
.toggle-facturation {
|
||||
background: #f3f4f6;
|
||||
border-radius: 8px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.facturation-option {
|
||||
padding: 8px 16px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.facturation-option.active {
|
||||
background: #3b82f6;
|
||||
color: white;
|
||||
box-shadow: 0 2px 4px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
.economie-badge {
|
||||
background: linear-gradient(135deg, #fbbf24, #f59e0b);
|
||||
color: white;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête Hero -->
|
||||
<div class="surface-section px-4 py-8 md:px-6 lg:px-8">
|
||||
<div class="max-w-screen-lg mx-auto text-center">
|
||||
<div class="text-900 text-6xl font-bold mb-4">Choisissez votre formule</div>
|
||||
<div class="text-700 text-xl mb-6">
|
||||
Des solutions adaptées à chaque taille d'organisation
|
||||
</div>
|
||||
<div class="text-600 line-height-3 text-lg">
|
||||
Gérez efficacement votre association avec nos outils professionnels.
|
||||
Commencez gratuitement et évoluez selon vos besoins.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toggle Facturation -->
|
||||
<div class="surface-section px-4 py-4 md:px-6 lg:px-8 border-bottom-1 surface-border">
|
||||
<div class="max-w-screen-lg mx-auto">
|
||||
<div class="flex justify-content-center">
|
||||
<div class="toggle-facturation">
|
||||
<div class="flex">
|
||||
<div class="facturation-option #{formulaireBean.typeFacturationSelectionne.name() == 'MENSUEL' ? 'active' : ''}">
|
||||
<p:commandLink value="Mensuel"
|
||||
action="#{formulaireBean.setTypeFacturationSelectionne('MENSUEL')}"
|
||||
update="formulaires-grid"
|
||||
styleClass="no-underline" />
|
||||
</div>
|
||||
<div class="facturation-option #{formulaireBean.typeFacturationSelectionne.name() == 'ANNUEL' ? 'active' : ''}">
|
||||
<p:commandLink value="Annuel"
|
||||
action="#{formulaireBean.setTypeFacturationSelectionne('ANNUEL')}"
|
||||
update="formulaires-grid"
|
||||
styleClass="no-underline" />
|
||||
<span class="economie-badge ml-2">Économisez jusqu'à 16%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Grille des Formulaires -->
|
||||
<div class="surface-section px-4 py-8 md:px-6 lg:px-8">
|
||||
<div class="max-w-screen-xl mx-auto">
|
||||
<h:panelGroup id="formulaires-grid">
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{formulaireBean.formulaires}" var="formulaire">
|
||||
<div class="col-12 md:col-6 xl:col-3">
|
||||
<div class="formulaire-card surface-card p-6 border-round shadow-2 #{formulaire.recommande ? 'recommande' : ''}">
|
||||
|
||||
<!-- En-tête du formulaire -->
|
||||
<div class="text-center mb-5">
|
||||
<div class="#{formulaire.couleurTheme} text-white inline-flex align-items-center justify-content-center border-circle mb-3"
|
||||
style="width: 60px; height: 60px;">
|
||||
<i class="#{formulaire.iconeFormulaire} text-2xl"></i>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl mb-2">#{formulaire.nom}</div>
|
||||
<div class="text-600 line-height-3">#{formulaire.description}</div>
|
||||
</div>
|
||||
|
||||
<!-- Prix -->
|
||||
<div class="text-center mb-5">
|
||||
<div class="text-900 prix-badge">
|
||||
#{formulaireBean.getPrixAffiche(formulaire)}
|
||||
</div>
|
||||
<div class="prix-periode">
|
||||
Jusqu'à #{formulaire.quotaMaxMembres} membres
|
||||
</div>
|
||||
<h:panelGroup rendered="#{formulaireBean.typeFacturationSelectionne.name() == 'ANNUEL'}">
|
||||
<div class="text-green-600 font-semibold text-sm mt-1">
|
||||
#{formulaireBean.getEconomieAffichee(formulaire)}
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
|
||||
<!-- Fonctionnalités -->
|
||||
<div class="mb-6">
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-center mb-3">
|
||||
<i class="pi pi-check fonctionnalite-active mr-2"></i>
|
||||
<span class="text-900">Gestion des membres</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-3">
|
||||
<i class="pi pi-check fonctionnalite-active mr-2"></i>
|
||||
<span class="text-900">Gestion des cotisations</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-3">
|
||||
<i class="pi #{formulaire.gestionEvenements ? 'pi-check fonctionnalite-active' : 'pi-times fonctionnalite-inactive'} mr-2"></i>
|
||||
<span class="text-900">Gestion des événements</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-3">
|
||||
<i class="pi #{formulaire.gestionAides ? 'pi-check fonctionnalite-active' : 'pi-times fonctionnalite-inactive'} mr-2"></i>
|
||||
<span class="text-900">Demandes d'aide</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-3">
|
||||
<i class="pi #{formulaire.rapportsAvances ? 'pi-check fonctionnalite-active' : 'pi-times fonctionnalite-inactive'} mr-2"></i>
|
||||
<span class="text-900">Rapports avancés</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-3">
|
||||
<i class="pi #{formulaire.supportPrioritaire ? 'pi-check fonctionnalite-active' : 'pi-times fonctionnalite-inactive'} mr-2"></i>
|
||||
<span class="text-900">Support prioritaire</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Boutons d'action -->
|
||||
<div class="flex flex-column gap-3">
|
||||
<p:commandButton value="Choisir ce formulaire"
|
||||
action="#{formulaireBean.selectionnerFormulaire(formulaire)}"
|
||||
oncomplete="PF('souscriptionDialog').show()"
|
||||
update=":souscription-form"
|
||||
styleClass="p-button-lg w-full #{formulaire.couleurTheme.replace('bg-', 'p-button-')}"/>
|
||||
|
||||
<p:commandButton value="Voir les détails"
|
||||
action="#{formulaireBean.voirDetailsFormulaire(formulaire)}"
|
||||
styleClass="p-button-outlined p-button-secondary w-full"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section FAQ rapide -->
|
||||
<div class="surface-100 px-4 py-8 md:px-6 lg:px-8">
|
||||
<div class="max-w-screen-lg mx-auto text-center">
|
||||
<div class="text-900 text-4xl font-bold mb-4">Questions fréquentes</div>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-card p-4 border-round shadow-1 h-full">
|
||||
<i class="pi pi-question-circle text-blue-500 text-3xl mb-3"></i>
|
||||
<div class="text-900 font-bold mb-2">Puis-je changer de formule ?</div>
|
||||
<div class="text-600">Oui, vous pouvez upgrader ou downgrader à tout moment selon vos besoins.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-card p-4 border-round shadow-1 h-full">
|
||||
<i class="pi pi-shield text-green-500 text-3xl mb-3"></i>
|
||||
<div class="text-900 font-bold mb-2">Mes données sont-elles sécurisées ?</div>
|
||||
<div class="text-600">Absolument. Nous utilisons un chiffrement de niveau bancaire pour protéger vos données.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-card p-4 border-round shadow-1 h-full">
|
||||
<i class="pi pi-phone text-purple-500 text-3xl mb-3"></i>
|
||||
<div class="text-900 font-bold mb-2">Quel support est disponible ?</div>
|
||||
<div class="text-600">Support par email pour tous, support prioritaire et téléphonique pour Premium+.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog de souscription -->
|
||||
<p:dialog id="souscription-dialog" widgetVar="souscriptionDialog"
|
||||
header="Finaliser votre souscription"
|
||||
modal="true" responsive="true" width="600" height="400">
|
||||
<h:form id="souscription-form">
|
||||
<h:panelGroup rendered="#{formulaireBean.formulaireSelectionne != null}">
|
||||
<div class="p-4">
|
||||
<div class="text-center mb-4">
|
||||
<div class="#{formulaireBean.formulaireSelectionne.couleurTheme} text-white inline-flex align-items-center justify-content-center border-circle mb-3"
|
||||
style="width: 60px; height: 60px;">
|
||||
<i class="#{formulaireBean.formulaireSelectionne.iconeFormulaire} text-2xl"></i>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl">#{formulaireBean.formulaireSelectionne.nom}</div>
|
||||
<div class="text-600">#{formulaireBean.getPrixAffiche(formulaireBean.formulaireSelectionne)}</div>
|
||||
</div>
|
||||
|
||||
<div class="formgrid grid mb-4">
|
||||
<div class="field col">
|
||||
<label class="block text-900 font-medium mb-2">Type de facturation</label>
|
||||
<p:selectOneRadio value="#{formulaireBean.typeFacturationSelectionne}" layout="custom">
|
||||
<f:selectItem itemValue="MENSUEL" itemLabel="Mensuel" />
|
||||
<f:selectItem itemValue="ANNUEL" itemLabel="Annuel (économisez 16%)" />
|
||||
</p:selectOneRadio>
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<p:radioButton itemIndex="0" />
|
||||
<label class="ml-2">Mensuel</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p:radioButton itemIndex="1" />
|
||||
<label class="ml-2">Annuel</label>
|
||||
<span class="economie-badge ml-2">-16%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<p:commandButton value="Procéder au paiement"
|
||||
action="#{formulaireBean.procederSouscription()}"
|
||||
styleClass="p-button-lg #{formulaireBean.formulaireSelectionne.couleurTheme.replace('bg-', 'p-button-')}"
|
||||
icon="pi pi-credit-card"/>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
98
target/classes/META-INF/resources/pages/public/home.xhtml
Normal file
98
target/classes/META-INF/resources/pages/public/home.xhtml
Normal file
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<h:head>
|
||||
<title>UnionFlow - Accueil</title>
|
||||
<style>
|
||||
body {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
padding: 40px;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
||||
min-width: 500px;
|
||||
}
|
||||
.logo {
|
||||
text-align: center;
|
||||
font-size: 48px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
</h:head>
|
||||
|
||||
<h:body>
|
||||
<div class="container">
|
||||
<div class="logo">🦁</div>
|
||||
<h1>UnionFlow</h1>
|
||||
|
||||
<h:form id="mainForm">
|
||||
<p:panel header="Bienvenue sur UnionFlow" style="margin-bottom: 20px;">
|
||||
<h:panelGrid columns="2" cellpadding="10">
|
||||
<h:outputText value="#{helloView.message}" style="font-weight: bold; color: #667eea;"/>
|
||||
</h:panelGrid>
|
||||
</p:panel>
|
||||
|
||||
<p:panel header="Test Interactif">
|
||||
<h:panelGrid columns="3" cellpadding="5">
|
||||
<p:outputLabel for="nameInput" value="Votre nom:"/>
|
||||
<p:inputText id="nameInput" value="#{helloView.name}"
|
||||
placeholder="Entrez votre nom"/>
|
||||
<p:commandButton value="Dire Bonjour"
|
||||
action="#{helloView.sayHello}"
|
||||
update="greetingPanel"
|
||||
icon="pi pi-user"/>
|
||||
</h:panelGrid>
|
||||
|
||||
<p:panel id="greetingPanel" style="margin-top: 20px;">
|
||||
<h:outputText value="#{helloView.greeting}"
|
||||
style="font-size: 18px; color: #764ba2;"
|
||||
rendered="#{not empty helloView.greeting}"/>
|
||||
</p:panel>
|
||||
</p:panel>
|
||||
|
||||
<p:panel header="Informations Système" style="margin-top: 20px;">
|
||||
<h:panelGrid columns="2" cellpadding="5">
|
||||
<h:outputText value="Framework:" style="font-weight: bold;"/>
|
||||
<h:outputText value="Quarkus + PrimeFaces"/>
|
||||
|
||||
<h:outputText value="Version PrimeFaces:" style="font-weight: bold;"/>
|
||||
<h:outputText value="14.0.5"/>
|
||||
|
||||
<h:outputText value="Thème:" style="font-weight: bold;"/>
|
||||
<h:outputText value="Freya Blue Light"/>
|
||||
|
||||
<h:outputText value="Port:" style="font-weight: bold;"/>
|
||||
<h:outputText value="8082"/>
|
||||
</h:panelGrid>
|
||||
</p:panel>
|
||||
|
||||
<div style="text-align: center; margin-top: 20px;">
|
||||
<p:button value="Documentation" icon="pi pi-book"
|
||||
href="https://www.primefaces.org/showcase"
|
||||
target="_blank"
|
||||
style="margin-right: 10px;"/>
|
||||
<p:button value="GitHub" icon="pi pi-github"
|
||||
href="https://github.com/quarkiverse/quarkus-primefaces"
|
||||
target="_blank"/>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</h:body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,61 @@
|
||||
<!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">Accès Refusé - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="flex align-items-center justify-content-center min-h-screen">
|
||||
<div class="surface-card p-6 shadow-2 border-round text-center" style="max-width: 500px;">
|
||||
<!-- Icône d'erreur -->
|
||||
<div class="text-red-500 mb-4">
|
||||
<i class="pi pi-lock" style="font-size: 4rem;"></i>
|
||||
</div>
|
||||
|
||||
<!-- Titre -->
|
||||
<h2 class="text-900 font-bold text-4xl mb-3">Accès Refusé</h2>
|
||||
|
||||
<!-- Message -->
|
||||
<div class="text-600 mb-5">
|
||||
<p class="mb-3">Vous n'avez pas les permissions nécessaires pour accéder à cette page.</p>
|
||||
<p class="text-sm">
|
||||
Connecté en tant que : <strong>#{userSession.currentUser.nomComplet}</strong><br/>
|
||||
Type de compte : <strong>#{userSession.typeCompte}</strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<h:form>
|
||||
<div class="flex gap-3 justify-content-center">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Retour au tableau de bord" />
|
||||
<ui:param name="icon" value="pi pi-home" />
|
||||
<ui:param name="action" value="#{navigationBean.goToDashboard}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Se déconnecter" />
|
||||
<ui:param name="icon" value="pi pi-sign-out" />
|
||||
<ui:param name="action" value="#{loginBean.logout}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
<!-- Contact support -->
|
||||
<div class="mt-5 pt-4 border-top-1 surface-border">
|
||||
<p class="text-600 text-sm mb-2">Besoin d'aide ?</p>
|
||||
<p:link href="mailto:support@unionflow.dev"
|
||||
value="Contacter le support technique"
|
||||
styleClass="text-primary font-medium" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,115 @@
|
||||
<!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:param name="page" value="#{adhesionsBean}"/>
|
||||
<ui:define name="title">Demande d'Adhésion - 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-user-plus text-green-500" />
|
||||
<ui:param name="title" value="Demande d'Adhésion" />
|
||||
<ui:param name="description" value="Formulaire de demande d'adhésion à une organisation" />
|
||||
</ui:include>
|
||||
|
||||
<!-- Formulaire de demande -->
|
||||
<div class="card">
|
||||
<h:form id="formDemande">
|
||||
<h5>Nouvelle Demande d'Adhésion</h5>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Informations du Membre" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="membreId" value="Membre" />
|
||||
<p:selectOneMenu id="membreId"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.membreId}"
|
||||
required="true"
|
||||
requiredMessage="Veuillez sélectionner un membre"
|
||||
filter="true"
|
||||
filterMatchMode="contains"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{adhesionsBean.membresSelectItems}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="membreId" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="organisationId" value="Organisation" />
|
||||
<p:selectOneMenu id="organisationId"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.organisationId}"
|
||||
required="true"
|
||||
requiredMessage="Veuillez sélectionner une organisation"
|
||||
filter="true"
|
||||
filterMatchMode="contains"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{adhesionsBean.associationsSelectItems}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="organisationId" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Frais d'Adhésion" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="fraisAdhesion" value="Frais d'adhésion (FCFA)" />
|
||||
<p:inputNumber id="fraisAdhesion"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.fraisAdhesion}"
|
||||
symbol=""
|
||||
minValue="0"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Observations" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="observations" />
|
||||
<ui:param name="label" value="Observations (optionnel)" />
|
||||
<ui:param name="value" value="#{adhesionsBean.nouvelleAdhesion.observations}" />
|
||||
<ui:param name="rows" value="4" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="action" value="#{navigationBean.goToDashboard}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Soumettre la demande" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{adhesionsBean.enregistrerAdhesion}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,259 @@
|
||||
<!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:param name="page" value="#{adhesionsBean}"/>
|
||||
<ui:define name="title">Historique des Adhésions - 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-blue-500" />
|
||||
<ui:param name="title" value="Historique des Adhésions" />
|
||||
<ui:param name="description" value="Consultation de l'historique complet des adhésions" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsHistory">
|
||||
<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="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{adhesionsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Filtres d'historique -->
|
||||
<div class="card">
|
||||
<h:form id="formFiltresHistory">
|
||||
<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="#{adhesionsBean.filtres.dateDebut}" />
|
||||
</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="#{adhesionsBean.filtres.dateFin}" />
|
||||
</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="statutHistory" />
|
||||
<ui:param name="label" value="Statut" />
|
||||
<ui:param name="value" value="#{adhesionsBean.filtres.statut}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="Approuvée" itemValue="APPROUVEE" />
|
||||
<f:selectItem itemLabel="Rejetée" itemValue="REJETEE" />
|
||||
<f:selectItem itemLabel="Payée" itemValue="PAYEE" />
|
||||
<f:selectItem itemLabel="En paiement" itemValue="EN_PAIEMENT" />
|
||||
<f:selectItem itemLabel="Annulée" itemValue="ANNULEE" />
|
||||
</ui:define>
|
||||
</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="#{adhesionsBean.rechercher}" />
|
||||
<ui:param name="update" value=":formHistory" />
|
||||
</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-times" />
|
||||
<ui:param name="action" value="#{adhesionsBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value="@form :formHistory" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Tableau d'historique -->
|
||||
<div class="card">
|
||||
<h:form id="formHistory">
|
||||
<h5>Historique des Adhésions</h5>
|
||||
|
||||
<p:dataTable id="dtHistory"
|
||||
value="#{adhesionsBean.adhesionsFiltrees}"
|
||||
var="adhesion"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
sortMode="multiple"
|
||||
emptyMessage="Aucune adhésion trouvée">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Historique (#{adhesionsBean.adhesionsFiltrees.size()} adhésion(s))</span>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column headerText="Date" sortBy="#{adhesion.dateDemande}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.dateDemandeFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{adhesion.numeroReference}" style="width:150px">
|
||||
<h:outputText value="#{adhesion.numeroReference}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{adhesion.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{adhesion.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{adhesion.numeroMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{adhesion.nomOrganisation}">
|
||||
<h:outputText value="#{adhesion.nomOrganisation}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Frais" sortBy="#{adhesion.fraisAdhesion}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.fraisAdhesionFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{adhesion.statut}" style="width:150px">
|
||||
<p:tag value="#{adhesion.statutLibelle}"
|
||||
severity="#{adhesion.statutSeverity}"
|
||||
icon="#{adhesion.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Approbation" sortBy="#{adhesion.dateApprobation}" style="width:150px">
|
||||
<h:outputText value="#{adhesion.dateApprobationFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Paiement" sortBy="#{adhesion.datePaiement}" style="width:150px">
|
||||
<h:outputText value="#{adhesion.datePaiementFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:100px">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir les détails"
|
||||
styleClass="p-button-rounded p-button-text p-button-info"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formDetailsAdhesion"
|
||||
oncomplete="PF('dlgDetailsAdhesion').show();" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Détails Adhésion -->
|
||||
<p:dialog header="Détails de l'Adhésion" widgetVar="dlgDetailsAdhesion" modal="true" width="600" resizable="false">
|
||||
<h:form id="formDetailsAdhesion">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Référence</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Statut</label>
|
||||
<p:tag value="#{adhesionsBean.adhesionSelectionnee.statutLibelle}"
|
||||
severity="#{adhesionsBean.adhesionSelectionnee.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Membre</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">N° #{adhesionsBean.adhesionSelectionnee.numeroMembre}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Organisation</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.nomOrganisation}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date de demande</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.dateDemandeFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Frais d'adhésion</label>
|
||||
<p class="text-600 font-bold">#{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant payé</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.montantPayeFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant restant</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.montantRestantFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date d'approbation</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.dateApprobationFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date de paiement</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.datePaiementFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Méthode de paiement</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.methodePaiementLibelle}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{adhesionsBean.adhesionSelectionnee.observations != null}">
|
||||
<div class="field">
|
||||
<label class="font-medium">Observations</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.observations}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{adhesionsBean.adhesionSelectionnee.motifRejet != null}">
|
||||
<div class="field">
|
||||
<label class="font-medium">Motif de rejet</label>
|
||||
<p class="text-600 text-red-500">#{adhesionsBean.adhesionSelectionnee.motifRejet}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,417 @@
|
||||
<!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:param name="page" value="#{adhesionsBean}"/>
|
||||
<ui:define name="title">Liste des Adhésions - 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-users text-blue-500" />
|
||||
<ui:param name="title" value="Liste des Adhésions" />
|
||||
<ui:param name="description" value="Gestion complète des demandes d'adhésion" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsListe">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Nouvelle adhésion" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="onclick" value="PF('dlgNouvelleAdhesion').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{adhesionsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.totalAdhesions}" />
|
||||
<ui:param name="label" value="Total Adhésions" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsEnAttente}" />
|
||||
<ui:param name="label" value="En Attente" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsApprouvees}" />
|
||||
<ui:param name="label" value="Approuvées" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.tauxApprobationInt}%" />
|
||||
<ui:param name="label" value="Taux d'Approbation" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</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-select.xhtml">
|
||||
<ui:param name="id" value="filtreStatut" />
|
||||
<ui:param name="label" value="Statut" />
|
||||
<ui:param name="value" value="#{adhesionsBean.filtres.statut}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="Approuvée" itemValue="APPROUVEE" />
|
||||
<f:selectItem itemLabel="Rejetée" itemValue="REJETEE" />
|
||||
<f:selectItem itemLabel="Payée" itemValue="PAYEE" />
|
||||
<f:selectItem itemLabel="En paiement" itemValue="EN_PAIEMENT" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="filtreNomMembre" />
|
||||
<ui:param name="label" value="Nom du membre" />
|
||||
<ui:param name="value" value="#{adhesionsBean.filtres.nomMembre}" />
|
||||
<ui:param name="placeholder" value="Rechercher par nom..." />
|
||||
</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="filtreDateDebut" />
|
||||
<ui:param name="label" value="Date début" />
|
||||
<ui:param name="value" value="#{adhesionsBean.filtres.dateDebut}" />
|
||||
</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="#{adhesionsBean.rechercher}" />
|
||||
<ui:param name="update" value=":formListe" />
|
||||
</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-times" />
|
||||
<ui:param name="action" value="#{adhesionsBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value="@form :formListe" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Liste des adhésions -->
|
||||
<div class="card">
|
||||
<h:form id="formListe">
|
||||
<h5>Adhésions</h5>
|
||||
|
||||
<p:dataTable id="dtAdhesions"
|
||||
value="#{adhesionsBean.adhesionsFiltrees}"
|
||||
var="adhesion"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
sortMode="multiple"
|
||||
emptyMessage="Aucune adhésion trouvée"
|
||||
selection="#{adhesionsBean.adhesionsSelectionnees}"
|
||||
selectionMode="multiple">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Liste des adhésions (#{adhesionsBean.adhesionsFiltrees.size()} adhésion(s))</span>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{adhesion.numeroReference}" style="width:150px">
|
||||
<h:outputText value="#{adhesion.numeroReference}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{adhesion.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{adhesion.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{adhesion.numeroMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{adhesion.nomOrganisation}">
|
||||
<h:outputText value="#{adhesion.nomOrganisation}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Demande" sortBy="#{adhesion.dateDemande}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.dateDemandeFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Frais" sortBy="#{adhesion.fraisAdhesion}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.fraisAdhesionFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{adhesion.statut}" style="width:150px">
|
||||
<p:tag value="#{adhesion.statutLibelle}"
|
||||
severity="#{adhesion.statutSeverity}"
|
||||
icon="#{adhesion.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir les détails"
|
||||
styleClass="p-button-rounded p-button-text p-button-info"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formDetailsAdhesion"
|
||||
oncomplete="PF('dlgDetailsAdhesion').show();" />
|
||||
<p:commandButton icon="pi pi-check"
|
||||
title="Approuver"
|
||||
styleClass="p-button-rounded p-button-text p-button-success"
|
||||
rendered="#{'EN_ATTENTE' == adhesion.statut}"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formApprobation"
|
||||
oncomplete="PF('dlgApprobation').show();" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
title="Rejeter"
|
||||
styleClass="p-button-rounded p-button-text p-button-danger"
|
||||
rendered="#{'EN_ATTENTE' == adhesion.statut}"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formRejet"
|
||||
oncomplete="PF('dlgRejet').show();" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Adhésion -->
|
||||
<p:dialog header="Nouvelle Adhésion" widgetVar="dlgNouvelleAdhesion" modal="true" width="600" resizable="false">
|
||||
<h:form id="formNouvelleAdhesion">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="membreId" value="Membre" />
|
||||
<p:selectOneMenu id="membreId"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.membreId}"
|
||||
required="true"
|
||||
requiredMessage="Veuillez sélectionner un membre"
|
||||
filter="true"
|
||||
filterMatchMode="contains"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{adhesionsBean.membresSelectItems}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="membreId" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="organisationId" value="Organisation" />
|
||||
<p:selectOneMenu id="organisationId"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.organisationId}"
|
||||
required="true"
|
||||
requiredMessage="Veuillez sélectionner une organisation"
|
||||
filter="true"
|
||||
filterMatchMode="contains"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{adhesionsBean.associationsSelectItems}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="organisationId" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="fraisAdhesion" value="Frais d'adhésion (FCFA)" />
|
||||
<p:inputNumber id="fraisAdhesion"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.fraisAdhesion}"
|
||||
symbol=""
|
||||
minValue="0"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="observations" />
|
||||
<ui:param name="label" value="Observations" />
|
||||
<ui:param name="value" value="#{adhesionsBean.nouvelleAdhesion.observations}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgNouvelleAdhesion').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Créer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.enregistrerAdhesion}" />
|
||||
<ui:param name="update" value="@form :formListe" />
|
||||
<ui:param name="oncomplete" value="PF('dlgNouvelleAdhesion').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Détails Adhésion -->
|
||||
<p:dialog header="Détails de l'Adhésion" widgetVar="dlgDetailsAdhesion" modal="true" width="600" resizable="false">
|
||||
<h:form id="formDetailsAdhesion">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Référence</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Statut</label>
|
||||
<p:tag value="#{adhesionsBean.adhesionSelectionnee.statutLibelle}"
|
||||
severity="#{adhesionsBean.adhesionSelectionnee.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Membre</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">N° #{adhesionsBean.adhesionSelectionnee.numeroMembre}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Organisation</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.nomOrganisation}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date de demande</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.dateDemandeFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Frais d'adhésion</label>
|
||||
<p class="text-600 font-bold">#{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant payé</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.montantPayeFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant restant</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.montantRestantFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{adhesionsBean.adhesionSelectionnee.dateApprobation != null}">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date d'approbation</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.dateApprobationFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{adhesionsBean.adhesionSelectionnee.observations != null}">
|
||||
<div class="field">
|
||||
<label class="font-medium">Observations</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.observations}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Approbation -->
|
||||
<p:dialog header="Approuver l'Adhésion" widgetVar="dlgApprobation" modal="true" width="500" resizable="false">
|
||||
<h:form id="formApprobation">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">Frais: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
|
||||
<p:message id="msgApprobation" />
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgApprobation').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Approuver" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.approuverAdhesion}" />
|
||||
<ui:param name="update" value="@form :formListe" />
|
||||
<ui:param name="oncomplete" value="PF('dlgApprobation').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Rejet -->
|
||||
<p:dialog header="Rejeter l'Adhésion" widgetVar="dlgRejet" modal="true" width="500" resizable="false">
|
||||
<h:form id="formRejet">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="motifRejet" />
|
||||
<ui:param name="label" value="Motif du rejet" />
|
||||
<ui:param name="value" value="#{adhesionsBean.adhesionSelectionnee.motifRejet}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="4" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgRejet').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<p:commandButton value="Rejeter"
|
||||
icon="pi pi-times"
|
||||
styleClass="p-button-danger"
|
||||
action="#{adhesionsBean.rejeterAdhesion(adhesionsBean.adhesionSelectionnee.motifRejet)}"
|
||||
update="@form :formListe"
|
||||
oncomplete="PF('dlgRejet').hide();" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,115 @@
|
||||
<!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:param name="page" value="#{adhesionsBean}"/>
|
||||
<ui:define name="title">Nouvelle Adhésion - 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-user-plus text-green-500" />
|
||||
<ui:param name="title" value="Nouvelle Adhésion" />
|
||||
<ui:param name="description" value="Création d'une nouvelle demande d'adhésion" />
|
||||
</ui:include>
|
||||
|
||||
<!-- Formulaire de nouvelle adhésion -->
|
||||
<div class="card">
|
||||
<h:form id="formNouvelleAdhesion">
|
||||
<h5>Créer une Nouvelle Adhésion</h5>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Informations du Membre" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="membreId" value="Membre" />
|
||||
<p:selectOneMenu id="membreId"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.membreId}"
|
||||
required="true"
|
||||
requiredMessage="Veuillez sélectionner un membre"
|
||||
filter="true"
|
||||
filterMatchMode="contains"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{adhesionsBean.membresSelectItems}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="membreId" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="organisationId" value="Organisation" />
|
||||
<p:selectOneMenu id="organisationId"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.organisationId}"
|
||||
required="true"
|
||||
requiredMessage="Veuillez sélectionner une organisation"
|
||||
filter="true"
|
||||
filterMatchMode="contains"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{adhesionsBean.associationsSelectItems}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="organisationId" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Frais d'Adhésion" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="fraisAdhesion" value="Frais d'adhésion (FCFA)" />
|
||||
<p:inputNumber id="fraisAdhesion"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.fraisAdhesion}"
|
||||
symbol=""
|
||||
minValue="0"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Observations" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="observations" />
|
||||
<ui:param name="label" value="Observations (optionnel)" />
|
||||
<ui:param name="value" value="#{adhesionsBean.nouvelleAdhesion.observations}" />
|
||||
<ui:param name="rows" value="4" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="action" value="#{navigationBean.goToDashboard}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Créer l'adhésion" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.enregistrerAdhesion}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,261 @@
|
||||
<!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:param name="page" value="#{adhesionsBean}"/>
|
||||
<ui:define name="title">Paiement des Adhésions - 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-credit-card text-green-500" />
|
||||
<ui:param name="title" value="Paiement des Adhésions" />
|
||||
<ui:param name="description" value="Enregistrement et suivi des paiements d'adhésion" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsPaiement">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{adhesionsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques de paiement -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.totalCollecteFormatte}" />
|
||||
<ui:param name="label" value="Total Collecté" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsPayees}" />
|
||||
<ui:param name="label" value="Adhésions Payées" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.tauxPaiementInt}%" />
|
||||
<ui:param name="label" value="Taux de Paiement" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsApprouvees - adhesionsBean.statistiques.adhesionsPayees}" />
|
||||
<ui:param name="label" value="En Attente de Paiement" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Adhésions approuvées en attente de paiement -->
|
||||
<div class="card">
|
||||
<h:form id="formPaiements">
|
||||
<h5>Adhésions Approuvées en Attente de Paiement</h5>
|
||||
|
||||
<p:dataTable id="dtPaiements"
|
||||
value="#{adhesionsBean.adhesionsFiltrees}"
|
||||
var="adhesion"
|
||||
filteredValue="#{adhesionsBean.adhesionsFiltrees}"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
emptyMessage="Aucune adhésion en attente de paiement"
|
||||
selection="#{adhesionsBean.adhesionSelectionnee}"
|
||||
selectionMode="single">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Adhésions à payer</span>
|
||||
<p:selectOneMenu value="#{adhesionsBean.filtres.statut}" styleClass="w-12rem">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="Approuvée" itemValue="APPROUVEE" />
|
||||
<f:selectItem itemLabel="En paiement" itemValue="EN_PAIEMENT" />
|
||||
<p:ajax update="dtPaiements" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{adhesion.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{adhesion.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{adhesion.numeroMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{adhesion.nomOrganisation}">
|
||||
<h:outputText value="#{adhesion.nomOrganisation}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Frais" sortBy="#{adhesion.fraisAdhesion}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.fraisAdhesionFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Payé" sortBy="#{adhesion.montantPaye}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.montantPayeFormatte}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Restant" style="width:120px">
|
||||
<h:outputText value="#{adhesion.montantRestantFormatte}"
|
||||
styleClass="#{adhesion.montantRestant.compareTo(java.math.BigDecimal.ZERO) > 0 ? 'text-orange-500 font-bold' : 'text-green-500'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Approbation" sortBy="#{adhesion.dateApprobation}" style="width:150px">
|
||||
<h:outputText value="#{adhesion.dateApprobationFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton value="Payer"
|
||||
icon="pi pi-check"
|
||||
styleClass="p-button-success p-button-sm"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formPaiement"
|
||||
oncomplete="PF('dlgPaiement').show();" />
|
||||
<p:commandButton value="Partiel"
|
||||
icon="pi pi-minus"
|
||||
styleClass="p-button-info p-button-sm"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formPaiementPartiel"
|
||||
oncomplete="PF('dlgPaiementPartiel').show();" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Paiement Complet -->
|
||||
<p:dialog header="Enregistrer un Paiement" widgetVar="dlgPaiement" modal="true" width="500" resizable="false">
|
||||
<h:form id="formPaiement">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">Frais d'adhésion: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="methodePaiement" />
|
||||
<ui:param name="label" value="Méthode de paiement" />
|
||||
<ui:param name="value" value="#{adhesionsBean.adhesionSelectionnee.methodePaiement}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Wave Money" itemValue="WAVE_MONEY" />
|
||||
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="Virement bancaire" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
|
||||
<f:selectItem itemLabel="Orange Money" itemValue="ORANGE_MONEY" />
|
||||
<f:selectItem itemLabel="Free Money" itemValue="FREE_MONEY" />
|
||||
<f:selectItem itemLabel="Carte bancaire" itemValue="CARTE_BANCAIRE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="referencePaiement" />
|
||||
<ui:param name="label" value="Référence de paiement" />
|
||||
<ui:param name="value" value="#{adhesionsBean.adhesionSelectionnee.referencePaiement}" />
|
||||
<ui:param name="placeholder" value="Ex: WAVE-123456789" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="observationsPaiement" />
|
||||
<ui:param name="label" value="Observations" />
|
||||
<ui:param name="value" value="#{adhesionsBean.adhesionSelectionnee.observations}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgPaiement').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.enregistrerPaiement(adhesionsBean.adhesionSelectionnee.fraisAdhesion, adhesionsBean.adhesionSelectionnee.methodePaiement, adhesionsBean.adhesionSelectionnee.referencePaiement)}" />
|
||||
<ui:param name="update" value="@form :formPaiements" />
|
||||
<ui:param name="oncomplete" value="PF('dlgPaiement').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Paiement Partiel -->
|
||||
<p:dialog header="Enregistrer un Paiement Partiel" widgetVar="dlgPaiementPartiel" modal="true" width="500" resizable="false">
|
||||
<h:form id="formPaiementPartiel">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">Frais d'adhésion: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
<p class="text-500 text-sm">Montant restant: #{adhesionsBean.adhesionSelectionnee.montantRestantFormatte}</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="montantPaye" value="Montant à payer (FCFA)" />
|
||||
<p:inputNumber id="montantPaye"
|
||||
value="#{adhesionsBean.adhesionSelectionnee.montantPaye}"
|
||||
symbol=""
|
||||
minValue="0"
|
||||
maxValue="#{adhesionsBean.adhesionSelectionnee.fraisAdhesion}"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="methodePaiementPartiel" />
|
||||
<ui:param name="label" value="Méthode de paiement" />
|
||||
<ui:param name="value" value="#{adhesionsBean.adhesionSelectionnee.methodePaiement}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Wave Money" itemValue="WAVE_MONEY" />
|
||||
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="Virement bancaire" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="referencePaiementPartiel" />
|
||||
<ui:param name="label" value="Référence de paiement" />
|
||||
<ui:param name="value" value="#{adhesionsBean.adhesionSelectionnee.referencePaiement}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgPaiementPartiel').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.enregistrerPaiement(adhesionsBean.adhesionSelectionnee.montantPaye, adhesionsBean.adhesionSelectionnee.methodePaiement, adhesionsBean.adhesionSelectionnee.referencePaiement)}" />
|
||||
<ui:param name="update" value="@form :formPaiements" />
|
||||
<ui:param name="oncomplete" value="PF('dlgPaiementPartiel').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
<!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:param name="page" value="#{adhesionsBean}"/>
|
||||
<ui:define name="title">Adhésions en Attente - 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-clock text-orange-500" />
|
||||
<ui:param name="title" value="Adhésions en Attente" />
|
||||
<ui:param name="description" value="Validation et traitement des demandes d'adhésion en attente" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsPending">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{adhesionsBean.chargerAdhesionsEnAttente}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsEnAttente}" />
|
||||
<ui:param name="label" value="En Attente" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsApprouvees}" />
|
||||
<ui:param name="label" value="Approuvées" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.tauxApprobationInt}%" />
|
||||
<ui:param name="label" value="Taux d'Approbation" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.totalCollecteFormatte}" />
|
||||
<ui:param name="label" value="Total Collecté" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des adhésions en attente -->
|
||||
<div class="card">
|
||||
<h:form id="formPending">
|
||||
<h5>Adhésions en Attente de Validation</h5>
|
||||
|
||||
<p:dataTable id="dtPending"
|
||||
value="#{adhesionsBean.adhesionsFiltrees}"
|
||||
var="adhesion"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
emptyMessage="Aucune adhésion en attente">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Demandes en attente d'approbation</span>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{adhesion.numeroReference}" style="width:150px">
|
||||
<h:outputText value="#{adhesion.numeroReference}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{adhesion.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{adhesion.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{adhesion.numeroMembre}</div>
|
||||
<div class="text-500 text-xs">#{adhesion.emailMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{adhesion.nomOrganisation}">
|
||||
<h:outputText value="#{adhesion.nomOrganisation}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Demande" sortBy="#{adhesion.dateDemande}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.dateDemandeFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Jours" style="width:80px">
|
||||
<h:outputText value="#{adhesion.joursDepuisDemande} jour(s)" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Frais" sortBy="#{adhesion.fraisAdhesion}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.fraisAdhesionFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-check"
|
||||
title="Approuver"
|
||||
styleClass="p-button-rounded p-button-text p-button-success"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formApprobation"
|
||||
oncomplete="PF('dlgApprobation').show();" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
title="Rejeter"
|
||||
styleClass="p-button-rounded p-button-text p-button-danger"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formRejet"
|
||||
oncomplete="PF('dlgRejet').show();" />
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir les détails"
|
||||
styleClass="p-button-rounded p-button-text p-button-info"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formDetailsAdhesion"
|
||||
oncomplete="PF('dlgDetailsAdhesion').show();" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Approbation -->
|
||||
<p:dialog header="Approuver l'Adhésion" widgetVar="dlgApprobation" modal="true" width="500" resizable="false">
|
||||
<h:form id="formApprobation">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">Frais: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgApprobation').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Approuver" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.approuverAdhesion}" />
|
||||
<ui:param name="update" value="@form :formPending" />
|
||||
<ui:param name="oncomplete" value="PF('dlgApprobation').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Rejet -->
|
||||
<p:dialog header="Rejeter l'Adhésion" widgetVar="dlgRejet" modal="true" width="500" resizable="false">
|
||||
<h:form id="formRejet">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="motifRejet" />
|
||||
<ui:param name="label" value="Motif du rejet" />
|
||||
<ui:param name="value" value="#{adhesionsBean.adhesionSelectionnee.motifRejet}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="4" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgRejet').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<p:commandButton value="Rejeter"
|
||||
icon="pi pi-times"
|
||||
styleClass="p-button-danger"
|
||||
action="#{adhesionsBean.rejeterAdhesion(adhesionsBean.adhesionSelectionnee.motifRejet)}"
|
||||
update="@form :formPending"
|
||||
oncomplete="PF('dlgRejet').hide();" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Détails Adhésion -->
|
||||
<p:dialog header="Détails de l'Adhésion" widgetVar="dlgDetailsAdhesion" modal="true" width="600" resizable="false">
|
||||
<h:form id="formDetailsAdhesion">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Référence</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Statut</label>
|
||||
<p:tag value="#{adhesionsBean.adhesionSelectionnee.statutLibelle}"
|
||||
severity="#{adhesionsBean.adhesionSelectionnee.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Membre</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">N° #{adhesionsBean.adhesionSelectionnee.numeroMembre} - #{adhesionsBean.adhesionSelectionnee.emailMembre}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Organisation</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.nomOrganisation}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date de demande</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.dateDemandeFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Frais d'adhésion</label>
|
||||
<p class="text-600 font-bold">#{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{adhesionsBean.adhesionSelectionnee.observations != null}">
|
||||
<div class="field">
|
||||
<label class="font-medium">Observations</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.observations}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,167 @@
|
||||
<!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:param name="page" value="#{adhesionsBean}"/>
|
||||
<ui:define name="title">Renouvellement d'Adhésion - 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-refresh text-blue-500" />
|
||||
<ui:param name="title" value="Renouvellement d'Adhésion" />
|
||||
<ui:param name="description" value="Gestion des renouvellements d'adhésion" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsRenouvellement">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{adhesionsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsPayees}" />
|
||||
<ui:param name="label" value="Adhésions Actives" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="À Renouveler (ce mois)" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Renouvelées (ce mois)" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.totalAdhesions}" />
|
||||
<ui:param name="label" value="Total Adhésions" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des adhésions à renouveler -->
|
||||
<div class="card">
|
||||
<h:form id="formRenouvellement">
|
||||
<h5>Adhésions à Renouveler</h5>
|
||||
|
||||
<p:dataTable id="dtRenouvellement"
|
||||
value="#{adhesionsBean.adhesionsFiltrees}"
|
||||
var="adhesion"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
emptyMessage="Aucune adhésion à renouveler">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Adhésions nécessitant un renouvellement</span>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{adhesion.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{adhesion.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{adhesion.numeroMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{adhesion.nomOrganisation}">
|
||||
<h:outputText value="#{adhesion.nomOrganisation}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Approbation" sortBy="#{adhesion.dateApprobation}" style="width:150px">
|
||||
<h:outputText value="#{adhesion.dateApprobationFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Frais" sortBy="#{adhesion.fraisAdhesion}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.fraisAdhesionFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" style="width:150px">
|
||||
<p:tag value="#{adhesion.statutLibelle}"
|
||||
severity="#{adhesion.statutSeverity}"
|
||||
icon="#{adhesion.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Renouveler" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="onclick" value="PF('dlgRenouvellement').show(); adhesionsBean.selectionnerAdhesion(adhesion);" />
|
||||
<ui:param name="styleClass" value="p-button-sm" />
|
||||
</ui:include>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Renouvellement -->
|
||||
<p:dialog header="Renouveler l'Adhésion" widgetVar="dlgRenouvellement" modal="true" width="500" resizable="false">
|
||||
<h:form id="formRenouvellement">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion actuelle</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">Frais actuel: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="nouveauxFrais" value="Nouveaux frais d'adhésion (FCFA)" />
|
||||
<p:inputNumber id="nouveauxFrais"
|
||||
value="#{adhesionsBean.nouvelleAdhesion.fraisAdhesion}"
|
||||
symbol=""
|
||||
minValue="0"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="observationsRenouvellement" />
|
||||
<ui:param name="label" value="Observations" />
|
||||
<ui:param name="value" value="#{adhesionsBean.nouvelleAdhesion.observations}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgRenouvellement').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Créer le renouvellement" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.enregistrerAdhesion}" />
|
||||
<ui:param name="update" value="@form :formRenouvellement" />
|
||||
<ui:param name="oncomplete" value="PF('dlgRenouvellement').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,254 @@
|
||||
<!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:param name="page" value="#{adhesionsBean}"/>
|
||||
<ui:define name="title">Validation des Adhésions - 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-check-circle text-green-500" />
|
||||
<ui:param name="title" value="Validation des Adhésions" />
|
||||
<ui:param name="description" value="Approbation et rejet des demandes d'adhésion" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsValidation">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{adhesionsBean.chargerAdhesionsEnAttente}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsEnAttente}" />
|
||||
<ui:param name="label" value="En Attente" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.adhesionsApprouvees}" />
|
||||
<ui:param name="label" value="Approuvées" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.tauxApprobationInt}%" />
|
||||
<ui:param name="label" value="Taux d'Approbation" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{adhesionsBean.statistiques.totalAdhesions}" />
|
||||
<ui:param name="label" value="Total" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des adhésions en attente -->
|
||||
<div class="card">
|
||||
<h:form id="formValidation">
|
||||
<h5>Adhésions en Attente de Validation</h5>
|
||||
|
||||
<p:dataTable id="dtValidation"
|
||||
value="#{adhesionsBean.adhesionsFiltrees}"
|
||||
var="adhesion"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
emptyMessage="Aucune adhésion en attente">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Demandes nécessitant une validation</span>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{adhesion.numeroReference}" style="width:150px">
|
||||
<h:outputText value="#{adhesion.numeroReference}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{adhesion.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{adhesion.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{adhesion.numeroMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{adhesion.nomOrganisation}">
|
||||
<h:outputText value="#{adhesion.nomOrganisation}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Demande" sortBy="#{adhesion.dateDemande}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.dateDemandeFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Frais" sortBy="#{adhesion.fraisAdhesion}" style="width:120px">
|
||||
<h:outputText value="#{adhesion.fraisAdhesionFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:250px">
|
||||
<div class="flex gap-1">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Approuver" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.selectionnerAdhesion(adhesion)}" />
|
||||
<ui:param name="update" value=":formApprobation" />
|
||||
<ui:param name="oncomplete" value="PF('dlgApprobation').show();" />
|
||||
<ui:param name="styleClass" value="p-button-sm" />
|
||||
</ui:include>
|
||||
<p:commandButton value="Rejeter"
|
||||
icon="pi pi-times"
|
||||
styleClass="p-button-danger p-button-sm"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formRejet"
|
||||
oncomplete="PF('dlgRejet').show();" />
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir les détails"
|
||||
styleClass="p-button-rounded p-button-text p-button-info p-button-sm"
|
||||
action="#{adhesionsBean.selectionnerAdhesion(adhesion)}"
|
||||
update=":formDetailsAdhesion"
|
||||
oncomplete="PF('dlgDetailsAdhesion').show();" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Approbation -->
|
||||
<p:dialog header="Approuver l'Adhésion" widgetVar="dlgApprobation" modal="true" width="500" resizable="false">
|
||||
<h:form id="formApprobation">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">Frais: #{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgApprobation').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Approuver" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{adhesionsBean.approuverAdhesion}" />
|
||||
<ui:param name="update" value="@form :formValidation" />
|
||||
<ui:param name="oncomplete" value="PF('dlgApprobation').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Rejet -->
|
||||
<p:dialog header="Rejeter l'Adhésion" widgetVar="dlgRejet" modal="true" width="500" resizable="false">
|
||||
<h:form id="formRejet">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Adhésion</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference} - #{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="motifRejet" />
|
||||
<ui:param name="label" value="Motif du rejet" />
|
||||
<ui:param name="value" value="#{adhesionsBean.adhesionSelectionnee.motifRejet}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="4" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgRejet').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<p:commandButton value="Rejeter"
|
||||
icon="pi pi-times"
|
||||
styleClass="p-button-danger"
|
||||
action="#{adhesionsBean.rejeterAdhesion(adhesionsBean.adhesionSelectionnee.motifRejet)}"
|
||||
update="@form :formValidation"
|
||||
oncomplete="PF('dlgRejet').hide();" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Détails Adhésion -->
|
||||
<p:dialog header="Détails de l'Adhésion" widgetVar="dlgDetailsAdhesion" modal="true" width="600" resizable="false">
|
||||
<h:form id="formDetailsAdhesion">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Référence</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.numeroReference}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Statut</label>
|
||||
<p:tag value="#{adhesionsBean.adhesionSelectionnee.statutLibelle}"
|
||||
severity="#{adhesionsBean.adhesionSelectionnee.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Membre</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">N° #{adhesionsBean.adhesionSelectionnee.numeroMembre}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Organisation</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.nomOrganisation}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date de demande</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.dateDemandeFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Frais d'adhésion</label>
|
||||
<p class="text-600 font-bold">#{adhesionsBean.adhesionSelectionnee.fraisAdhesionFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{adhesionsBean.adhesionSelectionnee.observations != null}">
|
||||
<div class="field">
|
||||
<label class="font-medium">Observations</label>
|
||||
<p class="text-600">#{adhesionsBean.adhesionSelectionnee.observations}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,32 @@
|
||||
<!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:param name="page" value="#{configurationBean}"/>
|
||||
<ui:define name="title">Journal d'Audit - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- Redirection vers la page principale d'audit -->
|
||||
<div class="card">
|
||||
<div class="text-center p-4">
|
||||
<i class="pi pi-history text-4xl text-indigo-500 mb-3"></i>
|
||||
<h5>Journal d'Audit</h5>
|
||||
<p class="text-600 mt-2">
|
||||
Redirection vers la page principale du journal d'audit...
|
||||
</p>
|
||||
<div class="mt-4">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Accéder au Journal d'Audit" />
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="outcome" value="/pages/admin/audit/journal.xhtml" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,47 @@
|
||||
<!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:param name="page" value="#{configurationBean}"/>
|
||||
<ui:define name="title">Paramètres Système - 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-cog text-orange-500" />
|
||||
<ui:param name="title" value="Paramètres Système" />
|
||||
<ui:param name="description" value="Configuration des paramètres généraux de l'application" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActions">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{configurationBean.enregistrer}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Information -->
|
||||
<div class="card">
|
||||
<div class="text-center p-4">
|
||||
<i class="pi pi-info-circle text-4xl text-orange-500 mb-3"></i>
|
||||
<h5>Configuration Système</h5>
|
||||
<p class="text-600 mt-2">
|
||||
La page de configuration système sera disponible prochainement.
|
||||
</p>
|
||||
<p class="text-600 mt-2">
|
||||
Elle permettra de configurer les paramètres généraux de l'application.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,53 @@
|
||||
<!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:param name="page" value="#{configurationBean}"/>
|
||||
<ui:define name="title">Gestion des Rôles - 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-shield text-purple-500" />
|
||||
<ui:param name="title" value="Gestion des Rôles" />
|
||||
<ui:param name="description" value="Gestion des rôles et permissions via Keycloak" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActions">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Documentation Keycloak" />
|
||||
<ui:param name="icon" value="pi pi-book" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Information -->
|
||||
<div class="card">
|
||||
<div class="text-center p-4">
|
||||
<i class="pi pi-info-circle text-4xl text-purple-500 mb-3"></i>
|
||||
<h5>Gestion des Rôles via Keycloak</h5>
|
||||
<p class="text-600 mt-2">
|
||||
La gestion des rôles et permissions se fait directement via Keycloak Admin Console.
|
||||
</p>
|
||||
<p class="text-600 mt-2">
|
||||
Les rôles disponibles incluent : SUPER_ADMIN, ADMIN_ORG, SECRETAIRE, TRESORIER, MEMBRE, etc.
|
||||
</p>
|
||||
<div class="mt-4">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Accéder à Keycloak Admin" />
|
||||
<ui:param name="icon" value="pi pi-external-link" />
|
||||
<ui:param name="onclick" value="window.open('https://security.lions.dev/admin', '_blank');" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,122 @@
|
||||
<!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:param name="page" value="#{configurationBean}"/>
|
||||
<ui:define name="title">Sauvegarde et Restauration - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formSauvegarde">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-database text-green-500 mr-2"></i>
|
||||
Sauvegarde et Restauration
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Gérez les sauvegardes et restaurez la base de données
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-2 md:mt-0">
|
||||
<p:commandButton value="Créer une sauvegarde"
|
||||
icon="pi pi-save"
|
||||
styleClass="ui-button-success"
|
||||
action="#{configurationBean.creerSauvegarde}"
|
||||
update="@form"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Information système -->
|
||||
<div class="card mb-3">
|
||||
<h5 class="mb-3">État du Système</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="text-600 text-sm mb-1">Dernière sauvegarde</div>
|
||||
<div class="font-bold text-lg">#{configurationBean.derniereSauvegarde}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="text-600 text-sm mb-1">Fréquence</div>
|
||||
<div class="font-bold text-lg">#{configurationBean.frequenceSauvegarde}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="text-600 text-sm mb-1">Rétention</div>
|
||||
<div class="font-bold text-lg">#{configurationBean.retentionSauvegardes} jours</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="text-600 text-sm mb-1">Temps d'activité</div>
|
||||
<div class="font-bold text-lg text-green-500">#{configurationBean.tempsActivite}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des sauvegardes -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Sauvegardes Disponibles</h5>
|
||||
|
||||
<p:dataTable id="dtSauvegardes"
|
||||
var="sauvegarde"
|
||||
value="#{configurationBean.sauvegardes}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25">
|
||||
|
||||
<p:column headerText="Date" sortBy="#{sauvegarde.date}">
|
||||
<h:outputText value="#{sauvegarde.date}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy HH:mm"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Taille" sortBy="#{sauvegarde.taille}">
|
||||
<div class="font-medium">#{sauvegarde.taille}</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{sauvegarde.type}">
|
||||
<p:tag value="#{sauvegarde.type}" severity="info"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{sauvegarde.statut}">
|
||||
<p:tag value="#{sauvegarde.statut}"
|
||||
severity="#{sauvegarde.statutSeverity}"
|
||||
icon="pi #{sauvegarde.statutIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-download"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{configurationBean.telechargerSauvegarde(sauvegarde)}"
|
||||
title="Télécharger"/>
|
||||
<p:commandButton icon="pi pi-refresh"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{configurationBean.restaurerSauvegarde(sauvegarde)}"
|
||||
title="Restaurer"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir restaurer cette sauvegarde ?');"/>
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
action="#{configurationBean.supprimerSauvegarde(sauvegarde)}"
|
||||
title="Supprimer"/>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,53 @@
|
||||
<!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:param name="page" value="#{configurationBean}"/>
|
||||
<ui:define name="title">Gestion des Utilisateurs - 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-users text-blue-500" />
|
||||
<ui:param name="title" value="Gestion des Utilisateurs" />
|
||||
<ui:param name="description" value="Gestion des utilisateurs et de leurs accès via Keycloak" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActions">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Documentation Keycloak" />
|
||||
<ui:param name="icon" value="pi pi-book" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Information -->
|
||||
<div class="card">
|
||||
<div class="text-center p-4">
|
||||
<i class="pi pi-info-circle text-4xl text-blue-500 mb-3"></i>
|
||||
<h5>Gestion des Utilisateurs via Keycloak</h5>
|
||||
<p class="text-600 mt-2">
|
||||
La gestion des utilisateurs se fait directement via Keycloak Admin Console.
|
||||
</p>
|
||||
<p class="text-600 mt-2">
|
||||
Pour accéder à la console d'administration Keycloak, veuillez utiliser l'interface dédiée.
|
||||
</p>
|
||||
<div class="mt-4">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Accéder à Keycloak Admin" />
|
||||
<ui:param name="icon" value="pi pi-external-link" />
|
||||
<ui:param name="onclick" value="window.open('https://security.lions.dev/admin', '_blank');" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,73 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Demandes d'Aide Approuvées - UnionFlow</ui:define>
|
||||
<ui:define name="content">
|
||||
<h:form id="formApproved">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-check-circle text-success mr-2"></i>
|
||||
Demandes d'Aide Approuvées
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Liste des demandes d'aide approuvées et en cours de traitement
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des demandes approuvées -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Demandes Approuvées</h5>
|
||||
|
||||
<p:dataTable id="dtApproved"
|
||||
var="demande"
|
||||
value="#{demandesAideBean.demandesFiltrees}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}">
|
||||
|
||||
<p:column headerText="Demandeur" sortBy="#{demande.demandeur}">
|
||||
<div>
|
||||
<div class="font-medium">#{demande.demandeur}</div>
|
||||
<small class="text-600">#{demande.telephone}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{demande.type}">
|
||||
<p:tag value="#{demande.typeLibelle}" severity="#{demande.typeSeverity}" icon="pi #{demande.typeIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant accordé" sortBy="#{demande.montantAccorde}">
|
||||
<div class="font-bold text-green-500">#{demande.montantAccorde} FCFA</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date approbation" sortBy="#{demande.dateDemande}">
|
||||
<h:outputText value="#{demande.dateDemande}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{demandesAideBean.voirDetails(demande)}"
|
||||
title="Voir détails"/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,327 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">À Propos d'UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête principal -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-6 text-center">
|
||||
<div class="mb-4">
|
||||
<i class="pi pi-heart-fill text-6xl text-primary mb-3"></i>
|
||||
<h1 class="text-900 font-bold text-5xl mb-3">UnionFlow</h1>
|
||||
<p class="text-600 text-xl mb-4">
|
||||
La solution complète de gestion d'associations et organisations
|
||||
</p>
|
||||
<div class="flex align-items-center justify-content-center gap-3">
|
||||
<p:tag value="Version 2.1.3" severity="success" styleClass="text-lg p-2" />
|
||||
<p:tag value="Build 20240118" severity="info" styleClass="text-lg p-2" />
|
||||
<p:tag value="Stable" severity="secondary" styleClass="text-lg p-2" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques système -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">99.9%</div>
|
||||
<div class="text-900 font-semibold mb-1">Disponibilité</div>
|
||||
<div class="text-600 text-sm">30 derniers jours</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">2.3s</div>
|
||||
<div class="text-900 font-semibold mb-1">Temps de Réponse</div>
|
||||
<div class="text-600 text-sm">Moyen</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">15,647</div>
|
||||
<div class="text-900 font-semibold mb-1">Utilisateurs</div>
|
||||
<div class="text-600 text-sm">Actifs ce mois</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">4.8★</div>
|
||||
<div class="text-900 font-semibold mb-1">Satisfaction</div>
|
||||
<div class="text-600 text-sm">Note moyenne</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mission et valeurs -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-card border-round p-4 h-full">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-flag text-primary mr-2"></i>
|
||||
Notre Mission
|
||||
</h4>
|
||||
<p class="text-700 line-height-3 mb-4">
|
||||
UnionFlow a été créé avec la vision de simplifier et moderniser la gestion des associations,
|
||||
coopératives et organisations communautaires. Notre objectif est de fournir des outils
|
||||
puissants et accessibles qui permettent aux dirigeants de se concentrer sur leur mission
|
||||
plutôt que sur la paperasse administrative.
|
||||
</p>
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-4">
|
||||
<h6 class="text-blue-800 font-semibold mb-2">
|
||||
<i class="pi pi-lightbulb mr-2"></i>Vision 2025
|
||||
</h6>
|
||||
<p class="text-blue-700 text-sm mb-0">
|
||||
Devenir la plateforme de référence pour la gestion d'organisations en Afrique
|
||||
de l'Ouest avec plus de 100,000 utilisateurs actifs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-card border-round p-4 h-full">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-heart text-red-500 mr-2"></i>
|
||||
Nos Valeurs
|
||||
</h4>
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<div class="mb-3">
|
||||
<i class="pi pi-users text-blue-500 text-xl mb-2"></i>
|
||||
<h6 class="text-900 font-semibold mb-1">Communauté</h6>
|
||||
<p class="text-600 text-sm">Favoriser l'entraide et la collaboration</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="mb-3">
|
||||
<i class="pi pi-shield text-green-500 text-xl mb-2"></i>
|
||||
<h6 class="text-900 font-semibold mb-1">Confiance</h6>
|
||||
<p class="text-600 text-sm">Sécurité et transparence totales</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="mb-3">
|
||||
<i class="pi pi-cog text-purple-500 text-xl mb-2"></i>
|
||||
<h6 class="text-900 font-semibold mb-1">Innovation</h6>
|
||||
<p class="text-600 text-sm">Solutions modernes et évolutives</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div>
|
||||
<i class="pi pi-globe text-orange-500 text-xl mb-2"></i>
|
||||
<h6 class="text-900 font-semibold mb-1">Accessibilité</h6>
|
||||
<p class="text-600 text-sm">Pour tous, partout, sur tout appareil</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations techniques -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-server mr-2"></i>
|
||||
Informations Système
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<h6 class="text-900 font-semibold mb-3">🏗️ Architecture</h6>
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Framework</div>
|
||||
<div class="text-900 font-semibold">Quarkus 3.15.1</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Interface</div>
|
||||
<div class="text-900 font-semibold">PrimeFaces 14.0.5</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Base de données</div>
|
||||
<div class="text-900 font-semibold">PostgreSQL 15</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Cache</div>
|
||||
<div class="text-900 font-semibold">Redis 7.2</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6">
|
||||
<h6 class="text-900 font-semibold mb-3">🔧 Environnement</h6>
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">JVM</div>
|
||||
<div class="text-900 font-semibold">OpenJDK 21</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Serveur</div>
|
||||
<div class="text-900 font-semibold">Kubernetes</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">CDN</div>
|
||||
<div class="text-900 font-semibold">Cloudflare</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Monitoring</div>
|
||||
<div class="text-900 font-semibold">Prometheus</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Équipe et crédits -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-users mr-2"></i>
|
||||
Équipe de Développement
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4 text-center">
|
||||
<div class="w-6rem h-6rem border-circle bg-primary-100 flex align-items-center justify-content-center mx-auto mb-3">
|
||||
<i class="pi pi-crown text-primary text-3xl"></i>
|
||||
</div>
|
||||
<h6 class="text-900 font-semibold mb-2">Équipe Core</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Architectes et développeurs principaux responsables
|
||||
de la vision produit et de l'architecture technique.
|
||||
</p>
|
||||
<div class="flex align-items-center justify-content-center gap-2">
|
||||
<p:tag value="5 développeurs" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4 text-center">
|
||||
<div class="w-6rem h-6rem border-circle bg-green-100 flex align-items-center justify-content-center mx-auto mb-3">
|
||||
<i class="pi pi-wrench text-green-500 text-3xl"></i>
|
||||
</div>
|
||||
<h6 class="text-900 font-semibold mb-2">Support Technique</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Équipe dédiée à l'assistance utilisateurs,
|
||||
maintenance et résolution des incidents.
|
||||
</p>
|
||||
<div class="flex align-items-center justify-content-center gap-2">
|
||||
<p:tag value="3 techniciens" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4 text-center">
|
||||
<div class="w-6rem h-6rem border-circle bg-purple-100 flex align-items-center justify-content-center mx-auto mb-3">
|
||||
<i class="pi pi-palette text-purple-500 text-3xl"></i>
|
||||
</div>
|
||||
<h6 class="text-900 font-semibold mb-2">UX/UI Design</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Designers spécialisés dans l'expérience utilisateur
|
||||
et l'interface moderne.
|
||||
</p>
|
||||
<div class="flex align-items-center justify-content-center gap-2">
|
||||
<p:tag value="2 designers" severity="help" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact et liens -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4 text-center">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-send mr-2"></i>
|
||||
Nous Contacter
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-envelope text-3xl text-blue-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Email</h6>
|
||||
<p class="text-600 text-sm">contact@unionflow.dev</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-globe text-3xl text-green-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Site Web</h6>
|
||||
<p class="text-600 text-sm">www.unionflow.dev</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-github text-3xl text-purple-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">GitHub</h6>
|
||||
<p class="text-600 text-sm">github.com/unionflow</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-twitter text-3xl text-blue-400 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Twitter</h6>
|
||||
<p class="text-600 text-sm">@unionflow_dev</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 pt-4 border-top-1 border-200">
|
||||
<p class="text-600 text-sm mb-2">
|
||||
© 2024 UnionFlow. Tous droits réservés.
|
||||
</p>
|
||||
<p class="text-500 text-xs">
|
||||
Développé avec ❤️ pour les communautés d'Afrique de l'Ouest par Lions Dev
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,158 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition template="/templates/main-template.xhtml"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<ui:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Demande d'Aide - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formDemande">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-heart text-primary mr-2"></i>
|
||||
Nouvelle Demande d'Aide
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Soumettez une demande d'aide pour vous ou un membre de votre organisation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Formulaire de demande -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Informations de la Demande</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="typeAide" value="Type d'aide *"/>
|
||||
<p:selectOneMenu id="typeAide" value="#{demandesAideBean.nouvelleDemande.type}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionnez 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="urgence" value="Niveau d'urgence *"/>
|
||||
<p:selectOneMenu id="urgence" value="#{demandesAideBean.nouvelleDemande.urgence}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionnez un niveau" itemValue=""/>
|
||||
<f:selectItem itemLabel="Faible" itemValue="FAIBLE"/>
|
||||
<f:selectItem itemLabel="Moyenne" itemValue="MOYENNE"/>
|
||||
<f:selectItem itemLabel="Haute" itemValue="HAUTE"/>
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="demandeur" value="Nom du demandeur *"/>
|
||||
<p:inputText id="demandeur" value="#{demandesAideBean.nouvelleDemande.demandeur}"
|
||||
styleClass="w-full" required="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="telephone" value="Téléphone *"/>
|
||||
<p:inputText id="telephone" value="#{demandesAideBean.nouvelleDemande.telephone}"
|
||||
styleClass="w-full" required="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="email" value="Email"/>
|
||||
<p:inputText id="email" value="#{demandesAideBean.nouvelleDemande.email}"
|
||||
styleClass="w-full"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="localisation" value="Localisation *"/>
|
||||
<p:inputText id="localisation" value="#{demandesAideBean.nouvelleDemande.localisation}"
|
||||
styleClass="w-full" required="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="montantDemande" value="Montant demandé (FCFA) *"/>
|
||||
<p:inputNumber id="montantDemande" value="#{demandesAideBean.nouvelleDemande.montantDemande}"
|
||||
styleClass="w-full" required="true" minValue="0"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="dateLimite" value="Date limite souhaitée"/>
|
||||
<p:calendar id="dateLimite" value="#{demandesAideBean.nouvelleDemande.dateLimite}"
|
||||
styleClass="w-full" pattern="dd/MM/yyyy"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="motif" value="Motif de la demande *"/>
|
||||
<p:inputText id="motif" value="#{demandesAideBean.nouvelleDemande.motif}"
|
||||
styleClass="w-full" required="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="description" value="Description détaillée *"/>
|
||||
<p:inputTextarea id="description" value="#{demandesAideBean.nouvelleDemande.description}"
|
||||
rows="5" styleClass="w-full" required="true"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler"/>
|
||||
<ui:param name="icon" value="pi pi-times"/>
|
||||
<ui:param name="outcome" value="dashboardPage"/>
|
||||
</ui:include>
|
||||
<p:commandButton value="Soumettre la demande"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-success"
|
||||
action="#{demandesAideBean.creerDemande}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) {PF('dlgConfirmation').show();}"/>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
<!-- Dialog de confirmation -->
|
||||
<p:dialog header="Demande soumise" widgetVar="dlgConfirmation" modal="true" width="400">
|
||||
<div class="text-center p-4">
|
||||
<i class="pi pi-check-circle text-green-500 text-6xl mb-3"></i>
|
||||
<h4 class="mb-2">Votre demande a été soumise avec succès</h4>
|
||||
<p class="text-600">Elle sera traitée dans les plus brefs délais.</p>
|
||||
<div class="flex justify-content-center gap-2 mt-4">
|
||||
<p:commandButton value="OK"
|
||||
styleClass="ui-button-primary"
|
||||
onclick="PF('dlgConfirmation').hide(); window.location.href='#{request.contextPath}/pages/secure/dashboard.xhtml';"/>
|
||||
</div>
|
||||
</div>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,170 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Documentation Complète - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-info-circle text-blue-500 mr-3"></i>
|
||||
Documentation Complète
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Documentation technique et fonctionnelle d'UnionFlow
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Version PDF"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-file-pdf" />
|
||||
<p:commandButton value="API Docs"
|
||||
styleClass="p-button-info p-button-outlined"
|
||||
icon="pi pi-code" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">45</div>
|
||||
<div class="text-900 font-semibold mb-1">Articles</div>
|
||||
<div class="text-600 text-sm">Documentation complète</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">12</div>
|
||||
<div class="text-900 font-semibold mb-1">Mis à Jour</div>
|
||||
<div class="text-600 text-sm">Ce mois-ci</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">6</div>
|
||||
<div class="text-900 font-semibold mb-1">Catégories</div>
|
||||
<div class="text-600 text-sm">Thématiques</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">3</div>
|
||||
<div class="text-900 font-semibold mb-1">Langages</div>
|
||||
<div class="text-600 text-sm">API supportées</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Catégories de documentation -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-book text-2xl mr-3 text-blue-500"></i>
|
||||
<p:tag value="GUIDE" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
<h5 class="text-900 font-bold mb-2">Guide Utilisateur</h5>
|
||||
<p class="text-600 text-sm mb-3">Documentation complète pour l'utilisation d'UnionFlow</p>
|
||||
<div class="flex justify-content-between">
|
||||
<span class="text-600 text-xs"><i class="pi pi-clock mr-1"></i>15 min</span>
|
||||
<span class="text-600 text-xs"><i class="pi pi-eye mr-1"></i>250</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-code text-2xl mr-3 text-green-500"></i>
|
||||
<p:tag value="API" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
<h5 class="text-900 font-bold mb-2">API REST</h5>
|
||||
<p class="text-600 text-sm mb-3">Documentation complète de l'API REST UnionFlow</p>
|
||||
<div class="flex justify-content-between">
|
||||
<span class="text-600 text-xs"><i class="pi pi-clock mr-1"></i>25 min</span>
|
||||
<span class="text-600 text-xs"><i class="pi pi-eye mr-1"></i>180</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-cog text-2xl mr-3 text-orange-500"></i>
|
||||
<p:tag value="CONFIG" severity="warning" styleClass="text-xs" />
|
||||
</div>
|
||||
<h5 class="text-900 font-bold mb-2">Configuration</h5>
|
||||
<p class="text-600 text-sm mb-3">Guide de configuration et paramétrage du système</p>
|
||||
<div class="flex justify-content-between">
|
||||
<span class="text-600 text-xs"><i class="pi pi-clock mr-1"></i>20 min</span>
|
||||
<span class="text-600 text-xs"><i class="pi pi-eye mr-1"></i>95</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-wrench text-2xl mr-3 text-red-500"></i>
|
||||
<p:tag value="DEPANNAGE" severity="danger" styleClass="text-xs" />
|
||||
</div>
|
||||
<h5 class="text-900 font-bold mb-2">Dépannage</h5>
|
||||
<p class="text-600 text-sm mb-3">Solutions aux problèmes courants et dépannage</p>
|
||||
<div class="flex justify-content-between">
|
||||
<span class="text-600 text-xs"><i class="pi pi-clock mr-1"></i>30 min</span>
|
||||
<span class="text-600 text-xs"><i class="pi pi-eye mr-1"></i>340</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-link text-2xl mr-3 text-purple-500"></i>
|
||||
<p:tag value="INTEGRATION" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
<h5 class="text-900 font-bold mb-2">Intégrations</h5>
|
||||
<p class="text-600 text-sm mb-3">Intégration avec des systèmes tiers et webhooks</p>
|
||||
<div class="flex justify-content-between">
|
||||
<span class="text-600 text-xs"><i class="pi pi-clock mr-1"></i>35 min</span>
|
||||
<span class="text-600 text-xs"><i class="pi pi-eye mr-1"></i>75</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-shield text-2xl mr-3 text-indigo-500"></i>
|
||||
<p:tag value="SECURITE" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
<h5 class="text-900 font-bold mb-2">Sécurité</h5>
|
||||
<p class="text-600 text-sm mb-3">Bonnes pratiques de sécurité et authentification</p>
|
||||
<div class="flex justify-content-between">
|
||||
<span class="text-600 text-xs"><i class="pi pi-clock mr-1"></i>28 min</span>
|
||||
<span class="text-600 text-xs"><i class="pi pi-eye mr-1"></i>120</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
469
target/classes/META-INF/resources/pages/secure/aide/faq.xhtml
Normal file
469
target/classes/META-INF/resources/pages/secure/aide/faq.xhtml
Normal file
@@ -0,0 +1,469 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Questions Fréquentes - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-question-circle text-blue-500 mr-3"></i>
|
||||
Questions Fréquentes
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Trouvez rapidement des réponses aux questions les plus courantes
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Poser une Question"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-plus"
|
||||
onclick="PF('questionDialog').show()" />
|
||||
<p:commandButton value="Contacter le Support"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-phone" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">47</div>
|
||||
<div class="text-900 font-semibold mb-1">Questions</div>
|
||||
<div class="text-600 text-sm">Dans la FAQ</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">94%</div>
|
||||
<div class="text-900 font-semibold mb-1">Résolution</div>
|
||||
<div class="text-600 text-sm">Taux de satisfaction</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">2.3m</div>
|
||||
<div class="text-900 font-semibold mb-1">Temps Moyen</div>
|
||||
<div class="text-600 text-sm">De réponse</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">8</div>
|
||||
<div class="text-900 font-semibold mb-1">Catégories</div>
|
||||
<div class="text-600 text-sm">Thématiques</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recherche rapide -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h:form id="rechercheForm">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-8">
|
||||
<label for="rechercheQuestion" class="block text-900 font-semibold mb-2">
|
||||
<i class="pi pi-search mr-2"></i>Rechercher dans la FAQ
|
||||
</label>
|
||||
<p:inputText id="rechercheQuestion"
|
||||
placeholder="Tapez votre question ou mots-clés..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12 lg:col-4">
|
||||
<label for="categorieRecherche" class="block text-900 font-semibold mb-2">Catégorie</label>
|
||||
<p:selectOneMenu id="categorieRecherche" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les catégories" itemValue="" />
|
||||
<f:selectItem itemLabel="Compte et Connexion" itemValue="compte" />
|
||||
<f:selectItem itemLabel="Gestion des Membres" itemValue="membres" />
|
||||
<f:selectItem itemLabel="Finances et Cotisations" itemValue="finances" />
|
||||
<f:selectItem itemLabel="Événements" itemValue="evenements" />
|
||||
<f:selectItem itemLabel="Rapports et Exports" itemValue="rapports" />
|
||||
<f:selectItem itemLabel="Administration" itemValue="admin" />
|
||||
<f:selectItem itemLabel="Support Technique" itemValue="technique" />
|
||||
<f:selectItem itemLabel="Sécurité" itemValue="securite" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Questions populaires -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-star-fill text-yellow-500 mr-2"></i>
|
||||
Questions les Plus Populaires
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 hover:surface-200 border-round p-3 cursor-pointer transition-duration-200 mb-3">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-1">Comment réinitialiser mon mot de passe ?</h6>
|
||||
<p class="text-600 text-sm mb-0">Procédure de récupération de compte</p>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2 ml-3">
|
||||
<p:tag value="3.2k vues" severity="info" styleClass="text-xs" />
|
||||
<i class="pi pi-angle-right text-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 hover:surface-200 border-round p-3 cursor-pointer transition-duration-200 mb-3">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-1">Comment exporter la liste des membres ?</h6>
|
||||
<p class="text-600 text-sm mb-0">Export Excel et PDF personnalisés</p>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2 ml-3">
|
||||
<p:tag value="2.8k vues" severity="success" styleClass="text-xs" />
|
||||
<i class="pi pi-angle-right text-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 hover:surface-200 border-round p-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-1">Configurer les notifications email ?</h6>
|
||||
<p class="text-600 text-sm mb-0">Paramétrage des alertes automatiques</p>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2 ml-3">
|
||||
<p:tag value="2.1k vues" severity="warning" styleClass="text-xs" />
|
||||
<i class="pi pi-angle-right text-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 hover:surface-200 border-round p-3 cursor-pointer transition-duration-200 mb-3">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-1">Organiser un événement étape par étape ?</h6>
|
||||
<p class="text-600 text-sm mb-0">Guide complet de création d'événement</p>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2 ml-3">
|
||||
<p:tag value="1.9k vues" severity="help" styleClass="text-xs" />
|
||||
<i class="pi pi-angle-right text-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 hover:surface-200 border-round p-3 cursor-pointer transition-duration-200 mb-3">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-1">Gérer les rôles et permissions ?</h6>
|
||||
<p class="text-600 text-sm mb-0">Attribution des droits d'accès</p>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2 ml-3">
|
||||
<p:tag value="1.7k vues" severity="danger" styleClass="text-xs" />
|
||||
<i class="pi pi-angle-right text-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 hover:surface-200 border-round p-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-1">Problème de connexion lente ?</h6>
|
||||
<p class="text-600 text-sm mb-0">Solutions de performance</p>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2 ml-3">
|
||||
<p:tag value="1.4k vues" severity="info" styleClass="text-xs" />
|
||||
<i class="pi pi-angle-right text-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FAQ par catégories -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-list mr-2"></i>
|
||||
FAQ par Catégories
|
||||
</h4>
|
||||
|
||||
<p:tabView>
|
||||
<!-- Compte et Connexion -->
|
||||
<p:tab title="🔐 Compte et Connexion">
|
||||
<div class="p-0">
|
||||
<div class="mb-4">
|
||||
<h6 class="text-900 font-semibold mb-3 p-3 surface-100 border-round">
|
||||
<i class="pi pi-key mr-2"></i>Authentification et Sécurité
|
||||
</h6>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">Comment créer un compte utilisateur ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Seul un administrateur peut créer de nouveaux comptes utilisateurs. Rendez-vous dans "Administration" → "Gestion Utilisateurs" → "Nouvel Utilisateur".
|
||||
Remplissez les informations obligatoires et attribuez un rôle approprié.
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Voir le Guide"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-book" />
|
||||
<p:commandButton value="Tutoriel Vidéo"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-video" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">Pourquoi ma session expire-t-elle souvent ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Par sécurité, les sessions expirent après 30 minutes d'inactivité. Vous pouvez cocher "Se souvenir de moi"
|
||||
lors de la connexion pour étendre cette durée. Si le problème persiste, videz le cache de votre navigateur.
|
||||
</p>
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-3">
|
||||
<h6 class="text-blue-800 font-semibold mb-2">
|
||||
<i class="pi pi-info-circle mr-2"></i>Conseil Pro
|
||||
</h6>
|
||||
<p class="text-blue-700 text-sm mb-0">
|
||||
Activez les notifications push pour être alerté avant l'expiration de votre session.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">Comment activer l'authentification à deux facteurs ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Allez dans "Mon Espace Personnel" → "Paramètres Compte" → "Sécurité" → "Authentification 2FA".
|
||||
Scannez le QR code avec Google Authenticator ou Authy, puis validez avec le code généré.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Gestion des Membres -->
|
||||
<p:tab title="👥 Gestion des Membres">
|
||||
<div class="p-0">
|
||||
<div class="mb-4">
|
||||
<h6 class="text-900 font-semibold mb-3 p-3 surface-100 border-round">
|
||||
<i class="pi pi-users mr-2"></i>Inscription et Modification
|
||||
</h6>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">Que faire si un membre refuse son adhésion ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Rendez-vous dans "Gestion des Adhésions" → "Validation des Demandes", trouvez la demande concernée
|
||||
et cliquez sur "Rejeter". Ajoutez un motif de refus qui sera envoyé automatiquement au demandeur.
|
||||
</p>
|
||||
<div class="surface-orange-50 border-left-3 border-orange-500 p-3">
|
||||
<h6 class="text-orange-800 font-semibold mb-2">
|
||||
<i class="pi pi-exclamation-triangle mr-2"></i>Important
|
||||
</h6>
|
||||
<p class="text-orange-700 text-sm mb-0">
|
||||
Assurez-vous de documenter les raisons du refus pour le suivi administratif.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">Comment transférer un membre vers une autre organisation ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3">
|
||||
Cette fonctionnalité n'est disponible que pour les Super-Administrateurs. Contactez le support
|
||||
avec les détails du transfert : membre concerné, organisation de destination et justification.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Finances -->
|
||||
<p:tab title="💰 Finances">
|
||||
<div class="p-0">
|
||||
<div class="mb-4">
|
||||
<h6 class="text-900 font-semibold mb-3 p-3 surface-100 border-round">
|
||||
<i class="pi pi-dollar mr-2"></i>Cotisations et Paiements
|
||||
</h6>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">Comment configurer les cotisations automatiques ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Allez dans "Gestion Financière" → "Cotisations" → "Configuration Auto". Définissez le montant,
|
||||
la périodicité (mensuelle/annuelle) et les conditions de prélèvement automatique.
|
||||
</p>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<p:commandButton value="Guide Configuration"
|
||||
styleClass="p-button-outlined p-button-sm w-full"
|
||||
icon="pi pi-cog" />
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<p:commandButton value="Tester la Config"
|
||||
styleClass="p-button-outlined p-button-sm w-full"
|
||||
icon="pi pi-play" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">Un paiement mobile money a échoué, que faire ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Vérifiez d'abord le statut dans "Historique Paiements". Si le paiement est marqué "Échec",
|
||||
cliquez sur "Relancer" ou demandez au membre de réessayer avec un solde suffisant.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Support Technique -->
|
||||
<p:tab title="🔧 Support Technique">
|
||||
<div class="p-0">
|
||||
<div class="mb-4">
|
||||
<h6 class="text-900 font-semibold mb-3 p-3 surface-100 border-round">
|
||||
<i class="pi pi-wrench mr-2"></i>Problèmes Courants
|
||||
</h6>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">L'application est lente ou ne répond pas ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
1. Vérifiez votre connexion internet<br/>
|
||||
2. Videz le cache : Ctrl+Maj+Suppr (Chrome)<br/>
|
||||
3. Redémarrez votre navigateur<br/>
|
||||
4. Essayez en navigation privée
|
||||
</p>
|
||||
<div class="surface-green-50 border-left-3 border-green-500 p-3">
|
||||
<h6 class="text-green-800 font-semibold mb-2">
|
||||
<i class="pi pi-check-circle mr-2"></i>Solution Rapide
|
||||
</h6>
|
||||
<p class="text-green-700 text-sm mb-0">
|
||||
90% des problèmes de lenteur sont résolus en vidant le cache navigateur.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="flex align-items-center justify-content-between cursor-pointer">
|
||||
<h6 class="text-900 font-semibold mb-2">Erreur "Page non trouvée" en naviguant ?</h6>
|
||||
<i class="pi pi-angle-down text-600"></i>
|
||||
</div>
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Cette erreur peut survenir après une mise à jour. Déconnectez-vous complètement,
|
||||
fermez tous les onglets UnionFlow, puis reconnectez-vous.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Question -->
|
||||
<p:dialog id="questionDialog"
|
||||
widgetVar="questionDialog"
|
||||
header="Poser une Nouvelle Question"
|
||||
modal="true"
|
||||
width="700"
|
||||
styleClass="surface-0">
|
||||
<h:form id="questionForm">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="categorieQuestion" class="block text-900 font-semibold mb-2">Catégorie *</label>
|
||||
<p:selectOneMenu id="categorieQuestion" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionnez une catégorie" itemValue="" />
|
||||
<f:selectItem itemLabel="Compte et Connexion" itemValue="compte" />
|
||||
<f:selectItem itemLabel="Gestion des Membres" itemValue="membres" />
|
||||
<f:selectItem itemLabel="Finances" itemValue="finances" />
|
||||
<f:selectItem itemLabel="Événements" itemValue="evenements" />
|
||||
<f:selectItem itemLabel="Support Technique" itemValue="technique" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="autre" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="prioriteQuestion" class="block text-900 font-semibold mb-2">Priorité</label>
|
||||
<p:selectOneMenu id="prioriteQuestion" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Normale" itemValue="normale" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="haute" />
|
||||
<f:selectItem itemLabel="Urgente" itemValue="urgente" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="titreQuestion" class="block text-900 font-semibold mb-2">Titre de votre question *</label>
|
||||
<p:inputText id="titreQuestion"
|
||||
placeholder="Résumez votre question en une phrase"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="detailQuestion" class="block text-900 font-semibold mb-2">Description détaillée *</label>
|
||||
<p:inputTextarea id="detailQuestion"
|
||||
rows="6"
|
||||
placeholder="Décrivez votre problème ou question en détail..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('questionDialog').hide()"
|
||||
type="button" />
|
||||
<p:commandButton value="Envoyer la Question"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-send" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
435
target/classes/META-INF/resources/pages/secure/aide/guide.xhtml
Normal file
435
target/classes/META-INF/resources/pages/secure/aide/guide.xhtml
Normal file
@@ -0,0 +1,435 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Guide Utilisateur - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-book text-primary mr-3"></i>
|
||||
Guide Utilisateur UnionFlow
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Apprenez à utiliser efficacement toutes les fonctionnalités d'UnionFlow
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Version PDF" />
|
||||
<ui:param name="icon" value="pi pi-file-pdf" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<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="onclick" value="PF('rechercheDialog').show()" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Barre de progression des sections lues -->
|
||||
<div class="surface-100 border-round-lg p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h4 class="text-900 font-semibold mb-0">Votre Progression</h4>
|
||||
<span class="text-600 text-sm">#{guideBean.sectionsLues} / #{guideBean.totalSections} sections</span>
|
||||
</div>
|
||||
<p:progressBar value="#{guideBean.pourcentageProgression}"
|
||||
styleClass="mb-2"
|
||||
displayValue="true" />
|
||||
<div class="flex gap-2">
|
||||
<p:tag value="Débutant" severity="info" rendered="#{guideBean.pourcentageProgression lt 30}" />
|
||||
<p:tag value="Intermédiaire" severity="warning" rendered="#{guideBean.pourcentageProgression ge 30 and guideBean.pourcentageProgression lt 70}" />
|
||||
<p:tag value="Avancé" severity="success" rendered="#{guideBean.pourcentageProgression ge 70}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation et contenu principal -->
|
||||
<div class="grid">
|
||||
<!-- Navigation latérale -->
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-section border-round">
|
||||
<h:form id="navigationForm">
|
||||
<!-- Header avec progression -->
|
||||
<div class="surface-card border-round p-4 mb-3">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h5 class="text-900 font-semibold m-0">
|
||||
<i class="pi pi-bookmark text-primary mr-2"></i>
|
||||
Table des Matières
|
||||
</h5>
|
||||
<p:tag value="#{guideBean.sectionsLues}/#{guideBean.totalSections}"
|
||||
severity="info"
|
||||
styleClass="text-xs" />
|
||||
</div>
|
||||
<p:progressBar value="#{guideBean.pourcentageProgression}"
|
||||
showValue="false"
|
||||
styleClass="h-1rem" />
|
||||
<div class="text-600 text-xs mt-1">#{guideBean.pourcentageProgression}% terminé</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation par PanelMenu -->
|
||||
<p:panelMenu styleClass="border-none">
|
||||
|
||||
<!-- Section 1: Premiers pas -->
|
||||
<p:submenu label="🚀 Premiers Pas" icon="pi pi-play">
|
||||
<ui:repeat value="#{guideBean.sectionsPremiersPas}" var="item">
|
||||
<p:menuitem value="#{item.titre}"
|
||||
icon="#{item.lu ? 'pi pi-check-circle text-green-500' : 'pi pi-circle text-300'}"
|
||||
action="#{guideBean.naviguerVers(item.id)}"
|
||||
styleClass="#{item.lu ? 'text-900' : 'text-600'} p-menuitem-link" />
|
||||
</ui:repeat>
|
||||
</p:submenu>
|
||||
|
||||
<!-- Section 2: Gestion des membres -->
|
||||
<p:submenu label="👥 Gestion des Membres" icon="pi pi-users">
|
||||
<ui:repeat value="#{guideBean.sectionsMembres}" var="item">
|
||||
<p:menuitem value="#{item.titre}"
|
||||
icon="#{item.lu ? 'pi pi-check-circle text-green-500' : 'pi pi-circle text-300'}"
|
||||
action="#{guideBean.naviguerVers(item.id)}"
|
||||
styleClass="#{item.lu ? 'text-900' : 'text-600'} p-menuitem-link" />
|
||||
</ui:repeat>
|
||||
</p:submenu>
|
||||
|
||||
<!-- Section 3: Finances -->
|
||||
<p:submenu label="💰 Finances et Cotisations" icon="pi pi-dollar">
|
||||
<ui:repeat value="#{guideBean.sectionsFinances}" var="item">
|
||||
<p:menuitem value="#{item.titre}"
|
||||
icon="#{item.lu ? 'pi pi-check-circle text-green-500' : 'pi pi-circle text-300'}"
|
||||
action="#{guideBean.naviguerVers(item.id)}"
|
||||
styleClass="#{item.lu ? 'text-900' : 'text-600'} p-menuitem-link" />
|
||||
</ui:repeat>
|
||||
</p:submenu>
|
||||
|
||||
<!-- Section 4: Événements -->
|
||||
<p:submenu label="📅 Événements" icon="pi pi-calendar">
|
||||
<ui:repeat value="#{guideBean.sectionsEvenements}" var="item">
|
||||
<p:menuitem value="#{item.titre}"
|
||||
icon="#{item.lu ? 'pi pi-check-circle text-green-500' : 'pi pi-circle text-300'}"
|
||||
action="#{guideBean.naviguerVers(item.id)}"
|
||||
styleClass="#{item.lu ? 'text-900' : 'text-600'} p-menuitem-link" />
|
||||
</ui:repeat>
|
||||
</p:submenu>
|
||||
|
||||
<!-- Section 5: Rapports -->
|
||||
<p:submenu label="📊 Rapports et Analyses" icon="pi pi-chart-bar">
|
||||
<ui:repeat value="#{guideBean.sectionsRapports}" var="item">
|
||||
<p:menuitem value="#{item.titre}"
|
||||
icon="#{item.lu ? 'pi pi-check-circle text-green-500' : 'pi pi-circle text-300'}"
|
||||
action="#{guideBean.naviguerVers(item.id)}"
|
||||
styleClass="#{item.lu ? 'text-900' : 'text-600'} p-menuitem-link" />
|
||||
</ui:repeat>
|
||||
</p:submenu>
|
||||
|
||||
<!-- Section 6: Administration -->
|
||||
<p:submenu label="⚙️ Administration" icon="pi pi-cog">
|
||||
<ui:repeat value="#{guideBean.sectionsAdmin}" var="item">
|
||||
<p:menuitem value="#{item.titre}"
|
||||
icon="#{item.lu ? 'pi pi-check-circle text-green-500' : 'pi pi-circle text-300'}"
|
||||
action="#{guideBean.naviguerVers(item.id)}"
|
||||
styleClass="#{item.lu ? 'text-900' : 'text-600'} p-menuitem-link" />
|
||||
</ui:repeat>
|
||||
</p:submenu>
|
||||
</p:panelMenu>
|
||||
|
||||
<!-- Actions rapides -->
|
||||
<div class="surface-card border-round p-3 mt-3">
|
||||
<div class="text-center">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Tout marquer comme lu" />
|
||||
<ui:param name="icon" value="pi pi-check-square" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-text ui-button-sm w-full" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Réinitialiser progression" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-text ui-button-sm w-full mt-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contenu principal -->
|
||||
<div class="col-12 lg:col-9">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
|
||||
<!-- En-tête de section -->
|
||||
<div class="flex align-items-center justify-content-between mb-4 pb-3 border-bottom-1 border-200">
|
||||
<div>
|
||||
<h3 class="text-900 font-bold text-2xl mb-1">#{guideBean.sectionCourante.titre}</h3>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<p:tag value="#{guideBean.sectionCourante.categorie}" severity="info" styleClass="text-xs" />
|
||||
<span class="text-600 text-sm">#{guideBean.sectionCourante.tempsLecture} min de lecture</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-bookmark" />
|
||||
<ui:param name="title" value="Marquer comme favori" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-share-alt" />
|
||||
<ui:param name="title" value="Partager" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-print" />
|
||||
<ui:param name="title" value="Imprimer" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contenu de la section -->
|
||||
<div class="line-height-3">
|
||||
<ui:fragment rendered="#{guideBean.sectionCourante.id == 'premiers-pas-connexion'}">
|
||||
<h4 class="text-primary font-semibold mb-3">Se connecter à UnionFlow</h4>
|
||||
|
||||
<p class="text-700 mb-4">
|
||||
Pour accéder à UnionFlow, vous devez disposer d'un compte utilisateur avec les droits appropriés.
|
||||
Voici comment procéder pour votre première connexion.
|
||||
</p>
|
||||
|
||||
<div class="surface-100 border-round-lg p-4 mb-4">
|
||||
<h5 class="text-900 font-semibold mb-3">
|
||||
<i class="pi pi-lightbulb text-yellow-500 mr-2"></i>
|
||||
Étapes de connexion
|
||||
</h5>
|
||||
<ol class="text-700 pl-4">
|
||||
<li class="mb-2">Rendez-vous sur la page de connexion UnionFlow</li>
|
||||
<li class="mb-2">Sélectionnez votre type de compte (Membre, Admin, etc.)</li>
|
||||
<li class="mb-2">Saisissez votre email ou nom d'utilisateur</li>
|
||||
<li class="mb-2">Entrez votre mot de passe</li>
|
||||
<li class="mb-2">Cliquez sur "Se connecter"</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="surface-orange-50 border-left-3 border-orange-500 p-4 mb-4">
|
||||
<h6 class="text-orange-800 font-semibold mb-2">
|
||||
<i class="pi pi-exclamation-triangle mr-2"></i>
|
||||
Mot de passe oublié ?
|
||||
</h6>
|
||||
<p class="text-orange-700 mb-0">
|
||||
Cliquez sur "Mot de passe oublié ?" sur la page de connexion pour recevoir
|
||||
un lien de réinitialisation par email.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5 class="text-900 font-semibold mb-3">Types de comptes disponibles</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-100 border-round p-3 text-center">
|
||||
<i class="pi pi-crown text-red-500 text-2xl mb-2"></i>
|
||||
<h6 class="text-900 font-semibold">Super-Admin</h6>
|
||||
<p class="text-600 text-sm mb-0">Accès complet au système</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-100 border-round p-3 text-center">
|
||||
<i class="pi pi-shield text-blue-500 text-2xl mb-2"></i>
|
||||
<h6 class="text-900 font-semibold">Admin Organisation</h6>
|
||||
<p class="text-600 text-sm mb-0">Gestion d'une organisation</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-100 border-round p-3 text-center">
|
||||
<i class="pi pi-user text-green-500 text-2xl mb-2"></i>
|
||||
<h6 class="text-900 font-semibold">Membre</h6>
|
||||
<p class="text-600 text-sm mb-0">Accès membre standard</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:fragment>
|
||||
|
||||
<ui:fragment rendered="#{guideBean.sectionCourante.id == 'membres-inscription'}">
|
||||
<h4 class="text-primary font-semibold mb-3">Inscrire un nouveau membre</h4>
|
||||
|
||||
<p class="text-700 mb-4">
|
||||
L'inscription d'un nouveau membre est une procédure simple qui permet d'ajouter
|
||||
une personne à votre organisation avec toutes les informations nécessaires.
|
||||
</p>
|
||||
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-4 mb-4">
|
||||
<h6 class="text-blue-800 font-semibold mb-2">
|
||||
<i class="pi pi-info-circle mr-2"></i>
|
||||
Prérequis
|
||||
</h6>
|
||||
<ul class="text-blue-700 pl-4 mb-0">
|
||||
<li>Avoir les droits d'administration ou de gestion des membres</li>
|
||||
<li>Disposer des informations personnelles du futur membre</li>
|
||||
<li>Connaître le type d'adhésion souhaité</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h5 class="text-900 font-semibold mb-3">Processus d'inscription</h5>
|
||||
|
||||
<div class="timeline-container mb-4">
|
||||
<div class="flex mb-4">
|
||||
<div class="flex flex-column align-items-center mr-4">
|
||||
<div class="w-3rem h-3rem border-circle bg-blue-500 text-white flex align-items-center justify-content-center font-bold">1</div>
|
||||
<div class="w-1 h-4rem bg-blue-200 mt-2"></div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-2">Accéder au formulaire</h6>
|
||||
<p class="text-600 mb-0">Menu "Gestion des Membres" → "Nouvelle Inscription"</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex mb-4">
|
||||
<div class="flex flex-column align-items-center mr-4">
|
||||
<div class="w-3rem h-3rem border-circle bg-blue-500 text-white flex align-items-center justify-content-center font-bold">2</div>
|
||||
<div class="w-1 h-4rem bg-blue-200 mt-2"></div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-2">Remplir les informations personnelles</h6>
|
||||
<p class="text-600 mb-0">Nom, prénom, date de naissance, contact, adresse</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex mb-4">
|
||||
<div class="flex flex-column align-items-center mr-4">
|
||||
<div class="w-3rem h-3rem border-circle bg-blue-500 text-white flex align-items-center justify-content-center font-bold">3</div>
|
||||
<div class="w-1 h-4rem bg-blue-200 mt-2"></div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-2">Choisir le type d'adhésion</h6>
|
||||
<p class="text-600 mb-0">Membre actif, associé, d'honneur, etc.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<div class="flex flex-column align-items-center mr-4">
|
||||
<div class="w-3rem h-3rem border-circle bg-green-500 text-white flex align-items-center justify-content-center">
|
||||
<i class="pi pi-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h6 class="text-900 font-semibold mb-2">Validation et enregistrement</h6>
|
||||
<p class="text-600 mb-0">Le membre reçoit automatiquement ses identifiants par email</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:fragment>
|
||||
|
||||
<ui:fragment rendered="#{guideBean.sectionCourante.id == 'default'}">
|
||||
<div class="text-center py-8">
|
||||
<i class="pi pi-book text-6xl text-300 mb-4"></i>
|
||||
<h4 class="text-600 mb-3">Sélectionnez une section</h4>
|
||||
<p class="text-500">Choisissez un sujet dans le menu de gauche pour commencer la lecture</p>
|
||||
</div>
|
||||
</ui:fragment>
|
||||
</div>
|
||||
|
||||
<!-- Navigation entre sections -->
|
||||
<div class="flex justify-content-between align-items-center mt-6 pt-4 border-top-1 border-200">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Section précédente" />
|
||||
<ui:param name="icon" value="pi pi-angle-left" />
|
||||
<ui:param name="action" value="#{guideBean.sectionPrecedente}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="rendered" value="#{guideBean.APrecedent}" />
|
||||
</ui:include>
|
||||
|
||||
<div class="flex gap-2" rendered="#{guideBean.sectionCourante.id != 'default'}">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Marquer comme lu" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{guideBean.marquerCommeLu}" />
|
||||
<ui:param name="rendered" value="#{not guideBean.sectionCourante.lu}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Lu" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="true" />
|
||||
<ui:param name="rendered" value="#{guideBean.sectionCourante.lu}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Section suivante" />
|
||||
<ui:param name="icon" value="pi pi-angle-right" />
|
||||
<ui:param name="action" value="#{guideBean.sectionSuivante}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="rendered" value="#{guideBean.ASuivant}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog de recherche -->
|
||||
<p:dialog id="rechercheDialog"
|
||||
widgetVar="rechercheDialog"
|
||||
header="Rechercher dans le guide"
|
||||
modal="true"
|
||||
width="600"
|
||||
styleClass="surface-0">
|
||||
<h:form id="rechercheForm">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label for="termeRecherche" class="block text-900 font-semibold mb-2">
|
||||
<i class="pi pi-search mr-2"></i>Terme à rechercher
|
||||
</label>
|
||||
<p:inputText id="termeRecherche"
|
||||
value="#{guideBean.termeRecherche}"
|
||||
placeholder="Ex: connexion, membre, cotisation..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" update="resultatsRecherche" delay="300" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
|
||||
<h:panelGroup id="resultatsRecherche" layout="block">
|
||||
<ui:repeat value="#{guideBean.resultatsRecherche}" var="resultat" rendered="#{not empty guideBean.termeRecherche}">
|
||||
<div class="surface-100 border-round p-3 mb-3 cursor-pointer hover:surface-200 transition-duration-200"
|
||||
onclick="#{guideBean.naviguerVers(resultat.id)}; PF('rechercheDialog').hide();">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#{resultat.titre}</h6>
|
||||
<p class="text-600 text-sm mb-1">#{resultat.description}</p>
|
||||
<p:tag value="#{resultat.categorie}" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
<i class="pi pi-angle-right text-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<div class="text-center py-4" rendered="#{not empty guideBean.termeRecherche and empty guideBean.resultatsRecherche}">
|
||||
<i class="pi pi-search text-3xl text-300 mb-2"></i>
|
||||
<p class="text-600">Aucun résultat trouvé pour "#{guideBean.termeRecherche}"</p>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition template="/templates/main-template.xhtml"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<ui:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Historique des Demandes d'Aide - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- Redirection vers history.xhtml (WOU/DRY - réutiliser la même page) -->
|
||||
<h:form>
|
||||
<p:commandButton value="Voir l'historique"
|
||||
action="#{demandesAideBean.voirHistorique()}"
|
||||
styleClass="ui-button-primary"/>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,132 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Historique des Demandes d'Aide - UnionFlow</ui:define>
|
||||
<ui:define name="content">
|
||||
<h:form id="formHistory">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-history text-primary mr-2"></i>
|
||||
Historique des Demandes d'Aide
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Consultez l'historique complet de toutes les demandes d'aide
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres -->
|
||||
<div class="card mb-3">
|
||||
<h5 class="mb-3">Filtres</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<p:outputLabel for="statutFilter" value="Statut"/>
|
||||
<p:selectOneMenu id="statutFilter" value="#{demandesAideBean.filtres.statut}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous" itemValue=""/>
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE"/>
|
||||
<f:selectItem itemLabel="Approuvée" itemValue="APPROUVEE"/>
|
||||
<f:selectItem itemLabel="Rejetée" itemValue="REJETEE"/>
|
||||
<p:ajax event="change" update="dtHistory"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<p:outputLabel for="typeFilter" value="Type"/>
|
||||
<p:selectOneMenu id="typeFilter" value="#{demandesAideBean.filtres.type}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous" itemValue=""/>
|
||||
<f:selectItem itemLabel="Médicale" itemValue="AIDE_MEDICALE"/>
|
||||
<f:selectItem itemLabel="Alimentaire" itemValue="AIDE_ALIMENTAIRE"/>
|
||||
<f:selectItem itemLabel="Éducative" itemValue="AIDE_EDUCATIVE"/>
|
||||
<p:ajax event="change" update="dtHistory"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<p:outputLabel for="dateDebut" value="Date début"/>
|
||||
<p:calendar id="dateDebut" value="#{demandesAideBean.filtres.dateDebut}"
|
||||
styleClass="w-full" pattern="dd/MM/yyyy">
|
||||
<p:ajax event="dateSelect" update="dtHistory"/>
|
||||
</p:calendar>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<p:outputLabel for="dateFin" value="Date fin"/>
|
||||
<p:calendar id="dateFin" value="#{demandesAideBean.filtres.dateFin}"
|
||||
styleClass="w-full" pattern="dd/MM/yyyy">
|
||||
<p:ajax event="dateSelect" update="dtHistory"/>
|
||||
</p:calendar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<p:commandButton value="Rechercher"
|
||||
icon="pi pi-search"
|
||||
styleClass="ui-button-primary"
|
||||
action="#{demandesAideBean.rechercher}"
|
||||
update="dtHistory"/>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{demandesAideBean.reinitialiserFiltres}"
|
||||
update="@form"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Historique Complet</h5>
|
||||
|
||||
<p:dataTable id="dtHistory"
|
||||
var="demande"
|
||||
value="#{demandesAideBean.demandesFiltrees}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}">
|
||||
|
||||
<p:column headerText="Demandeur" sortBy="#{demande.demandeur}">
|
||||
<div>
|
||||
<div class="font-medium">#{demande.demandeur}</div>
|
||||
<small class="text-600">#{demande.localisation}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{demande.type}">
|
||||
<p:tag value="#{demande.typeLibelle}" severity="#{demande.typeSeverity}" icon="pi #{demande.typeIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{demande.montantDemande}">
|
||||
<div class="font-bold text-green-500">#{demande.montantDemande} FCFA</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{demande.statut}">
|
||||
<p:tag value="#{demande.statutLibelle}"
|
||||
severity="#{demande.statutSeverity}"
|
||||
icon="pi #{demande.statutIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date" sortBy="#{demande.dateDemande}">
|
||||
<h:outputText value="#{demande.dateDemande}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{demandesAideBean.voirDetails(demande)}"
|
||||
title="Voir détails"/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,401 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Nouveautés - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-sparkles text-purple-500 mr-3"></i>
|
||||
Nouveautés UnionFlow
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Découvrez les dernières fonctionnalités, améliorations et corrections
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="S'abonner aux Notifications"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-bell" />
|
||||
<p:commandButton value="Historique Complet"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-history" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques des versions -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">v2.1.3</div>
|
||||
<div class="text-900 font-semibold mb-1">Version Actuelle</div>
|
||||
<div class="text-600 text-sm">Stable</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">47</div>
|
||||
<div class="text-900 font-semibold mb-1">Nouvelles Fonctionnalités</div>
|
||||
<div class="text-600 text-sm">Cette année</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">134</div>
|
||||
<div class="text-900 font-semibold mb-1">Améliorations</div>
|
||||
<div class="text-600 text-sm">Depuis v2.0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-red-500 mb-2">89</div>
|
||||
<div class="text-900 font-semibold mb-1">Corrections</div>
|
||||
<div class="text-600 text-sm">Bugs résolus</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h:form id="filtresForm">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="typeChangement" class="block text-900 font-semibold mb-2">Type de changement</label>
|
||||
<p:selectOneMenu id="typeChangement" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les changements" itemValue="" />
|
||||
<f:selectItem itemLabel="Nouvelles fonctionnalités" itemValue="feature" />
|
||||
<f:selectItem itemLabel="Améliorations" itemValue="enhancement" />
|
||||
<f:selectItem itemLabel="Corrections de bugs" itemValue="bugfix" />
|
||||
<f:selectItem itemLabel="Sécurité" itemValue="security" />
|
||||
<f:selectItem itemLabel="Performance" itemValue="performance" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="versionFilter" class="block text-900 font-semibold mb-2">Version</label>
|
||||
<p:selectOneMenu id="versionFilter" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les versions" itemValue="" />
|
||||
<f:selectItem itemLabel="v2.1.x" itemValue="2.1" />
|
||||
<f:selectItem itemLabel="v2.0.x" itemValue="2.0" />
|
||||
<f:selectItem itemLabel="v1.9.x" itemValue="1.9" />
|
||||
<f:selectItem itemLabel="v1.8.x" itemValue="1.8" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="periodeFilter" class="block text-900 font-semibold mb-2">Période</label>
|
||||
<p:selectOneMenu id="periodeFilter" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les périodes" itemValue="" />
|
||||
<f:selectItem itemLabel="Ce mois-ci" itemValue="mois" />
|
||||
<f:selectItem itemLabel="3 derniers mois" itemValue="trimestre" />
|
||||
<f:selectItem itemLabel="Cette année" itemValue="annee" />
|
||||
<f:selectItem itemLabel="Année dernière" itemValue="annee_precedente" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="rechercheNouveautes" class="block text-900 font-semibold mb-2">Rechercher</label>
|
||||
<p:inputText id="rechercheNouveautes"
|
||||
placeholder="Fonctionnalité, mot-clé..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Version actuelle highlight -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4 border-2 border-primary">
|
||||
<div class="flex align-items-center gap-3 mb-4">
|
||||
<div class="w-4rem h-4rem border-circle bg-primary flex align-items-center justify-content-center">
|
||||
<i class="pi pi-star text-white text-2xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-primary font-bold text-2xl mb-1">Version 2.1.3 - Dernière version stable</h4>
|
||||
<p class="text-600 mb-0">Publiée le 18 janvier 2024 • Mise à jour de sécurité importante</p>
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
<p:tag value="ACTUELLE" severity="success" styleClass="text-lg p-2" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-8">
|
||||
<h6 class="text-900 font-semibold mb-3">🔒 Améliorations de Sécurité</h6>
|
||||
<ul class="list-none p-0 m-0 mb-4">
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-check-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700">Correction de faille XSS dans les formulaires de commentaires</span>
|
||||
</li>
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-check-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700">Mise à jour des dépendances de sécurité critiques</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-check-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700">Renforcement de la validation des uploads de fichiers</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h6 class="text-900 font-semibold mb-3">🐛 Corrections de Bugs</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-check-circle text-blue-500 mr-2 mt-1"></i>
|
||||
<span class="text-700">Résolution du problème d'export Excel sur Chrome 120+</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-check-circle text-blue-500 mr-2 mt-1"></i>
|
||||
<span class="text-700">Correction de l'affichage des dates sur mobile</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-3">
|
||||
<h6 class="text-900 font-semibold mb-3">📊 Impact de la mise à jour</h6>
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-600 text-sm">Sécurité</span>
|
||||
<p:tag value="CRITIQUE" severity="danger" styleClass="text-xs" />
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-600 text-sm">Compatibilité</span>
|
||||
<p:tag value="100%" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span class="text-600 text-sm">Taille</span>
|
||||
<span class="text-600 text-sm">15.2 MB</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historique des versions -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-history mr-2"></i>
|
||||
Historique des Versions
|
||||
</h4>
|
||||
|
||||
<!-- Version 2.1.2 -->
|
||||
<div class="surface-100 border-round p-4 mb-4">
|
||||
<div class="flex align-items-center gap-3 mb-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-blue-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-code text-blue-600 text-xl"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h5 class="text-900 font-bold mb-1">Version 2.1.2</h5>
|
||||
<p class="text-600 text-sm mb-0">Publiée le 3 janvier 2024</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:tag value="STABLE" severity="success" styleClass="text-xs" />
|
||||
<p:tag value="MAJEURE" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<h6 class="text-blue-600 font-semibold mb-2">✨ Nouvelles Fonctionnalités</h6>
|
||||
<ul class="list-none p-0 m-0 mb-3">
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-plus-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Système de notifications en temps réel</span>
|
||||
</li>
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-plus-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Export PDF avec signature électronique</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-plus-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Interface de gestion des rôles avancée</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 lg:col-6">
|
||||
<h6 class="text-orange-600 font-semibold mb-2">⚡ Améliorations</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-arrow-up text-orange-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Performance des rapports (+40%)</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-arrow-up text-orange-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Interface mobile optimisée</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Version 2.1.1 -->
|
||||
<div class="surface-100 border-round p-4 mb-4">
|
||||
<div class="flex align-items-center gap-3 mb-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-green-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-wrench text-green-600 text-xl"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h5 class="text-900 font-bold mb-1">Version 2.1.1</h5>
|
||||
<p class="text-600 text-sm mb-0">Publiée le 15 décembre 2023</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:tag value="MAINTENANCE" severity="warning" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h6 class="text-red-600 font-semibold mb-2">🐛 Corrections</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-times-circle text-red-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Correction du bug d'affichage dans les tableaux de données</span>
|
||||
</li>
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-times-circle text-red-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Résolution des problèmes de connexion SSO</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-times-circle text-red-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Correction des erreurs de validation de formulaires</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Version 2.1.0 -->
|
||||
<div class="surface-100 border-round p-4 mb-4">
|
||||
<div class="flex align-items-center gap-3 mb-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-purple-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-star text-purple-600 text-xl"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h5 class="text-900 font-bold mb-1">Version 2.1.0 - Release Majeure</h5>
|
||||
<p class="text-600 text-sm mb-0">Publiée le 1er décembre 2023</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:tag value="MAJEURE" severity="success" styleClass="text-xs" />
|
||||
<p:tag value="LTS" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-3 mb-3">
|
||||
<h6 class="text-blue-800 font-semibold mb-2">
|
||||
<i class="pi pi-info-circle mr-2"></i>Points forts de cette version
|
||||
</h6>
|
||||
<p class="text-blue-700 text-sm mb-0">
|
||||
Version LTS avec support étendu jusqu'en décembre 2025.
|
||||
Architecture modernisée et nouvelles API REST.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<h6 class="text-blue-600 font-semibold mb-2">✨ Nouvelles Fonctionnalités</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-start mb-1">
|
||||
<i class="pi pi-plus-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">API REST v2 complète</span>
|
||||
</li>
|
||||
<li class="flex align-items-start mb-1">
|
||||
<i class="pi pi-plus-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Workflow personnalisables</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-plus-circle text-green-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Tableau de bord configurable</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<h6 class="text-orange-600 font-semibold mb-2">⚡ Améliorations</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-start mb-1">
|
||||
<i class="pi pi-arrow-up text-orange-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Performances globales +60%</span>
|
||||
</li>
|
||||
<li class="flex align-items-start mb-1">
|
||||
<i class="pi pi-arrow-up text-orange-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Sécurité renforcée (2FA)</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-arrow-up text-orange-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">UX/UI redesignée</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<h6 class="text-purple-600 font-semibold mb-2">🔧 Technique</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-start mb-1">
|
||||
<i class="pi pi-cog text-purple-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Migration Quarkus 3.x</span>
|
||||
</li>
|
||||
<li class="flex align-items-start mb-1">
|
||||
<i class="pi pi-cog text-purple-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Base de données optimisée</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-cog text-purple-500 mr-2 mt-1"></i>
|
||||
<span class="text-700 text-sm">Cache distribué Redis</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Version 2.0.5 -->
|
||||
<div class="surface-100 border-round p-4 opacity-70">
|
||||
<div class="flex align-items-center gap-3 mb-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-gray-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-history text-gray-600 text-xl"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h5 class="text-900 font-bold mb-1">Version 2.0.5</h5>
|
||||
<p class="text-600 text-sm mb-0">Publiée le 10 novembre 2023 • Support terminé</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:tag value="EOL" severity="danger" styleClass="text-xs" />
|
||||
<p:tag value="ARCHIVÉE" severity="secondary" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">
|
||||
Dernière version de la branche 2.0.x. Migration vers 2.1.x recommandée pour les corrections de sécurité.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Pagination ou Load More -->
|
||||
<div class="text-center mt-4">
|
||||
<p:commandButton value="Charger Plus de Versions"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-angle-down" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,79 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Mes Demandes d'Aide - UnionFlow</ui:define>
|
||||
<ui:define name="content">
|
||||
<h:form id="formRequests">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-list text-primary mr-2"></i>
|
||||
Mes Demandes d'Aide
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Consultez l'état de vos demandes d'aide
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-2 md:mt-0">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouvelle demande"/>
|
||||
<ui:param name="icon" value="pi pi-plus"/>
|
||||
<ui:param name="outcome" value="aideDemandePage"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des demandes -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Historique de mes Demandes</h5>
|
||||
|
||||
<p:dataTable id="dtDemandes"
|
||||
var="demande"
|
||||
value="#{demandesAideBean.demandesFiltrees}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}">
|
||||
|
||||
<p:column headerText="Type" sortBy="#{demande.type}">
|
||||
<p:tag value="#{demande.typeLibelle}" severity="#{demande.typeSeverity}" icon="pi #{demande.typeIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{demande.montantDemande}">
|
||||
<div class="font-bold text-green-500">#{demande.montantDemande} FCFA</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{demande.statut}">
|
||||
<p:tag value="#{demande.statutLibelle}"
|
||||
severity="#{demande.statutSeverity}"
|
||||
icon="pi #{demande.statutIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date" sortBy="#{demande.dateDemande}">
|
||||
<h:outputText value="#{demande.dateDemande}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{demandesAideBean.voirDetails(demande)}"
|
||||
title="Voir détails"/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition template="/templates/main-template.xhtml"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<ui:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Statistiques des Demandes d'Aide - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formStatistiques">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-chart-bar text-primary mr-2"></i>
|
||||
Statistiques des Demandes d'Aide
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Analyse et statistiques détaillées des demandes d'aide
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-2 md:mt-0">
|
||||
<p:commandButton value="Actualiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{demandesAideBean.actualiser}"
|
||||
update="@form"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques principales -->
|
||||
<div class="grid mb-3">
|
||||
<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">#{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: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-inbox 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">#{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: 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">#{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: 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-purple-100 border-left-3 border-purple-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-purple-900 font-bold text-2xl">#{demandesAideBean.statistiques.montantTotalAide}</div>
|
||||
<div class="text-purple-700">Montant Total</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>
|
||||
|
||||
<!-- Répartition par type -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Répartition par Type d'Aide</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="surface-100 border-round p-4 text-center">
|
||||
<i class="pi pi-chart-pie text-6xl text-blue-500 mb-3"></i>
|
||||
<p class="text-600">Graphique de répartition par type</p>
|
||||
<small class="text-500">À implémenter avec PrimeNG Charts</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="surface-100 border-round p-4 text-center">
|
||||
<i class="pi pi-chart-bar text-6xl text-green-500 mb-3"></i>
|
||||
<p class="text-600">Graphique de répartition par statut</p>
|
||||
<small class="text-500">À implémenter avec PrimeNG Charts</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,463 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Suggestions et Feedback - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-lightbulb text-yellow-500 mr-3"></i>
|
||||
Suggestions et Feedback
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Partagez vos idées pour améliorer UnionFlow et votez pour les suggestions de la communauté
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouvelle Suggestion"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-plus"
|
||||
onclick="PF('nouvelleSuggestionDialog').show()" />
|
||||
<p:commandButton value="Mes Suggestions"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-user" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques communauté -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">247</div>
|
||||
<div class="text-900 font-semibold mb-1">Suggestions</div>
|
||||
<div class="text-600 text-sm">Soumises</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">43</div>
|
||||
<div class="text-900 font-semibold mb-1">Implémentées</div>
|
||||
<div class="text-600 text-sm">Dans la v2.0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">1,523</div>
|
||||
<div class="text-900 font-semibold mb-1">Votes</div>
|
||||
<div class="text-600 text-sm">Ce mois-ci</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">156</div>
|
||||
<div class="text-900 font-semibold mb-1">Contributeurs</div>
|
||||
<div class="text-600 text-sm">Actifs</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et tri -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h:form id="filtresForm">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="statutSuggestion" class="block text-900 font-semibold mb-2">Statut</label>
|
||||
<p:selectOneMenu id="statutSuggestion" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Nouvelle" itemValue="nouvelle" />
|
||||
<f:selectItem itemLabel="En cours d'évaluation" itemValue="evaluation" />
|
||||
<f:selectItem itemLabel="Approuvée" itemValue="approuvee" />
|
||||
<f:selectItem itemLabel="En développement" itemValue="developpement" />
|
||||
<f:selectItem itemLabel="Implémentée" itemValue="implementee" />
|
||||
<f:selectItem itemLabel="Rejetée" itemValue="rejetee" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="categorieSuggestion" class="block text-900 font-semibold mb-2">Catégorie</label>
|
||||
<p:selectOneMenu id="categorieSuggestion" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les catégories" itemValue="" />
|
||||
<f:selectItem itemLabel="Interface Utilisateur" itemValue="ui" />
|
||||
<f:selectItem itemLabel="Fonctionnalité" itemValue="feature" />
|
||||
<f:selectItem itemLabel="Performance" itemValue="performance" />
|
||||
<f:selectItem itemLabel="Sécurité" itemValue="securite" />
|
||||
<f:selectItem itemLabel="Intégration" itemValue="integration" />
|
||||
<f:selectItem itemLabel="Mobile" itemValue="mobile" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="triSuggestion" class="block text-900 font-semibold mb-2">Trier par</label>
|
||||
<p:selectOneMenu id="triSuggestion" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Plus récentes" itemValue="date_desc" />
|
||||
<f:selectItem itemLabel="Plus anciennes" itemValue="date_asc" />
|
||||
<f:selectItem itemLabel="Plus votées" itemValue="votes_desc" />
|
||||
<f:selectItem itemLabel="Moins votées" itemValue="votes_asc" />
|
||||
<f:selectItem itemLabel="Statut" itemValue="statut" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="rechercheSuggestion" class="block text-900 font-semibold mb-2">Rechercher</label>
|
||||
<p:inputText id="rechercheSuggestion"
|
||||
placeholder="Mots-clés..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Suggestions populaires -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-star-fill text-yellow-500 mr-2"></i>
|
||||
Suggestions les Plus Populaires
|
||||
</h4>
|
||||
|
||||
<!-- Suggestion 1 - Très populaire -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-4 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-start justify-content-between mb-3">
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center gap-2 mb-2">
|
||||
<h6 class="text-900 font-semibold mb-0">Mode sombre pour l'interface</h6>
|
||||
<p:tag value="EN DÉVELOPPEMENT" severity="info" styleClass="text-xs" />
|
||||
<p:tag value="INTERFACE" severity="help" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">Proposé par Marie Dubois • il y a 2 semaines</p>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Ajouter un thème sombre à l'interface pour réduire la fatigue visuelle lors de longues sessions de travail.
|
||||
Particulièrement utile pour les utilisateurs travaillant en soirée ou dans des environnements peu éclairés.
|
||||
</p>
|
||||
<div class="flex align-items-center gap-3">
|
||||
<span class="text-600 text-sm">
|
||||
<i class="pi pi-comments mr-1"></i>24 commentaires
|
||||
</span>
|
||||
<span class="text-600 text-sm">
|
||||
<i class="pi pi-eye mr-1"></i>847 vues
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center ml-4">
|
||||
<div class="surface-blue-100 border-round p-3 cursor-pointer hover:surface-blue-200 transition-duration-200">
|
||||
<i class="pi pi-thumbs-up text-blue-600 text-xl mb-1"></i>
|
||||
<div class="text-blue-600 font-bold text-lg">156</div>
|
||||
<div class="text-blue-600 text-xs">votes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-3">
|
||||
<p class="text-blue-700 text-sm mb-0">
|
||||
<i class="pi pi-info-circle mr-2"></i>
|
||||
<strong>Mise à jour:</strong> Cette fonctionnalité est en cours de développement et sera disponible dans la version 2.2.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Suggestion 2 - Populaire -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-4 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-start justify-content-between mb-3">
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center gap-2 mb-2">
|
||||
<h6 class="text-900 font-semibold mb-0">Export PDF personnalisé avec logo</h6>
|
||||
<p:tag value="APPROUVÉE" severity="success" styleClass="text-xs" />
|
||||
<p:tag value="FONCTIONNALITÉ" severity="warning" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">Proposé par Thomas Martin • il y a 1 mois</p>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Permettre l'ajout du logo de l'organisation sur tous les exports PDF (rapports, listes membres, etc.)
|
||||
pour une meilleure présentation des documents officiels.
|
||||
</p>
|
||||
<div class="flex align-items-center gap-3">
|
||||
<span class="text-600 text-sm">
|
||||
<i class="pi pi-comments mr-1"></i>18 commentaires
|
||||
</span>
|
||||
<span class="text-600 text-sm">
|
||||
<i class="pi pi-eye mr-1"></i>523 vues
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center ml-4">
|
||||
<div class="surface-green-100 border-round p-3 cursor-pointer hover:surface-green-200 transition-duration-200">
|
||||
<i class="pi pi-thumbs-up text-green-600 text-xl mb-1"></i>
|
||||
<div class="text-green-600 font-bold text-lg">98</div>
|
||||
<div class="text-green-600 text-xs">votes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Suggestion 3 - Récente -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-start justify-content-between mb-3">
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center gap-2 mb-2">
|
||||
<h6 class="text-900 font-semibold mb-0">Notifications push mobiles</h6>
|
||||
<p:tag value="NOUVELLE" severity="secondary" styleClass="text-xs" />
|
||||
<p:tag value="MOBILE" severity="info" styleClass="text-xs" />
|
||||
<p:tag value="NOUVEAU" severity="danger" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">Proposé par Sophie Leroy • il y a 3 jours</p>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Recevoir des notifications push sur mobile pour les événements importants :
|
||||
nouvelles adhésions, rappels de cotisations, événements à venir, etc.
|
||||
</p>
|
||||
<div class="flex align-items-center gap-3">
|
||||
<span class="text-600 text-sm">
|
||||
<i class="pi pi-comments mr-1"></i>7 commentaires
|
||||
</span>
|
||||
<span class="text-600 text-sm">
|
||||
<i class="pi pi-eye mr-1"></i>156 vues
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center ml-4">
|
||||
<div class="surface-purple-100 border-round p-3 cursor-pointer hover:surface-purple-200 transition-duration-200">
|
||||
<i class="pi pi-thumbs-up text-purple-600 text-xl mb-1"></i>
|
||||
<div class="text-purple-600 font-bold text-lg">34</div>
|
||||
<div class="text-purple-600 text-xs">votes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mes contributions -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-user mr-2"></i>
|
||||
Mes Contributions
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<!-- Ma suggestion 1 -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h6 class="text-900 font-semibold mb-0">Import CSV automatisé</h6>
|
||||
<p:tag value="EN ÉVALUATION" severity="warning" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">Soumise il y a 1 semaine</p>
|
||||
<p class="text-700 text-sm mb-3">
|
||||
Permettre l'import automatique de fichiers CSV pour les inscriptions en masse...
|
||||
</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-thumbs-up text-blue-500"></i>
|
||||
<span class="text-600 text-sm">12 votes</span>
|
||||
</div>
|
||||
<p:commandButton value="Modifier"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-pencil" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ma suggestion 2 -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h6 class="text-900 font-semibold mb-0">Calendrier partagé équipe</h6>
|
||||
<p:tag value="IMPLÉMENTÉE" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">Soumise il y a 3 mois</p>
|
||||
<p class="text-700 text-sm mb-3">
|
||||
Calendrier collaboratif pour planifier les événements et réunions...
|
||||
</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-thumbs-up text-green-500"></i>
|
||||
<span class="text-600 text-sm">67 votes</span>
|
||||
</div>
|
||||
<p:commandButton value="Voir Implémentation"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-external-link" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Roadmap des suggestions -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-map mr-2"></i>
|
||||
Roadmap des Suggestions
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-blue-600 font-semibold mb-3">
|
||||
<i class="pi pi-calendar mr-2"></i>Version 2.2 (Q2 2024)
|
||||
</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-center mb-2">
|
||||
<i class="pi pi-check-circle text-green-500 mr-2"></i>
|
||||
<span class="text-700 text-sm">Mode sombre</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-2">
|
||||
<i class="pi pi-check-circle text-green-500 mr-2"></i>
|
||||
<span class="text-700 text-sm">Export PDF avec logo</span>
|
||||
</li>
|
||||
<li class="flex align-items-center">
|
||||
<i class="pi pi-clock text-orange-500 mr-2"></i>
|
||||
<span class="text-700 text-sm">Recherche avancée globale</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-purple-600 font-semibold mb-3">
|
||||
<i class="pi pi-calendar mr-2"></i>Version 2.3 (Q3 2024)
|
||||
</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-center mb-2">
|
||||
<i class="pi pi-clock text-orange-500 mr-2"></i>
|
||||
<span class="text-700 text-sm">Notifications push mobiles</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-2">
|
||||
<i class="pi pi-clock text-orange-500 mr-2"></i>
|
||||
<span class="text-700 text-sm">API REST publique</span>
|
||||
</li>
|
||||
<li class="flex align-items-center">
|
||||
<i class="pi pi-clock text-orange-500 mr-2"></i>
|
||||
<span class="text-700 text-sm">Tableau de bord personnalisable</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-orange-600 font-semibold mb-3">
|
||||
<i class="pi pi-calendar mr-2"></i>Version 3.0 (Q4 2024)
|
||||
</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-center mb-2">
|
||||
<i class="pi pi-circle text-300 mr-2"></i>
|
||||
<span class="text-700 text-sm">Application mobile native</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-2">
|
||||
<i class="pi pi-circle text-300 mr-2"></i>
|
||||
<span class="text-700 text-sm">Intelligence artificielle</span>
|
||||
</li>
|
||||
<li class="flex align-items-center">
|
||||
<i class="pi pi-circle text-300 mr-2"></i>
|
||||
<span class="text-700 text-sm">Intégrations avancées</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Suggestion -->
|
||||
<p:dialog id="nouvelleSuggestionDialog"
|
||||
widgetVar="nouvelleSuggestionDialog"
|
||||
header="Soumettre une Nouvelle Suggestion"
|
||||
modal="true"
|
||||
width="800"
|
||||
styleClass="surface-0">
|
||||
<h:form id="nouvelleSuggestionForm">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="categorieSugg" class="block text-900 font-semibold mb-2">Catégorie *</label>
|
||||
<p:selectOneMenu id="categorieSugg" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionnez une catégorie" itemValue="" />
|
||||
<f:selectItem itemLabel="Interface Utilisateur" itemValue="ui" />
|
||||
<f:selectItem itemLabel="Nouvelle Fonctionnalité" itemValue="feature" />
|
||||
<f:selectItem itemLabel="Amélioration Performance" itemValue="performance" />
|
||||
<f:selectItem itemLabel="Sécurité" itemValue="securite" />
|
||||
<f:selectItem itemLabel="Intégration Externe" itemValue="integration" />
|
||||
<f:selectItem itemLabel="Application Mobile" itemValue="mobile" />
|
||||
<f:selectItem itemLabel="Rapports et Analytics" itemValue="reporting" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="prioriteSugg" class="block text-900 font-semibold mb-2">Priorité estimée</label>
|
||||
<p:selectOneMenu id="prioriteSugg" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Basse" itemValue="basse" />
|
||||
<f:selectItem itemLabel="Moyenne" itemValue="moyenne" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="haute" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="critique" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="titreSugg" class="block text-900 font-semibold mb-2">Titre de votre suggestion *</label>
|
||||
<p:inputText id="titreSugg"
|
||||
placeholder="Résumez votre idée en une phrase claire"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="descriptionSugg" class="block text-900 font-semibold mb-2">Description détaillée *</label>
|
||||
<p:inputTextarea id="descriptionSugg"
|
||||
rows="6"
|
||||
placeholder="Décrivez votre suggestion : problème rencontré, solution proposée, bénéfices attendus..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="justificationSugg" class="block text-900 font-semibold mb-2">Justification métier</label>
|
||||
<p:inputTextarea id="justificationSugg"
|
||||
rows="3"
|
||||
placeholder="Expliquez pourquoi cette fonctionnalité serait utile et pour quels utilisateurs..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label class="block text-900 font-semibold mb-2">Maquettes ou références (optionnel)</label>
|
||||
<p:fileUpload mode="basic"
|
||||
multiple="true"
|
||||
chooseLabel="Choisir des fichiers"
|
||||
styleClass="w-full" />
|
||||
<small class="text-500">Images, schémas, liens vers des exemples similaires (max 5MB par fichier)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('nouvelleSuggestionDialog').hide()"
|
||||
type="button" />
|
||||
<p:commandButton value="Soumettre la Suggestion"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-send" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,322 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Contacter le Support - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-phone text-green-500 mr-3"></i>
|
||||
Contacter le Support
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Notre équipe support est là pour vous aider
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouveau Ticket"
|
||||
styleClass="p-button-success"
|
||||
icon="pi pi-plus"
|
||||
onclick="PF('ticketDialog').show()" />
|
||||
<p:commandButton value="Base de Connaissances"
|
||||
styleClass="p-button-info p-button-outlined"
|
||||
icon="pi pi-book" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations de contact -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-4 text-center" style="min-height: 9rem">
|
||||
<i class="pi pi-clock text-2xl text-blue-500 mb-2"></i>
|
||||
<div class="text-900 font-semibold mb-1">Temps de Réponse</div>
|
||||
<div class="text-600 text-sm">Moins de 2h</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-4 text-center" style="min-height: 9rem">
|
||||
<i class="pi pi-check-circle text-2xl text-green-500 mb-2"></i>
|
||||
<div class="text-900 font-semibold mb-1">Taux de Résolution</div>
|
||||
<div class="text-600 text-sm">98.5%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-4 text-center" style="min-height: 9rem">
|
||||
<i class="pi pi-users text-2xl text-purple-500 mb-2"></i>
|
||||
<div class="text-900 font-semibold mb-1">Satisfaction Client</div>
|
||||
<div class="text-600 text-sm">4.8/5</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round-lg p-4 text-center" style="min-height: 9rem">
|
||||
<i class="pi pi-calendar text-2xl text-orange-500 mb-2"></i>
|
||||
<div class="text-900 font-semibold mb-1">Support</div>
|
||||
<div class="text-600 text-sm">7j/7 - 24h/24</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Canaux de support -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-comment mr-2"></i>
|
||||
Choisissez votre canal de support
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="text-center">
|
||||
<i class="pi pi-ticket text-4xl text-blue-500 mb-3"></i>
|
||||
<h5 class="text-900 font-bold mb-2">Ticket Support</h5>
|
||||
<p class="text-600 text-sm mb-3">Pour les problèmes techniques et demandes complexes</p>
|
||||
<p:commandButton value="Créer un Ticket"
|
||||
styleClass="p-button-sm w-full"
|
||||
onclick="PF('ticketDialog').show()" />
|
||||
<p class="text-500 text-xs mt-2">Réponse sous 2h</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="text-center">
|
||||
<i class="pi pi-comments text-4xl text-green-500 mb-3"></i>
|
||||
<h5 class="text-900 font-bold mb-2">Chat en Direct</h5>
|
||||
<p class="text-600 text-sm mb-3">Support instantané pour les questions urgentes</p>
|
||||
<p:commandButton value="Démarrer le Chat"
|
||||
styleClass="p-button-sm w-full p-button-success" />
|
||||
<p class="text-500 text-xs mt-2">Disponible 9h-18h</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round-lg p-4 cursor-pointer transition-all transition-duration-200 h-full">
|
||||
<div class="text-center">
|
||||
<i class="pi pi-phone text-4xl text-orange-500 mb-3"></i>
|
||||
<h5 class="text-900 font-bold mb-2">Support Téléphonique</h5>
|
||||
<p class="text-600 text-sm mb-3">Appelez-nous directement pour une assistance immédiate</p>
|
||||
<div class="text-900 font-bold text-lg mb-2">+33 1 23 45 67 89</div>
|
||||
<p class="text-500 text-xs">Lun-Ven 8h-19h</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FAQ rapide -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-question-circle mr-2"></i>
|
||||
Questions Fréquentes
|
||||
</h4>
|
||||
|
||||
<p:tabView>
|
||||
<p:tab title="Comment réinitialiser mon mot de passe ?">
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Pour réinitialiser votre mot de passe, cliquez sur "Mot de passe oublié ?"
|
||||
sur la page de connexion. Vous recevrez un email avec un lien de réinitialisation
|
||||
valable pendant 24 heures.
|
||||
</p>
|
||||
<p:commandButton value="Réinitialiser maintenant"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-key" />
|
||||
</p:tab>
|
||||
|
||||
<p:tab title="Comment exporter mes données ?">
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Vous pouvez exporter vos données depuis le menu "Rapports" → "Export Personnalisés".
|
||||
Plusieurs formats sont disponibles : Excel, PDF, CSV et JSON.
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Guide d'Export"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-book" />
|
||||
<p:commandButton value="Accéder aux Exports"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-download" />
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<p:tab title="Problème de performance lente ?">
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Si l'application semble lente, vérifiez votre connexion internet et
|
||||
videz le cache de votre navigateur. Pour Chrome : Ctrl+Maj+Suppr.
|
||||
</p>
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-3">
|
||||
<h6 class="text-blue-800 font-semibold mb-2">
|
||||
<i class="pi pi-info-circle mr-2"></i>Diagnostic automatique
|
||||
</h6>
|
||||
<p class="text-blue-700 text-sm mb-0">
|
||||
Utilisez l'outil de diagnostic intégré pour identifier les problèmes.
|
||||
</p>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<p:tab title="Comment configurer les notifications ?">
|
||||
<p class="text-600 line-height-3 mb-3">
|
||||
Rendez-vous dans "Mon Espace Personnel" → "Mes Préférences" → "Notifications"
|
||||
pour configurer vos alertes par email et dans l'application.
|
||||
</p>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ressources utiles -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-bookmark mr-2"></i>
|
||||
Ressources Utiles
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="flex align-items-center p-3 surface-100 border-round hover:surface-200 cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-video text-2xl text-purple-500 mr-3"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Tutoriels Vidéo</h6>
|
||||
<p class="text-600 text-sm mb-0">Guides visuels étape par étape</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="flex align-items-center p-3 surface-100 border-round hover:surface-200 cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-book text-2xl text-blue-500 mr-3"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Documentation</h6>
|
||||
<p class="text-600 text-sm mb-0">Guide complet d'utilisation</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="flex align-items-center p-3 surface-100 border-round hover:surface-200 cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-users text-2xl text-green-500 mr-3"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Communauté</h6>
|
||||
<p class="text-600 text-sm mb-0">Forum d'entraide utilisateurs</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="flex align-items-center p-3 surface-100 border-round hover:surface-200 cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-sparkles text-2xl text-orange-500 mr-3"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Nouveautés</h6>
|
||||
<p class="text-600 text-sm mb-0">Dernières fonctionnalités</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouveau Ticket -->
|
||||
<p:dialog id="ticketDialog"
|
||||
widgetVar="ticketDialog"
|
||||
header="Créer un Ticket Support"
|
||||
modal="true"
|
||||
width="700"
|
||||
styleClass="surface-0">
|
||||
<h:form id="ticketForm">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="sujetTicket" class="block text-900 font-semibold mb-2">Sujet *</label>
|
||||
<p:inputText id="sujetTicket"
|
||||
placeholder="Résumé du problème"
|
||||
required="true"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="prioriteTicket" class="block text-900 font-semibold mb-2">Priorité</label>
|
||||
<p:selectOneMenu id="prioriteTicket" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Basse" itemValue="BASSE" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="Urgente" itemValue="URGENTE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="categorieTicket" class="block text-900 font-semibold mb-2">Catégorie</label>
|
||||
<p:selectOneMenu id="categorieTicket" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Problème Technique" itemValue="TECHNIQUE" />
|
||||
<f:selectItem itemLabel="Demande de Fonctionnalité" itemValue="FONCTIONNALITE" />
|
||||
<f:selectItem itemLabel="Question d'Utilisation" itemValue="UTILISATION" />
|
||||
<f:selectItem itemLabel="Problème de Compte" itemValue="COMPTE" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="environnement" class="block text-900 font-semibold mb-2">Environnement</label>
|
||||
<p:inputText id="environnement"
|
||||
placeholder="Ex: Chrome 120, Windows 11"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="descriptionTicket" class="block text-900 font-semibold mb-2">Description *</label>
|
||||
<p:inputTextarea id="descriptionTicket"
|
||||
rows="5"
|
||||
placeholder="Décrivez votre problème en détail..."
|
||||
required="true"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label class="block text-900 font-semibold mb-2">Pièces Jointes</label>
|
||||
<p:fileUpload mode="basic"
|
||||
multiple="true"
|
||||
chooseLabel="Choisir des fichiers"
|
||||
uploadLabel="Télécharger"
|
||||
cancelLabel="Annuler"
|
||||
styleClass="w-full" />
|
||||
<small class="text-500">Formats acceptés: jpg, png, pdf, doc, xlsx (max 10MB)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('ticketDialog').hide()"
|
||||
type="button" />
|
||||
<p:commandButton value="Créer le Ticket"
|
||||
styleClass="p-button-success"
|
||||
icon="pi pi-send" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,437 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Mes Tickets Support - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-ticket text-purple-500 mr-3"></i>
|
||||
Mes Tickets Support
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Suivez l'état de vos demandes d'assistance et échangez avec notre équipe
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouveau Ticket"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-plus"
|
||||
onclick="PF('nouveauTicketDialog').show()" />
|
||||
<p:commandButton value="FAQ"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-question-circle" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques personnelles -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">12</div>
|
||||
<div class="text-900 font-semibold mb-1">Tickets Créés</div>
|
||||
<div class="text-600 text-sm">Au total</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">3</div>
|
||||
<div class="text-900 font-semibold mb-1">En Attente</div>
|
||||
<div class="text-600 text-sm">Réponse support</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">8</div>
|
||||
<div class="text-900 font-semibold mb-1">Résolus</div>
|
||||
<div class="text-600 text-sm">Avec succès</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-red-500 mb-2">1</div>
|
||||
<div class="text-900 font-semibold mb-1">Fermé</div>
|
||||
<div class="text-600 text-sm">Sans résolution</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h:form id="filtresForm">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="statutFilter" class="block text-900 font-semibold mb-2">Statut</label>
|
||||
<p:selectOneMenu id="statutFilter" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Ouvert" itemValue="ouvert" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="en_cours" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="en_attente" />
|
||||
<f:selectItem itemLabel="Résolu" itemValue="resolu" />
|
||||
<f:selectItem itemLabel="Fermé" itemValue="ferme" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="prioriteFilter" class="block text-900 font-semibold mb-2">Priorité</label>
|
||||
<p:selectOneMenu id="prioriteFilter" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les priorités" itemValue="" />
|
||||
<f:selectItem itemLabel="Basse" itemValue="basse" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="normale" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="haute" />
|
||||
<f:selectItem itemLabel="Urgente" itemValue="urgente" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="categorieFilter" class="block text-900 font-semibold mb-2">Catégorie</label>
|
||||
<p:selectOneMenu id="categorieFilter" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les catégories" itemValue="" />
|
||||
<f:selectItem itemLabel="Problème Technique" itemValue="technique" />
|
||||
<f:selectItem itemLabel="Demande de Fonctionnalité" itemValue="fonctionnalite" />
|
||||
<f:selectItem itemLabel="Question d'Utilisation" itemValue="utilisation" />
|
||||
<f:selectItem itemLabel="Problème de Compte" itemValue="compte" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-3">
|
||||
<label for="rechercheTicket" class="block text-900 font-semibold mb-2">Rechercher</label>
|
||||
<p:inputText id="rechercheTicket"
|
||||
placeholder="Numéro, sujet..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des tickets -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-list mr-2"></i>
|
||||
Historique de vos Tickets
|
||||
</h4>
|
||||
|
||||
<!-- Ticket 1 - En cours -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-orange-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-clock text-orange-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#TK-2024-0157 - Problème d'export Excel</h6>
|
||||
<div class="flex align-items-center gap-2 mb-1">
|
||||
<p:tag value="EN COURS" severity="warning" styleClass="text-xs" />
|
||||
<p:tag value="HAUTE" severity="danger" styleClass="text-xs" />
|
||||
<p:tag value="TECHNIQUE" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">Créé le 15 janvier 2024 • Dernière réponse il y a 2h</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-600 text-sm mb-2">Agent: Marie Dubois</div>
|
||||
<p:commandButton value="Voir Détails"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-eye" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Impossible d'exporter la liste des membres en format Excel. Le fichier généré est corrompu
|
||||
et ne s'ouvre pas dans Excel. Cela concerne tous les exports depuis la version 2.1.
|
||||
</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-comments text-blue-500"></i>
|
||||
<span class="text-600 text-sm">5 messages</span>
|
||||
<i class="pi pi-paperclip text-600 ml-3"></i>
|
||||
<span class="text-600 text-sm">2 fichiers</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-clock text-600"></i>
|
||||
<span class="text-600 text-sm">SLA: 4h restantes</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ticket 2 - En attente -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-blue-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-pause text-blue-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#TK-2024-0143 - Demande de formation personnalisée</h6>
|
||||
<div class="flex align-items-center gap-2 mb-1">
|
||||
<p:tag value="EN ATTENTE" severity="info" styleClass="text-xs" />
|
||||
<p:tag value="NORMALE" severity="success" styleClass="text-xs" />
|
||||
<p:tag value="FONCTIONNALITÉ" severity="help" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">Créé le 12 janvier 2024 • En attente de votre réponse</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-600 text-sm mb-2">Agent: Thomas Martin</div>
|
||||
<p:commandButton value="Répondre"
|
||||
styleClass="p-button-primary p-button-sm"
|
||||
icon="pi pi-reply" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Souhaitons organiser une formation sur mesure pour notre équipe administrative.
|
||||
Besoin de devis pour 15 personnes sur 2 jours.
|
||||
</p>
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-3 mb-3">
|
||||
<p class="text-blue-700 text-sm mb-0">
|
||||
<i class="pi pi-info-circle mr-2"></i>
|
||||
<strong>Action requise:</strong> Merci de préciser vos disponibilités pour les dates proposées.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-comments text-blue-500"></i>
|
||||
<span class="text-600 text-sm">3 messages</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-exclamation-triangle text-orange-500"></i>
|
||||
<span class="text-orange-600 text-sm">Réponse attendue depuis 3 jours</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ticket 3 - Résolu -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-green-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-check text-green-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#TK-2024-0128 - Problème de connexion mobile</h6>
|
||||
<div class="flex align-items-center gap-2 mb-1">
|
||||
<p:tag value="RÉSOLU" severity="success" styleClass="text-xs" />
|
||||
<p:tag value="BASSE" severity="secondary" styleClass="text-xs" />
|
||||
<p:tag value="TECHNIQUE" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">Créé le 8 janvier 2024 • Résolu le 10 janvier 2024</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-600 text-sm mb-2">Agent: Sophie Leroy</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Noter"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-star" />
|
||||
<p:commandButton value="Détails"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-eye" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Application ne se charge pas sur smartphone Android. Écran blanc après connexion.
|
||||
</p>
|
||||
<div class="surface-green-50 border-left-3 border-green-500 p-3 mb-3">
|
||||
<p class="text-green-700 text-sm mb-0">
|
||||
<i class="pi pi-check-circle mr-2"></i>
|
||||
<strong>Résolution:</strong> Problème résolu en vidant le cache de l'application mobile.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-comments text-blue-500"></i>
|
||||
<span class="text-600 text-sm">6 messages</span>
|
||||
<i class="pi pi-clock text-600 ml-3"></i>
|
||||
<span class="text-600 text-sm">Résolu en 2 jours</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-400"></i>
|
||||
<span class="text-600 text-sm">Note: 5/5</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ticket 4 - Fermé -->
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200 opacity-70">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-red-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-times text-red-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#TK-2024-0095 - Demande modification base</h6>
|
||||
<div class="flex align-items-center gap-2 mb-1">
|
||||
<p:tag value="FERMÉ" severity="danger" styleClass="text-xs" />
|
||||
<p:tag value="HAUTE" severity="danger" styleClass="text-xs" />
|
||||
<p:tag value="FONCTIONNALITÉ" severity="help" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-0">Créé le 28 décembre 2023 • Fermé le 5 janvier 2024</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-600 text-sm mb-2">Agent: Marc Durand</div>
|
||||
<p:commandButton value="Rouvrir"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-replay" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-700 line-height-3 mb-3">
|
||||
Demande de modification des champs de la base de données membres pour ajouter
|
||||
des informations métier spécifiques.
|
||||
</p>
|
||||
<div class="surface-red-50 border-left-3 border-red-500 p-3 mb-3">
|
||||
<p class="text-red-700 text-sm mb-0">
|
||||
<i class="pi pi-times-circle mr-2"></i>
|
||||
<strong>Fermé:</strong> Demande non compatible avec l'architecture actuelle.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-comments text-blue-500"></i>
|
||||
<span class="text-600 text-sm">8 messages</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-ban text-red-500"></i>
|
||||
<span class="text-red-600 text-sm">Non résolu</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions rapides -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-bolt mr-2"></i>
|
||||
Actions Rapides
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-plus-circle text-3xl text-primary mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Nouveau Ticket</h6>
|
||||
<p class="text-600 text-sm mb-0">Créer une demande d'assistance</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-question-circle text-3xl text-blue-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Consulter la FAQ</h6>
|
||||
<p class="text-600 text-sm mb-0">Réponses aux questions courantes</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-book text-3xl text-green-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Guide Utilisateur</h6>
|
||||
<p class="text-600 text-sm mb-0">Documentation complète</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-phone text-3xl text-orange-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Contact Direct</h6>
|
||||
<p class="text-600 text-sm mb-0">Appelez le support</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouveau Ticket -->
|
||||
<p:dialog id="nouveauTicketDialog"
|
||||
widgetVar="nouveauTicketDialog"
|
||||
header="Créer un Nouveau Ticket"
|
||||
modal="true"
|
||||
width="800"
|
||||
styleClass="surface-0">
|
||||
<h:form id="nouveauTicketForm">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="categorieTicket" class="block text-900 font-semibold mb-2">Catégorie *</label>
|
||||
<p:selectOneMenu id="categorieTicket" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionnez une catégorie" itemValue="" />
|
||||
<f:selectItem itemLabel="Problème Technique" itemValue="technique" />
|
||||
<f:selectItem itemLabel="Demande de Fonctionnalité" itemValue="fonctionnalite" />
|
||||
<f:selectItem itemLabel="Question d'Utilisation" itemValue="utilisation" />
|
||||
<f:selectItem itemLabel="Problème de Compte" itemValue="compte" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="autre" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<label for="prioriteTicket" class="block text-900 font-semibold mb-2">Priorité</label>
|
||||
<p:selectOneMenu id="prioriteTicket" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Basse" itemValue="basse" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="normale" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="haute" />
|
||||
<f:selectItem itemLabel="Urgente" itemValue="urgente" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="sujetTicket" class="block text-900 font-semibold mb-2">Sujet *</label>
|
||||
<p:inputText id="sujetTicket"
|
||||
placeholder="Résumé du problème ou de la demande"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label for="descriptionTicket" class="block text-900 font-semibold mb-2">Description détaillée *</label>
|
||||
<p:inputTextarea id="descriptionTicket"
|
||||
rows="6"
|
||||
placeholder="Décrivez votre problème en détail, incluez les étapes pour reproduire..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label class="block text-900 font-semibold mb-2">Pièces jointes</label>
|
||||
<p:fileUpload mode="basic"
|
||||
multiple="true"
|
||||
chooseLabel="Choisir des fichiers"
|
||||
styleClass="w-full" />
|
||||
<small class="text-500">Formats acceptés: jpg, png, pdf, doc, xlsx (max 10MB par fichier)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('nouveauTicketDialog').hide()"
|
||||
type="button" />
|
||||
<p:commandButton value="Créer le Ticket"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-send" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,161 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition template="/templates/main-template.xhtml"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<ui:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Traitement des Demandes d'Aide - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formTraitement">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-inbox text-primary mr-2"></i>
|
||||
Traitement des Demandes d'Aide
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Gérez et traitez les demandes d'aide des membres
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-2 md:mt-0">
|
||||
<p:commandButton value="Actualiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{demandesAideBean.actualiser}"
|
||||
update="@form"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid mb-3">
|
||||
<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">#{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: 3rem; height: 3rem; line-height: 3rem;">
|
||||
<i class="pi pi-inbox 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">#{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: 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">#{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: 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-red-100 border-left-3 border-red-500">
|
||||
<div class="flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-red-900 font-bold text-2xl">#{demandesAideBean.statistiques.demandesRejetees}</div>
|
||||
<div class="text-red-700">Rejetées</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-times text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des demandes -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Demandes à Traiter</h5>
|
||||
|
||||
<p:dataTable id="dtDemandes"
|
||||
var="demande"
|
||||
value="#{demandesAideBean.demandesFiltrees}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column headerText="Demandeur" sortBy="#{demande.demandeur}">
|
||||
<div>
|
||||
<div class="font-medium">#{demande.demandeur}</div>
|
||||
<small class="text-600">#{demande.telephone}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{demande.type}">
|
||||
<p:tag value="#{demande.typeLibelle}" severity="#{demande.typeSeverity}" icon="pi #{demande.typeIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{demande.montantDemande}">
|
||||
<div class="font-bold text-green-500">#{demande.montantDemande} FCFA</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{demande.statut}">
|
||||
<p:tag value="#{demande.statut}"
|
||||
severity="#{demande.statutSeverity}"
|
||||
icon="pi #{demande.statutIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date" sortBy="#{demande.dateDemande}">
|
||||
<h:outputText value="#{demande.dateDemande}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
</h:outputText>
|
||||
</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="#{demandesAideBean.voirDetails(demande)}"
|
||||
title="Voir détails"/>
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{demandesAideBean.approuver(demande)}"
|
||||
title="Approuver"
|
||||
rendered="#{demande.statut == 'EN_ATTENTE'}"/>
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
action="#{demandesAideBean.rejeter(demande)}"
|
||||
title="Rejeter"
|
||||
rendered="#{demande.statut == 'EN_ATTENTE'}"/>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,368 @@
|
||||
<!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:param name="page" value="#{demandesAideBean}"/>
|
||||
<ui:define name="title">Tutoriels Vidéo - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-video text-orange-500 mr-3"></i>
|
||||
Tutoriels Vidéo
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Apprenez UnionFlow grâce à nos tutoriels vidéo étape par étape
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Playlist Complète"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-play-circle" />
|
||||
<p:commandButton value="Télécharger"
|
||||
styleClass="p-button-primary p-button-outlined"
|
||||
icon="pi pi-download" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">24</div>
|
||||
<div class="text-900 font-semibold mb-1">Tutoriels</div>
|
||||
<div class="text-600 text-sm">Disponibles</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">4h 32m</div>
|
||||
<div class="text-900 font-semibold mb-1">Durée Totale</div>
|
||||
<div class="text-600 text-sm">Contenu vidéo</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">1,847</div>
|
||||
<div class="text-900 font-semibold mb-1">Vues</div>
|
||||
<div class="text-600 text-sm">Ce mois-ci</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">4.8★</div>
|
||||
<div class="text-900 font-semibold mb-1">Note Moyenne</div>
|
||||
<div class="text-600 text-sm">Sur 156 avis</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtrres et recherche -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h:form id="filtresForm">
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-12 md:col-4">
|
||||
<label for="categorieFilter" class="block text-900 font-semibold mb-2">Catégorie</label>
|
||||
<p:selectOneMenu id="categorieFilter" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les catégories" itemValue="" />
|
||||
<f:selectItem itemLabel="Premiers Pas" itemValue="debutant" />
|
||||
<f:selectItem itemLabel="Gestion des Membres" itemValue="membres" />
|
||||
<f:selectItem itemLabel="Finances" itemValue="finances" />
|
||||
<f:selectItem itemLabel="Événements" itemValue="evenements" />
|
||||
<f:selectItem itemLabel="Administration" itemValue="admin" />
|
||||
<f:selectItem itemLabel="Rapports" itemValue="rapports" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<label for="dureeFilter" class="block text-900 font-semibold mb-2">Durée</label>
|
||||
<p:selectOneMenu id="dureeFilter" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les durées" itemValue="" />
|
||||
<f:selectItem itemLabel="Moins de 5 min" itemValue="court" />
|
||||
<f:selectItem itemLabel="5-15 min" itemValue="moyen" />
|
||||
<f:selectItem itemLabel="Plus de 15 min" itemValue="long" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<label for="rechercheVideo" class="block text-900 font-semibold mb-2">Rechercher</label>
|
||||
<p:inputText id="rechercheVideo"
|
||||
placeholder="Titre, mots-clés..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des tutoriels par catégorie -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-play mr-2"></i>
|
||||
Premiers Pas avec UnionFlow
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<!-- Tutoriel 1 -->
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round transition-duration-200 cursor-pointer">
|
||||
<div class="relative">
|
||||
<div class="w-full h-12rem bg-primary-50 border-round-top flex align-items-center justify-content-center">
|
||||
<i class="pi pi-play-circle text-6xl text-primary-500"></i>
|
||||
</div>
|
||||
<div class="absolute top-0 right-0 m-2">
|
||||
<p:tag value="3:45" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 left-0 right-0 h-1rem bg-blue-500" style="width: 25%; opacity: 0.8;"></div>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<h6 class="text-900 font-semibold mb-2">Première Connexion</h6>
|
||||
<p class="text-600 text-sm mb-3">Découvrez comment vous connecter pour la première fois à UnionFlow</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-eye text-600 text-sm"></i>
|
||||
<span class="text-600 text-sm">2,341 vues</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-400"></i>
|
||||
<span class="text-600 text-sm">4.9</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tutoriel 2 -->
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round transition-duration-200 cursor-pointer">
|
||||
<div class="relative">
|
||||
<div class="w-full h-12rem bg-green-50 border-round-top flex align-items-center justify-content-center">
|
||||
<i class="pi pi-play-circle text-6xl text-green-500"></i>
|
||||
</div>
|
||||
<div class="absolute top-0 right-0 m-2">
|
||||
<p:tag value="7:22" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 left-0 right-0 h-1rem bg-blue-500" style="width: 100%; opacity: 0.8;"></div>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<h6 class="text-900 font-semibold mb-2">Navigation dans l'Interface</h6>
|
||||
<p class="text-600 text-sm mb-3">Tour complet de l'interface utilisateur et des menus principaux</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-eye text-600 text-sm"></i>
|
||||
<span class="text-600 text-sm">1,876 vues</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-400"></i>
|
||||
<span class="text-600 text-sm">4.7</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tutoriel 3 -->
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round transition-duration-200 cursor-pointer">
|
||||
<div class="relative">
|
||||
<div class="w-full h-12rem bg-orange-50 border-round-top flex align-items-center justify-content-center">
|
||||
<i class="pi pi-play-circle text-6xl text-orange-500"></i>
|
||||
</div>
|
||||
<div class="absolute top-0 right-0 m-2">
|
||||
<p:tag value="5:18" severity="warning" styleClass="text-xs" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 left-0 right-0 h-1rem bg-blue-500" style="width: 60%; opacity: 0.8;"></div>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<h6 class="text-900 font-semibold mb-2">Personnaliser son Profil</h6>
|
||||
<p class="text-600 text-sm mb-3">Comment configurer vos informations personnelles et préférences</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-eye text-600 text-sm"></i>
|
||||
<span class="text-600 text-sm">1,432 vues</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-400"></i>
|
||||
<span class="text-600 text-sm">4.8</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gestion des Membres -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-users mr-2"></i>
|
||||
Gestion des Membres
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<!-- Tutoriel Membre 1 -->
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round transition-duration-200 cursor-pointer">
|
||||
<div class="relative">
|
||||
<div class="w-full h-12rem bg-blue-50 border-round-top flex align-items-center justify-content-center">
|
||||
<i class="pi pi-play-circle text-6xl text-blue-500"></i>
|
||||
</div>
|
||||
<div class="absolute top-0 right-0 m-2">
|
||||
<p:tag value="12:45" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
<div class="absolute top-0 left-0 m-2">
|
||||
<p:tag value="NOUVEAU" severity="danger" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<h6 class="text-900 font-semibold mb-2">Inscrire un Nouveau Membre</h6>
|
||||
<p class="text-600 text-sm mb-3">Processus complet d'inscription d'un membre avec toutes les étapes</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-eye text-600 text-sm"></i>
|
||||
<span class="text-600 text-sm">987 vues</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-400"></i>
|
||||
<span class="text-600 text-sm">5.0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tutoriel Membre 2 -->
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round transition-duration-200 cursor-pointer">
|
||||
<div class="relative">
|
||||
<div class="w-full h-12rem bg-purple-50 border-round-top flex align-items-center justify-content-center">
|
||||
<i class="pi pi-play-circle text-6xl text-purple-500"></i>
|
||||
</div>
|
||||
<div class="absolute top-0 right-0 m-2">
|
||||
<p:tag value="8:33" severity="help" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<h6 class="text-900 font-semibold mb-2">Recherche Avancée</h6>
|
||||
<p class="text-600 text-sm mb-3">Utiliser les filtres et critères de recherche pour trouver des membres</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-eye text-600 text-sm"></i>
|
||||
<span class="text-600 text-sm">1,234 vues</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-400"></i>
|
||||
<span class="text-600 text-sm">4.6</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tutoriel Membre 3 -->
|
||||
<div class="col-12 lg:col-6 xl:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round transition-duration-200 cursor-pointer">
|
||||
<div class="relative">
|
||||
<div class="w-full h-12rem bg-teal-50 border-round-top flex align-items-center justify-content-center">
|
||||
<i class="pi pi-play-circle text-6xl text-teal-500"></i>
|
||||
</div>
|
||||
<div class="absolute top-0 right-0 m-2">
|
||||
<p:tag value="15:27" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<h6 class="text-900 font-semibold mb-2">Export et Rapports Membres</h6>
|
||||
<p class="text-600 text-sm mb-3">Générer des exports Excel et des rapports personnalisés</p>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-eye text-600 text-sm"></i>
|
||||
<span class="text-600 text-sm">765 vues</span>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-400"></i>
|
||||
<span class="text-600 text-sm">4.9</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Playlist recommandées -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-bookmark mr-2"></i>
|
||||
Playlists Recommandées
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-play-circle text-2xl text-primary mr-3"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Formation Complète Débutant</h6>
|
||||
<p class="text-600 text-sm mb-0">8 vidéos • 45 min</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Parcours complet pour débuter avec UnionFlow, de la connexion à la première utilisation
|
||||
</p>
|
||||
<p:commandButton value="Commencer"
|
||||
styleClass="p-button-primary p-button-sm w-full"
|
||||
icon="pi pi-play" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-cog text-2xl text-orange-500 mr-3"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Administration Avancée</h6>
|
||||
<p class="text-600 text-sm mb-0">12 vidéos • 2h 15min</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Maîtrisez l'administration d'UnionFlow : utilisateurs, rôles, permissions et configuration
|
||||
</p>
|
||||
<p:commandButton value="Commencer"
|
||||
styleClass="p-button-outlined p-button-sm w-full"
|
||||
icon="pi pi-play" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,456 @@
|
||||
<!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:param name="page" value="#{cotisationsBean}"/>
|
||||
<ui:define name="title">Gestion des Cotisations - 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-money-bill text-green-500" />
|
||||
<ui:param name="title" value="Gestion des Cotisations" />
|
||||
<ui:param name="description" value="Suivi et gestion des cotisations des membres" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsCotisations">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouvelle cotisation" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="onclick" value="PF('dlgNouvelleCotisation').show();" />
|
||||
</ui:include>
|
||||
<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="action" value="#{cotisationsBean.exporterCotisations}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{cotisationsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.totalCollecteFormatte}" />
|
||||
<ui:param name="label" value="Total Collecté" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.tauxRecouvrementInt}%" />
|
||||
<ui:param name="label" value="Taux de Recouvrement" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.cotisationsEnRetard}" />
|
||||
<ui:param name="label" value="En Retard" />
|
||||
<ui:param name="icon" value="pi pi-exclamation-triangle" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.montantRetardFormatte}" />
|
||||
<ui:param name="label" value="Montant Retard" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des cotisations -->
|
||||
<div class="card">
|
||||
<h:form id="formCotisations">
|
||||
<h5>Liste des Cotisations</h5>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchMembre" value="Rechercher" />
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchMembre"
|
||||
placeholder="Rechercher par membre..."
|
||||
value="#{cotisationsBean.filtres.nomMembre}"
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" update="dtCotisations" delay="500"/>
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filtreStatut"
|
||||
value="#{cotisationsBean.filtres.statut}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="Payée" itemValue="PAYEE" />
|
||||
<f:selectItem itemLabel="Partiellement payée" itemValue="PARTIELLEMENT_PAYEE" />
|
||||
<f:selectItem itemLabel="En retard" itemValue="EN_RETARD" />
|
||||
<f:selectItem itemLabel="Annulée" itemValue="ANNULEE" />
|
||||
<p:ajax event="change" update="dtCotisations" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreType" value="Type" />
|
||||
<p:selectOneMenu id="filtreType"
|
||||
value="#{cotisationsBean.filtres.typeCotisation}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Mensuelle" itemValue="MENSUELLE" />
|
||||
<f:selectItem itemLabel="Trimestrielle" itemValue="TRIMESTRIELLE" />
|
||||
<f:selectItem itemLabel="Semestrielle" itemValue="SEMESTRIELLE" />
|
||||
<f:selectItem itemLabel="Annuelle" itemValue="ANNUELLE" />
|
||||
<f:selectItem itemLabel="Adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Exceptionnelle" itemValue="EXCEPTIONNELLE" />
|
||||
<p:ajax event="change" update="dtCotisations" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Filtres avancés"
|
||||
icon="pi pi-filter"
|
||||
onclick="PF('dlgFiltresAvances').show();"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Réinitialiser</label>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
action="#{cotisationsBean.reinitialiserFiltres}"
|
||||
update="dtCotisations searchMembre filtreStatut filtreType"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Tableau des cotisations -->
|
||||
<p:dataTable id="dtCotisations"
|
||||
value="#{cotisationsBean.cotisationsFiltrees}"
|
||||
var="cotisation"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
|
||||
currentPageReportTemplate="{startRecord} - {endRecord} sur {totalRecords}"
|
||||
emptyMessage="Aucune cotisation trouvée"
|
||||
selection="#{cotisationsBean.cotisationsSelectionnees}"
|
||||
selectionMode="multiple">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Cotisations (#{cotisationsBean.cotisationsFiltrees.size()})</span>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Rappels groupés" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{cotisationsBean.envoyerRappelsGroupes}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="disabled" value="#{empty cotisationsBean.cotisationsSelectionnees}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{cotisation.numeroReference}" style="width:150px">
|
||||
<h:outputText value="#{cotisation.numeroReference}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{cotisation.nomMembre}">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{cotisation.numeroMembre}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{cotisation.typeCotisation}" style="width:120px">
|
||||
<p:tag value="#{cotisation.typeCotisationLibelle}"
|
||||
severity="info"
|
||||
icon="#{cotisation.typeCotisation == 'ADHESION' ? 'pi-user-plus' : 'pi-calendar'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Dû" sortBy="#{cotisation.montantDu}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.montantDuFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Payé" sortBy="#{cotisation.montantPaye}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.montantPayeFormatte}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{cotisation.statut}" style="width:150px">
|
||||
<p:tag value="#{cotisation.statutLibelle}"
|
||||
severity="#{cotisation.statutSeverity}"
|
||||
icon="#{cotisation.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Échéance" sortBy="#{cotisation.dateEcheance}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.dateEcheanceFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-check"
|
||||
title="Marquer comme payée"
|
||||
styleClass="p-button-rounded p-button-text p-button-success"
|
||||
disabled="#{cotisation.statut == 'PAYEE'}"
|
||||
action="#{cotisationsBean.marquerCommePaye(cotisation)}"
|
||||
update="@form" />
|
||||
<p:commandButton icon="pi pi-send"
|
||||
title="Envoyer un rappel"
|
||||
styleClass="p-button-rounded p-button-text p-button-warning"
|
||||
action="#{cotisationsBean.envoyerRappel(cotisation)}"
|
||||
update="@form" />
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir les détails"
|
||||
styleClass="p-button-rounded p-button-text p-button-info"
|
||||
action="#{cotisationsBean.selectionnerCotisation(cotisation)}"
|
||||
update=":formDetailsCotisation"
|
||||
oncomplete="PF('dlgDetailsCotisation').show();" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvelle Cotisation -->
|
||||
<p:dialog header="Nouvelle Cotisation" widgetVar="dlgNouvelleCotisation" modal="true" width="600" resizable="false">
|
||||
<h:form id="formNouvelleCotisation">
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="title">Informations de la cotisation</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="libelle" />
|
||||
<ui:param name="label" value="Libellé" />
|
||||
<ui:param name="value" value="#{cotisationsBean.nouvelleCotisation.libelle}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="placeholder" value="Ex: Cotisation mensuelle janvier 2024" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="typeCotisation" />
|
||||
<ui:param name="label" value="Type de cotisation" />
|
||||
<ui:param name="value" value="#{cotisationsBean.nouvelleCotisation.typeCotisation}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Mensuelle" itemValue="MENSUELLE" />
|
||||
<f:selectItem itemLabel="Trimestrielle" itemValue="TRIMESTRIELLE" />
|
||||
<f:selectItem itemLabel="Semestrielle" itemValue="SEMESTRIELLE" />
|
||||
<f:selectItem itemLabel="Annuelle" itemValue="ANNUELLE" />
|
||||
<f:selectItem itemLabel="Adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Exceptionnelle" itemValue="EXCEPTIONNELLE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateEcheance" />
|
||||
<ui:param name="label" value="Date d'échéance" />
|
||||
<ui:param name="value" value="#{cotisationsBean.nouvelleCotisation.dateEcheance}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="montantDu" value="Montant dû (FCFA)" />
|
||||
<p:inputNumber id="montantDu"
|
||||
value="#{cotisationsBean.nouvelleCotisation.montantDu}"
|
||||
symbol=""
|
||||
minValue="0"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="observations" />
|
||||
<ui:param name="label" value="Observations" />
|
||||
<ui:param name="value" value="#{cotisationsBean.nouvelleCotisation.observations}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgNouvelleCotisation').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{cotisationsBean.enregistrerCotisation}" />
|
||||
<ui:param name="update" value="@form :formCotisations" />
|
||||
<ui:param name="oncomplete" value="PF('dlgNouvelleCotisation').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Filtres Avancés -->
|
||||
<p:dialog header="Filtres Avancés" widgetVar="dlgFiltresAvances" modal="true" width="500" resizable="false">
|
||||
<h:form id="formFiltresAvances">
|
||||
<div class="ui-fluid">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="club" />
|
||||
<ui:param name="label" value="Club/Association" />
|
||||
<ui:param name="value" value="#{cotisationsBean.filtres.club}" />
|
||||
<ui:param name="placeholder" value="Rechercher par club..." />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="methodePaiement" />
|
||||
<ui:param name="label" value="Méthode de paiement" />
|
||||
<ui:param name="value" value="#{cotisationsBean.filtres.methodePaiement}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Toutes" itemValue="" />
|
||||
<f:selectItem itemLabel="Wave Money" itemValue="WAVE_MONEY" />
|
||||
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="Virement" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<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="#{cotisationsBean.filtres.dateDebut}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<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="#{cotisationsBean.filtres.dateFin}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Appliquer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{cotisationsBean.rechercher}" />
|
||||
<ui:param name="update" value=":formCotisations" />
|
||||
<ui:param name="oncomplete" value="PF('dlgFiltresAvances').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Détails Cotisation -->
|
||||
<p:dialog header="Détails de la Cotisation" widgetVar="dlgDetailsCotisation" modal="true" width="600" resizable="false">
|
||||
<h:form id="formDetailsCotisation">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Référence</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.numeroReference}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Statut</label>
|
||||
<p:tag value="#{cotisationsBean.cotisationSelectionnee.statutLibelle}"
|
||||
severity="#{cotisationsBean.cotisationSelectionnee.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Membre</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">#{cotisationsBean.cotisationSelectionnee.numeroMembre}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Type</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.typeCotisationLibelle}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant dû</label>
|
||||
<p class="text-600 font-bold">#{cotisationsBean.cotisationSelectionnee.montantDuFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant payé</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.montantPayeFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date d'échéance</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.dateEcheanceFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date de paiement</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.datePaiementFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,253 @@
|
||||
<!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:param name="page" value="#{cotisationsBean}"/>
|
||||
<ui:define name="title">Historique des Cotisations - 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-blue-500" />
|
||||
<ui:param name="title" value="Historique des Cotisations" />
|
||||
<ui:param name="description" value="Consultation de l'historique complet des cotisations et paiements" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsHistorique">
|
||||
<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="action" value="#{cotisationsBean.exporterCotisations}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{cotisationsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Filtres d'historique -->
|
||||
<div class="card">
|
||||
<h:form id="formFiltresHistorique">
|
||||
<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="#{cotisationsBean.filtres.dateDebut}" />
|
||||
</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="#{cotisationsBean.filtres.dateFin}" />
|
||||
</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="statutHistorique" />
|
||||
<ui:param name="label" value="Statut" />
|
||||
<ui:param name="value" value="#{cotisationsBean.filtres.statut}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="Payée" itemValue="PAYEE" />
|
||||
<f:selectItem itemLabel="Partiellement payée" itemValue="PARTIELLEMENT_PAYEE" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="En retard" itemValue="EN_RETARD" />
|
||||
<f:selectItem itemLabel="Annulée" itemValue="ANNULEE" />
|
||||
</ui:define>
|
||||
</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="#{cotisationsBean.rechercher}" />
|
||||
<ui:param name="update" value=":formHistorique" />
|
||||
</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-times" />
|
||||
<ui:param name="action" value="#{cotisationsBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value="@form :formHistorique" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Tableau d'historique -->
|
||||
<div class="card">
|
||||
<h:form id="formHistorique">
|
||||
<h5>Historique des Cotisations</h5>
|
||||
|
||||
<p:dataTable id="dtHistorique"
|
||||
value="#{cotisationsBean.cotisationsFiltrees}"
|
||||
var="cotisation"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
sortMode="multiple"
|
||||
emptyMessage="Aucune cotisation trouvée">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Historique (#{cotisationsBean.cotisationsFiltrees.size()} cotisation(s))</span>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column headerText="Date" sortBy="#{cotisation.dateCreation}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.dateCreation}" rendered="#{cotisation.dateCreation != null}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{cotisation.numeroReference}" style="width:150px">
|
||||
<h:outputText value="#{cotisation.numeroReference}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{cotisation.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{cotisation.numeroMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{cotisation.typeCotisation}" style="width:120px">
|
||||
<p:tag value="#{cotisation.typeCotisationLibelle}" severity="info" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Dû" sortBy="#{cotisation.montantDu}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.montantDuFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Payé" sortBy="#{cotisation.montantPaye}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.montantPayeFormatte}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{cotisation.statut}" style="width:150px">
|
||||
<p:tag value="#{cotisation.statutLibelle}"
|
||||
severity="#{cotisation.statutSeverity}"
|
||||
icon="#{cotisation.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Paiement" sortBy="#{cotisation.datePaiement}" style="width:150px">
|
||||
<h:outputText value="#{cotisation.datePaiementFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Méthode" style="width:120px">
|
||||
<h:outputText value="#{cotisation.methodePaiementLibelle}" rendered="#{cotisation.methodePaiement != null}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:100px">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir les détails"
|
||||
styleClass="p-button-rounded p-button-text p-button-info"
|
||||
action="#{cotisationsBean.selectionnerCotisation(cotisation)}"
|
||||
update=":formDetailsCotisation"
|
||||
oncomplete="PF('dlgDetailsCotisation').show();" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Détails Cotisation -->
|
||||
<p:dialog header="Détails de la Cotisation" widgetVar="dlgDetailsCotisation" modal="true" width="600" resizable="false">
|
||||
<h:form id="formDetailsCotisation">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Référence</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.numeroReference}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Statut</label>
|
||||
<p:tag value="#{cotisationsBean.cotisationSelectionnee.statutLibelle}"
|
||||
severity="#{cotisationsBean.cotisationSelectionnee.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-medium">Membre</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">N° #{cotisationsBean.cotisationSelectionnee.numeroMembre}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Type</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.typeCotisationLibelle}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date d'échéance</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.dateEcheanceFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant dû</label>
|
||||
<p class="text-600 font-bold">#{cotisationsBean.cotisationSelectionnee.montantDuFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant payé</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.montantPayeFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<label class="font-medium">Montant restant</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.montantRestantFormatte}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Date de paiement</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.datePaiementFormatee}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-medium">Méthode de paiement</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.methodePaiementLibelle}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{cotisationsBean.cotisationSelectionnee.observations != null}">
|
||||
<div class="field">
|
||||
<label class="font-medium">Observations</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.observations}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,307 @@
|
||||
<!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:param name="page" value="#{cotisationsBean}"/>
|
||||
<ui:define name="title">Paiement de Cotisations - 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-credit-card text-green-500" />
|
||||
<ui:param name="title" value="Paiement de Cotisations" />
|
||||
<ui:param name="description" value="Enregistrement et suivi des paiements de cotisations" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsPaiement">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{cotisationsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques de paiement -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.totalCollecteFormatte}" />
|
||||
<ui:param name="label" value="Total Collecté" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.moyenneMensuelleFormattee}" />
|
||||
<ui:param name="label" value="Moyenne Mensuelle" />
|
||||
<ui:param name="icon" value="pi pi-chart-line" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.objectifAnnuelFormatte}" />
|
||||
<ui:param name="label" value="Objectif Annuel" />
|
||||
<ui:param name="icon" value="pi pi-target" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.tauxRecouvrementInt}%" />
|
||||
<ui:param name="label" value="Taux de Recouvrement" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Répartition par méthode de paiement -->
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-chart-pie mr-2"></i>
|
||||
Répartition par Méthode de Paiement
|
||||
</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="flex flex-column gap-3">
|
||||
<ui:repeat value="#{cotisationsBean.repartitionMethodes}" var="methode">
|
||||
<div class="flex align-items-center justify-content-between p-3 border-round surface-50">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<div class="border-round text-white text-center"
|
||||
style="width: 2.5rem; height: 2.5rem; line-height: 2.5rem; background: var(--#{methode.couleur});">
|
||||
<i class="#{methode.icon}"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium">#{methode.methode}</div>
|
||||
<div class="text-600 text-sm">#{methode.montantFormatte}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="font-bold text-xl">#{methode.pourcentageInt}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="flex flex-column gap-2">
|
||||
<ui:repeat value="#{cotisationsBean.repartitionMethodes}" var="methode">
|
||||
<div>
|
||||
<div class="flex justify-content-between mb-1">
|
||||
<span class="font-medium">#{methode.methode}</span>
|
||||
<span class="text-600">#{methode.pourcentageInt}%</span>
|
||||
</div>
|
||||
<p:progressBar value="#{methode.pourcentageInt}"
|
||||
showValue="false"
|
||||
styleClass="progressbar-custom" />
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cotisations en attente de paiement -->
|
||||
<div class="card">
|
||||
<h:form id="formPaiements">
|
||||
<h5>Cotisations en Attente de Paiement</h5>
|
||||
|
||||
<p:dataTable id="dtPaiements"
|
||||
value="#{cotisationsBean.cotisationsFiltrees}"
|
||||
var="cotisation"
|
||||
filteredValue="#{cotisationsBean.cotisationsFiltrees}"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
emptyMessage="Aucune cotisation en attente"
|
||||
selection="#{cotisationsBean.cotisationSelectionnee}"
|
||||
selectionMode="single">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Cotisations à payer</span>
|
||||
<p:selectOneMenu value="#{cotisationsBean.filtres.statut}" styleClass="w-12rem">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="Partiellement payée" itemValue="PARTIELLEMENT_PAYEE" />
|
||||
<f:selectItem itemLabel="En retard" itemValue="EN_RETARD" />
|
||||
<p:ajax update="dtPaiements" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{cotisation.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{cotisation.numeroMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{cotisation.typeCotisation}" style="width:120px">
|
||||
<p:tag value="#{cotisation.typeCotisationLibelle}" severity="info" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Dû" sortBy="#{cotisation.montantDu}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.montantDuFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Payé" sortBy="#{cotisation.montantPaye}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.montantPayeFormatte}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Restant" style="width:120px">
|
||||
<h:outputText value="#{cotisation.montantRestantFormatte}"
|
||||
styleClass="#{cotisation.montantRestant.compareTo(java.math.BigDecimal.ZERO) > 0 ? 'text-orange-500 font-bold' : 'text-green-500'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Échéance" sortBy="#{cotisation.dateEcheance}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.dateEcheanceFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton value="Payer"
|
||||
icon="pi pi-check"
|
||||
styleClass="p-button-success p-button-sm"
|
||||
action="#{cotisationsBean.selectionnerCotisation(cotisation)}"
|
||||
update=":formPaiement"
|
||||
oncomplete="PF('dlgPaiement').show();" />
|
||||
<p:commandButton value="Partiel"
|
||||
icon="pi pi-minus"
|
||||
styleClass="p-button-info p-button-sm"
|
||||
action="#{cotisationsBean.selectionnerCotisation(cotisation)}"
|
||||
update=":formPaiementPartiel"
|
||||
oncomplete="PF('dlgPaiementPartiel').show();" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Paiement Complet -->
|
||||
<p:dialog header="Enregistrer un Paiement" widgetVar="dlgPaiement" modal="true" width="500" resizable="false">
|
||||
<h:form id="formPaiement">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Cotisation</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.numeroReference} - #{cotisationsBean.cotisationSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">Montant dû: #{cotisationsBean.cotisationSelectionnee.montantDuFormatte}</p>
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="methodePaiement" />
|
||||
<ui:param name="label" value="Méthode de paiement" />
|
||||
<ui:param name="value" value="#{cotisationsBean.cotisationSelectionnee.methodePaiement}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Wave Money" itemValue="WAVE_MONEY" />
|
||||
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="Virement bancaire" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
|
||||
<f:selectItem itemLabel="Orange Money" itemValue="ORANGE_MONEY" />
|
||||
<f:selectItem itemLabel="Free Money" itemValue="FREE_MONEY" />
|
||||
<f:selectItem itemLabel="Carte bancaire" itemValue="CARTE_BANCAIRE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="referencePaiement" />
|
||||
<ui:param name="label" value="Référence de paiement" />
|
||||
<ui:param name="value" value="#{cotisationsBean.cotisationSelectionnee.referencePaiement}" />
|
||||
<ui:param name="placeholder" value="Ex: WAVE-123456789" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="observationsPaiement" />
|
||||
<ui:param name="label" value="Observations" />
|
||||
<ui:param name="value" value="#{cotisationsBean.cotisationSelectionnee.observations}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgPaiement').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{cotisationsBean.marquerCommePaye}" />
|
||||
<ui:param name="update" value="@form :formPaiements" />
|
||||
<ui:param name="oncomplete" value="PF('dlgPaiement').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Paiement Partiel -->
|
||||
<p:dialog header="Enregistrer un Paiement Partiel" widgetVar="dlgPaiementPartiel" modal="true" width="500" resizable="false">
|
||||
<h:form id="formPaiementPartiel">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<label class="font-medium">Cotisation</label>
|
||||
<p class="text-600">#{cotisationsBean.cotisationSelectionnee.numeroReference} - #{cotisationsBean.cotisationSelectionnee.nomMembre}</p>
|
||||
<p class="text-500 text-sm">Montant dû: #{cotisationsBean.cotisationSelectionnee.montantDuFormatte}</p>
|
||||
<p class="text-500 text-sm">Montant restant: #{cotisationsBean.cotisationSelectionnee.montantRestantFormatte}</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="montantPaye" value="Montant à payer (FCFA)" />
|
||||
<p:inputNumber id="montantPaye"
|
||||
value="#{cotisationsBean.cotisationSelectionnee.montantPaye}"
|
||||
symbol=""
|
||||
minValue="0"
|
||||
maxValue="#{cotisationsBean.cotisationSelectionnee.montantDu}"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="methodePaiementPartiel" />
|
||||
<ui:param name="label" value="Méthode de paiement" />
|
||||
<ui:param name="value" value="#{cotisationsBean.cotisationSelectionnee.methodePaiement}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Wave Money" itemValue="WAVE_MONEY" />
|
||||
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
|
||||
<f:selectItem itemLabel="Virement bancaire" itemValue="VIREMENT" />
|
||||
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="referencePaiementPartiel" />
|
||||
<ui:param name="label" value="Référence de paiement" />
|
||||
<ui:param name="value" value="#{cotisationsBean.cotisationSelectionnee.referencePaiement}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgPaiementPartiel').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{cotisationsBean.enregistrerPaiementPartiel(cotisationsBean.cotisationSelectionnee.montantPaye, cotisationsBean.cotisationSelectionnee.methodePaiement, cotisationsBean.cotisationSelectionnee.referencePaiement)}" />
|
||||
<ui:param name="update" value="@form :formPaiements" />
|
||||
<ui:param name="oncomplete" value="PF('dlgPaiementPartiel').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,185 @@
|
||||
<!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:param name="page" value="#{cotisationsGestionBean}"/>
|
||||
<ui:define name="title">Rapports Financiers - 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-chart-bar text-purple-500" />
|
||||
<ui:param name="title" value="Rapports Financiers" />
|
||||
<ui:param name="description" value="Analyse et rapports détaillés sur les cotisations et paiements" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsRapports">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Générer rapport" />
|
||||
<ui:param name="icon" value="pi pi-file-pdf" />
|
||||
<ui:param name="action" value="#{cotisationsBean.genererRapportFinancier}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{cotisationsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Vue d'ensemble -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-chart-line mr-2"></i>
|
||||
Évolution des Paiements (12 derniers mois)
|
||||
</h5>
|
||||
<div class="flex flex-column gap-2 mt-3">
|
||||
<ui:repeat value="#{cotisationsBean.evolutionPaiements}" var="evolution">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="text-600" style="width: 60px;">#{evolution.mois}</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<div class="bg-blue-500 border-round"
|
||||
style="width: #{evolution.hauteur}px; height: 20px; min-width: 10px;"></div>
|
||||
<span class="text-600 text-sm">#{evolution.montantFormatte}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-chart-pie mr-2"></i>
|
||||
Répartition par Méthode
|
||||
</h5>
|
||||
<div class="flex flex-column gap-3 mt-3">
|
||||
<ui:repeat value="#{cotisationsBean.repartitionMethodes}" var="methode">
|
||||
<div>
|
||||
<div class="flex justify-content-between mb-1">
|
||||
<span class="font-medium">#{methode.methode}</span>
|
||||
<span class="text-600">#{methode.pourcentageInt}%</span>
|
||||
</div>
|
||||
<p:progressBar value="#{methode.pourcentageInt}"
|
||||
showValue="false" />
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques détaillées -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.totalCollecteFormatte}" />
|
||||
<ui:param name="label" value="Total Collecté" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.objectifAnnuelFormatte}" />
|
||||
<ui:param name="label" value="Objectif Annuel" />
|
||||
<ui:param name="icon" value="pi pi-target" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.moyenneMensuelleFormattee}" />
|
||||
<ui:param name="label" value="Moyenne Mensuelle" />
|
||||
<ui:param name="icon" value="pi pi-chart-line" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.tauxRecouvrementInt}%" />
|
||||
<ui:param name="label" value="Taux de Recouvrement" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Résumé des cotisations -->
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-list mr-2"></i>
|
||||
Résumé des Cotisations
|
||||
</h5>
|
||||
|
||||
<div class="grid mt-3">
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-3">Par Statut</h6>
|
||||
<div class="flex flex-column gap-2">
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">Payées</span>
|
||||
<p:tag value="#{cotisationsBean.compterParStatut('PAYEE')}"
|
||||
severity="success" />
|
||||
</div>
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">Partiellement payées</span>
|
||||
<p:tag value="#{cotisationsBean.compterParStatut('PARTIELLEMENT_PAYEE')}"
|
||||
severity="info" />
|
||||
</div>
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">En attente</span>
|
||||
<p:tag value="#{cotisationsBean.compterParStatut('EN_ATTENTE')}"
|
||||
severity="warning" />
|
||||
</div>
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">En retard</span>
|
||||
<p:tag value="#{cotisationsBean.compterParStatut('EN_RETARD')}"
|
||||
severity="danger" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-3">Par Type</h6>
|
||||
<div class="flex flex-column gap-2">
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">Mensuelle</span>
|
||||
<p:tag value="#{cotisationsBean.compterParType('MENSUELLE')}" severity="info" />
|
||||
</div>
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">Trimestrielle</span>
|
||||
<p:tag value="#{cotisationsBean.compterParType('TRIMESTRIELLE')}" severity="info" />
|
||||
</div>
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">Semestrielle</span>
|
||||
<p:tag value="#{cotisationsBean.compterParType('SEMESTRIELLE')}" severity="info" />
|
||||
</div>
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">Annuelle</span>
|
||||
<p:tag value="#{cotisationsBean.compterParType('ANNUELLE')}" severity="info" />
|
||||
</div>
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">Adhésion</span>
|
||||
<p:tag value="#{cotisationsBean.compterParType('ADHESION')}" severity="info" />
|
||||
</div>
|
||||
<div class="flex justify-content-between align-items-center p-2 border-round surface-50">
|
||||
<span class="font-medium">Exceptionnelle</span>
|
||||
<p:tag value="#{cotisationsBean.compterParType('EXCEPTIONNELLE')}" severity="info" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,229 @@
|
||||
<!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:param name="page" value="#{cotisationsGestionBean}"/>
|
||||
<ui:define name="title">Relances de Cotisations - 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-send text-orange-500" />
|
||||
<ui:param name="title" value="Relances de Cotisations" />
|
||||
<ui:param name="description" value="Gestion et envoi des relances pour les cotisations en retard" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsRelances">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Relances groupées" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="onclick" value="PF('dlgRelancesGroupes').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{cotisationsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques de relances -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.cotisationsEnRetard}" />
|
||||
<ui:param name="label" value="Cotisations en Retard" />
|
||||
<ui:param name="icon" value="pi pi-exclamation-triangle" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.montantRetardFormatte}" />
|
||||
<ui:param name="label" value="Montant en Retard" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="red" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.rappelsEnAttente.size()}" />
|
||||
<ui:param name="label" value="Rappels en Attente" />
|
||||
<ui:param name="icon" value="pi pi-bell" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{cotisationsBean.statistiques.tauxRecouvrementInt}%" />
|
||||
<ui:param name="label" value="Taux de Recouvrement" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des rappels en attente -->
|
||||
<div class="card">
|
||||
<h5>
|
||||
<i class="pi pi-bell mr-2"></i>
|
||||
Rappels en Attente
|
||||
</h5>
|
||||
|
||||
<p:dataTable id="dtRappels"
|
||||
value="#{cotisationsBean.rappelsEnAttente}"
|
||||
var="rappel"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
emptyMessage="Aucun rappel en attente">
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{rappel.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{rappel.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{rappel.club}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Dû" sortBy="#{rappel.montantDu}" style="width:120px">
|
||||
<h:outputText value="#{rappel.montantDuFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Jours de Retard" sortBy="#{rappel.joursRetard}" style="width:120px">
|
||||
<h:outputText value="#{rappel.joursRetard} jour(s)" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Priorité" sortBy="#{rappel.priorite}" style="width:120px">
|
||||
<p:tag value="#{rappel.priorite}"
|
||||
severity="#{rappel.prioriteSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Envoyer" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{cotisationsBean.envoyerRappel}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="styleClass" value="p-button-sm" />
|
||||
</ui:include>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
<!-- Cotisations en retard -->
|
||||
<div class="card">
|
||||
<h:form id="formRelances">
|
||||
<h5>Cotisations en Retard</h5>
|
||||
|
||||
<p:dataTable id="dtRetard"
|
||||
value="#{cotisationsBean.cotisationsFiltrees}"
|
||||
var="cotisation"
|
||||
filteredValue="#{cotisationsBean.cotisationsFiltrees}"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
emptyMessage="Aucune cotisation en retard"
|
||||
selection="#{cotisationsBean.cotisationsSelectionnees}"
|
||||
selectionMode="multiple">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Cotisations nécessitant une relance</span>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Relancer sélectionnées" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{cotisationsBean.envoyerRappelsGroupes}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="disabled" value="#{empty cotisationsBean.cotisationsSelectionnees}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{cotisation.nomMembre}">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.nomMembre}</div>
|
||||
<div class="text-600 text-sm">#{cotisation.numeroMembre}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{cotisation.typeCotisation}" style="width:120px">
|
||||
<p:tag value="#{cotisation.typeCotisationLibelle}" severity="info" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant Dû" sortBy="#{cotisation.montantDu}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.montantDuFormatte}" styleClass="font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Échéance" sortBy="#{cotisation.dateEcheance}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.dateEcheanceFormatee}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Jours Retard" style="width:120px">
|
||||
<h:outputText value="#{cotisation.joursRetard} jour(s)"
|
||||
styleClass="#{cotisation.joursRetard > 30 ? 'text-red-500 font-bold' : cotisation.joursRetard > 15 ? 'text-orange-500' : 'text-yellow-500'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-send"
|
||||
title="Envoyer un rappel"
|
||||
styleClass="p-button-rounded p-button-text p-button-warning"
|
||||
action="#{cotisationsBean.envoyerRappel(cotisation)}"
|
||||
update="@form" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Relances Groupées -->
|
||||
<p:dialog header="Relances Groupées" widgetVar="dlgRelancesGroupes" modal="true" width="500" resizable="false">
|
||||
<h:form id="formRelancesGroupes">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="messageRelance" value="Message de relance" />
|
||||
<p:inputTextarea id="messageRelance"
|
||||
rows="5"
|
||||
styleClass="w-full"
|
||||
placeholder="Message personnalisé pour les relances..." />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="relanceUrgente" />
|
||||
<p:outputLabel for="relanceUrgente" value=" Marquer comme urgente" />
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Destinataires :</div>
|
||||
<div class="text-600 text-sm">#{cotisationsBean.cotisationsSelectionnees.size()} cotisation(s) sélectionnée(s)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<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('dlgRelancesGroupes').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Envoyer les relances" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{cotisationsBean.envoyerRappelsGroupes}" />
|
||||
<ui:param name="update" value="@form :formRelances" />
|
||||
<ui:param name="oncomplete" value="PF('dlgRelancesGroupes').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,108 @@
|
||||
<!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:param name="page" value="#{cotisationsGestionBean}"/>
|
||||
<ui:define name="title">Rappels de Cotisations - UnionFlow</ui:define>
|
||||
<ui:define name="content">
|
||||
<h:form id="formReminders">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-bell text-primary mr-2"></i>
|
||||
Rappels de Cotisations
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Gérez et envoyez les rappels de cotisations aux membres
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-2 md:mt-0">
|
||||
<p:commandButton value="Envoyer rappels"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-success"
|
||||
action="#{cotisationsGestionBean.envoyerRappelsGroupes}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid mb-3">
|
||||
<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">#{cotisationsGestionBean.nombreMembresEnRetard}</div>
|
||||
<div class="text-orange-700">En Retard</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-exclamation-triangle 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">#{cotisationsGestionBean.nombreRappelsEnvoyes}</div>
|
||||
<div class="text-blue-700">Rappels Envoyé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-send text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des membres en retard -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Membres avec Cotisations en Retard</h5>
|
||||
|
||||
<p:dataTable id="dtRetard"
|
||||
var="membre"
|
||||
value="#{cotisationsGestionBean.membresEnRetard}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
selection="#{cotisationsGestionBean.membresSelectionnes}"
|
||||
selectionMode="multiple"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px"/>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{membre.nomComplet}">
|
||||
<div>
|
||||
<div class="font-medium">#{membre.nomComplet}</div>
|
||||
<small class="text-600">#{membre.numeroMembre}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant dû" sortBy="#{membre.montantDu}">
|
||||
<div class="font-bold text-red-500">#{membre.montantDu} FCFA</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Jours de retard" sortBy="#{membre.joursRetard}">
|
||||
<p:tag value="#{membre.joursRetard} jours" severity="danger"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<p:commandButton icon="pi pi-send"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-primary"
|
||||
action="#{cotisationsGestionBean.envoyerRappel(membre)}"
|
||||
title="Envoyer rappel"/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,117 @@
|
||||
<!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:param name="page" value="#{cotisationsGestionBean}"/>
|
||||
<ui:define name="title">Rapports de Cotisations - UnionFlow</ui:define>
|
||||
<ui:define name="content">
|
||||
<h:form id="formReport">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-file-pdf text-primary mr-2"></i>
|
||||
Rapports de Cotisations
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Générez et consultez les rapports détaillés sur les cotisations
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-2 md:mt-0">
|
||||
<p:commandButton value="Générer rapport"
|
||||
icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-success"
|
||||
action="#{cotisationsGestionBean.genererRapport}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres pour le rapport -->
|
||||
<div class="card mb-3">
|
||||
<h5 class="mb-3">Paramètres du Rapport</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<p:outputLabel for="periodeRapport" value="Période"/>
|
||||
<p:selectOneMenu id="periodeRapport" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Ce mois" itemValue="MOIS_COURANT"/>
|
||||
<f:selectItem itemLabel="Ce trimestre" itemValue="TRIMESTRE_COURANT"/>
|
||||
<f:selectItem itemLabel="Cette année" itemValue="ANNEE_COURANTE"/>
|
||||
<f:selectItem itemLabel="Personnalisée" itemValue="PERSONNALISEE"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<p:outputLabel for="typeRapport" value="Type de rapport"/>
|
||||
<p:selectOneMenu id="typeRapport" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Rapport complet" itemValue="COMPLET"/>
|
||||
<f:selectItem itemLabel="Rapport simplifié" itemValue="SIMPLIFIE"/>
|
||||
<f:selectItem itemLabel="Rapport analytique" itemValue="ANALYTIQUE"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<p:outputLabel for="formatRapport" value="Format"/>
|
||||
<p:selectOneMenu id="formatRapport" styleClass="w-full">
|
||||
<f:selectItem itemLabel="PDF" itemValue="PDF"/>
|
||||
<f:selectItem itemLabel="Excel" itemValue="EXCEL"/>
|
||||
<f:selectItem itemLabel="CSV" itemValue="CSV"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rapports disponibles -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Rapports Disponibles</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-100 border-round p-4 cursor-pointer hover:surface-200 transition-duration-200">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-file-pdf text-red-500 text-2xl mr-3"></i>
|
||||
<div>
|
||||
<h6 class="m-0">Rapport Mensuel</h6>
|
||||
<small class="text-600">Rapport complet du mois</small>
|
||||
</div>
|
||||
</div>
|
||||
<p:commandButton value="Générer"
|
||||
styleClass="ui-button-outlined ui-button-primary w-full"
|
||||
action="#{cotisationsGestionBean.genererRapportMensuel}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-100 border-round p-4 cursor-pointer hover:surface-200 transition-duration-200">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-file-excel text-green-500 text-2xl mr-3"></i>
|
||||
<div>
|
||||
<h6 class="m-0">Rapport Annuel</h6>
|
||||
<small class="text-600">Synthèse de l'année</small>
|
||||
</div>
|
||||
</div>
|
||||
<p:commandButton value="Générer"
|
||||
styleClass="ui-button-outlined ui-button-success w-full"
|
||||
action="#{cotisationsGestionBean.genererRapportAnnuel}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-100 border-round p-4 cursor-pointer hover:surface-200 transition-duration-200">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<i class="pi pi-chart-bar text-blue-500 text-2xl mr-3"></i>
|
||||
<div>
|
||||
<h6 class="m-0">Rapport Analytique</h6>
|
||||
<small class="text-600">Analyses et statistiques</small>
|
||||
</div>
|
||||
</div>
|
||||
<p:commandButton value="Générer"
|
||||
styleClass="ui-button-outlined ui-button-info w-full"
|
||||
action="#{cotisationsGestionBean.genererRapportAnalytique}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
533
target/classes/META-INF/resources/pages/secure/dashboard.xhtml
Normal file
533
target/classes/META-INF/resources/pages/secure/dashboard.xhtml
Normal file
@@ -0,0 +1,533 @@
|
||||
<!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 - Tableau de bord</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<!-- Header avec informations contextuelles -->
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="flex flex-column lg:flex-row lg:align-items-center lg:justify-content-between">
|
||||
<div>
|
||||
<h2 class="text-900 font-medium text-4xl">Tableau de bord UnionFlow</h2>
|
||||
<p class="text-600 text-lg mt-0 mb-3">Bienvenue #{userSession.currentUser.nom}, voici un aperçu de votre union</p>
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-calendar text-blue-500"></i>
|
||||
<span class="text-700 ml-2">#{dashboardBean.currentDate}</span>
|
||||
<span class="mx-3">|</span>
|
||||
<i class="pi pi-users text-green-500"></i>
|
||||
<span class="text-700 ml-2">#{dashboardBean.totalMembers} membres inscrits</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 lg:mt-0">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Rapport mensuel" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{dashboardBean.generateRapport}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="mr-2" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Aide" />
|
||||
<ui:param name="icon" value="pi pi-question-circle" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-help" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alertes URGENTES - En premier pour l'attention immédiate -->
|
||||
<ui:fragment rendered="#{dashboardBean.hasAlerts}">
|
||||
<div class="col-12">
|
||||
<div class="card surface-50 border-round">
|
||||
<h5 class="text-900 font-bold mb-3">
|
||||
<i class="pi pi-exclamation-circle text-orange-500 mr-2"></i>
|
||||
Actions requises aujourd'hui
|
||||
</h5>
|
||||
<div class="grid">
|
||||
<!-- URGENT : Cotisations en retard -->
|
||||
<div class="col-12 md:col-6 lg:col-3">
|
||||
<div class="surface-card border-round p-3 border-left-3 border-red-500 hover-elevate-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-red-100 border-round flex align-items-center justify-content-center mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi pi-exclamation-triangle text-red-600"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-red-900 font-bold text-2xl">#{dashboardBean.cotisationsRetard}</div>
|
||||
<div class="text-red-700 text-sm font-medium">Cotisations en retard</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- IMPORTANT : Adhésions à renouveler -->
|
||||
<div class="col-12 md:col-6 lg:col-3">
|
||||
<div class="surface-card border-round p-3 border-left-3 border-orange-500 hover-elevate-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-orange-100 border-round flex align-items-center justify-content-center mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi pi-clock text-orange-600"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-orange-900 font-bold text-2xl">#{dashboardBean.adhesionsExpiration}</div>
|
||||
<div class="text-orange-700 text-sm font-medium">Expire dans 7 jours</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- À TRAITER : Demandes en attente -->
|
||||
<div class="col-12 md:col-6 lg:col-3">
|
||||
<div class="surface-card border-round p-3 border-left-3 border-blue-500 hover-elevate-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-blue-100 border-round flex align-items-center justify-content-center mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi pi-inbox text-blue-600"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-blue-900 font-bold text-2xl">#{dashboardBean.demandesToTraiter}</div>
|
||||
<div class="text-blue-700 text-sm font-medium">Demandes en attente</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SUCCÈS : Tâches complétées -->
|
||||
<div class="col-12 md:col-6 lg:col-3">
|
||||
<div class="surface-card border-round p-3 border-left-3 border-green-500 hover-elevate-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-green-100 border-round flex align-items-center justify-content-center mr-3"
|
||||
style="width: 2.5rem; height: 2.5rem;">
|
||||
<i class="pi pi-check-circle text-green-600"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-green-900 font-bold text-2xl">#{dashboardBean.tachesCompletees}</div>
|
||||
<div class="text-green-700 text-sm font-medium">Complétées aujourd'hui</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:fragment>
|
||||
|
||||
<!-- KPIs principaux - Ordre psychologique optimal -->
|
||||
<div class="col-12">
|
||||
<h5 class="text-900 font-bold mb-3">
|
||||
<i class="pi pi-chart-bar text-primary mr-2"></i>
|
||||
Vue d'ensemble
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<!-- 1. MEMBRES : L'humain d'abord - le plus important -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Membres Actifs" />
|
||||
<ui:param name="value" value="#{dashboardBean.activeMembers}" />
|
||||
<ui:param name="icon" value="pi-users" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="growthValue" value="#{dashboardBean.membresEvolutionPourcent}" />
|
||||
<ui:param name="growthLabel" value="ce mois" />
|
||||
<ui:param name="progressValue" value="#{dashboardBean.tauxActivite}" />
|
||||
</ui:include>
|
||||
|
||||
<!-- 2. FINANCES : Santé financière - crucial pour la survie -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="FCFA Collectés" />
|
||||
<ui:param name="value" value="#{dashboardBean.totalCotisations}" />
|
||||
<ui:param name="icon" value="pi-dollar" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="growthValue" value="#{dashboardBean.cotisationsEvolutionPourcent}" />
|
||||
<ui:param name="growthLabel" value="vs mois dernier" />
|
||||
<ui:param name="progressValue" value="#{dashboardBean.tauxObjectifCotisations}" />
|
||||
</ui:include>
|
||||
|
||||
<!-- 3. SOLIDARITÉ : Impact social - raison d'être -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="FCFA Distribués" />
|
||||
<ui:param name="value" value="#{dashboardBean.aidesDistribuees}" />
|
||||
<ui:param name="icon" value="pi-heart" />
|
||||
<ui:param name="iconColor" value="purple-600" />
|
||||
<ui:param name="statusIcon" value="pi-circle-fill" />
|
||||
<ui:param name="statusLabel" value="Demandes en attente" />
|
||||
<ui:param name="statusValue" value="#{dashboardBean.pendingAides}" />
|
||||
<ui:param name="progressValue" value="#{dashboardBean.tauxAidesTraitees}" />
|
||||
</ui:include>
|
||||
|
||||
<!-- 4. ENGAGEMENT : Vitalité de l'organisation -->
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Taux de Participation" />
|
||||
<ui:param name="value" value="#{dashboardBean.tauxParticipation}%" />
|
||||
<ui:param name="icon" value="pi-chart-line" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="statusIcon" value="pi-calendar" />
|
||||
<ui:param name="statusLabel" value="Événements prévus" />
|
||||
<ui:param name="statusValue" value="#{dashboardBean.upcomingEvents}" />
|
||||
<ui:param name="progressValue" value="#{dashboardBean.tauxEngagement}" />
|
||||
</ui:include>
|
||||
|
||||
<!-- Tendances financières et analyses -->
|
||||
<div class="col-12 lg:col-8">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<h5>Évolution financière (3 derniers mois)</h5>
|
||||
<div>
|
||||
<h:form>
|
||||
<p:selectOneButton value="#{dashboardBean.periodeGraph}">
|
||||
<f:selectItem itemLabel="3M" itemValue="3M" />
|
||||
<f:selectItem itemLabel="6M" itemValue="6M" />
|
||||
<f:selectItem itemLabel="1A" itemValue="1A" />
|
||||
<p:ajax update="tendancesPanel" />
|
||||
</p:selectOneButton>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h:panelGroup id="tendancesPanel" layout="block">
|
||||
<!-- Graphique avec données dynamiques -->
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{dashboardBean.evolutionFinanciere}" var="mois">
|
||||
<div class="col-4 text-center">
|
||||
<h6 class="text-600 mb-2">#{mois.libelle}</h6>
|
||||
<div class="flex flex-column align-items-center">
|
||||
<div class="bg-blue-500 border-round mb-2" style="width:20px;height:#{mois.hauteur}px;"></div>
|
||||
<span class="text-sm text-600">#{mois.montantFormatte}</span>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
|
||||
<!-- Indicateurs de tendance dynamiques -->
|
||||
<div class="grid mt-4">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="flex align-items-center">
|
||||
<i class="#{dashboardBean.evolutionRecettesIcon} text-2xl mr-2"></i>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{dashboardBean.evolutionRecettesPrefix}#{dashboardBean.evolutionRecettesPourcent}%</div>
|
||||
<span class="text-600 text-sm">Recettes vs mois dernier</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="flex align-items-center">
|
||||
<i class="#{dashboardBean.evolutionDepensesIcon} text-2xl mr-2"></i>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{dashboardBean.evolutionDepensesPrefix}#{dashboardBean.evolutionDepensesPourcent}%</div>
|
||||
<span class="text-600 text-sm">Dépenses vs mois dernier</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-minus text-blue-500 text-2xl mr-2"></i>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{dashboardBean.tendanceParticipation}</div>
|
||||
<span class="text-600 text-sm">Taux de participation</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="card">
|
||||
<h5>État des cotisations</h5>
|
||||
|
||||
<!-- Graphique circulaire dynamique -->
|
||||
<div class="text-center mb-4">
|
||||
<div class="relative inline-block">
|
||||
<div class="w-8rem h-8rem border-circle border-8 border-blue-200 mx-auto mb-3 relative">
|
||||
<div class="absolute top-50 left-50 bg-white border-circle flex align-items-center justify-content-center" style="width: 60px; height: 60px; margin-top: -30px; margin-left: -30px;">
|
||||
<span class="text-900 font-bold">#{dashboardBean.cotisationsAJourPourcent}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Légende avec données dynamiques -->
|
||||
<div class="mt-3">
|
||||
<div class="flex align-items-center justify-content-between py-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="w-1rem h-1rem bg-blue-500 border-round mr-2"></div>
|
||||
<span class="text-600">À jour</span>
|
||||
</div>
|
||||
<span class="text-900 font-medium">#{dashboardBean.cotisationsAJourPourcent}%</span>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between py-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="w-1rem h-1rem bg-orange-500 border-round mr-2"></div>
|
||||
<span class="text-600">En retard</span>
|
||||
</div>
|
||||
<span class="text-900 font-medium">#{dashboardBean.cotisationsRetardPourcent}%</span>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between py-2">
|
||||
<div class="flex align-items-center">
|
||||
<div class="w-1rem h-1rem bg-red-500 border-round mr-2"></div>
|
||||
<span class="text-600">Impayées</span>
|
||||
</div>
|
||||
<span class="text-900 font-medium">#{dashboardBean.cotisationsImpayeesPourcent}%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Barres de progression dynamiques -->
|
||||
<div class="mt-4">
|
||||
<div class="mb-3">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-600">Taux de collecte</span>
|
||||
<span class="text-900 font-medium">#{dashboardBean.tauxCollecte}%</span>
|
||||
</div>
|
||||
<div class="bg-gray-200 border-round overflow-hidden" style="height: 8px;">
|
||||
<div class="bg-green-500 h-full border-round" style="width: #{dashboardBean.tauxCollecte}%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-600">Objectif mensuel</span>
|
||||
<span class="text-900 font-medium">#{dashboardBean.tauxObjectifCotisations}%</span>
|
||||
</div>
|
||||
<div class="bg-gray-200 border-round overflow-hidden" style="height: 8px;">
|
||||
<div class="bg-blue-500 h-full border-round" style="width: #{dashboardBean.tauxObjectifCotisations}%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Journal d'activités et Tâches prioritaires -->
|
||||
<div class="col-12 lg:col-8">
|
||||
<h:form>
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<h5>Journal d'activités</h5>
|
||||
<div>
|
||||
<p:selectOneMenu value="#{dashboardBean.filtreActivite}">
|
||||
<f:selectItem itemLabel="Toutes" itemValue="ALL" />
|
||||
<f:selectItem itemLabel="Cotisations" itemValue="COTISATION" />
|
||||
<f:selectItem itemLabel="Adhésions" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Aides" itemValue="AIDE" />
|
||||
<f:selectItem itemLabel="Événements" itemValue="EVENEMENT" />
|
||||
<p:ajax update="activitiesTable" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<p:dataTable id="activitiesTable" value="#{dashboardBean.recentActivities}" var="activity"
|
||||
rows="8" paginator="true" paginatorPosition="bottom">
|
||||
<p:column headerText="Date" style="width:120px">
|
||||
<div class="flex flex-column">
|
||||
<span class="text-900 font-medium">
|
||||
<h:outputText value="#{activity.date}">
|
||||
<f:convertDateTime pattern="dd/MM HH:mm" type="localDateTime"/>
|
||||
</h:outputText>
|
||||
</span>
|
||||
<small class="text-500">
|
||||
<h:outputText value="#{activity.date}">
|
||||
<f:convertDateTime pattern="yyyy" type="localDateTime"/>
|
||||
</h:outputText>
|
||||
</small>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Activité" style="width:100px">
|
||||
<p:tag value="#{activity.type}" severity="#{activity.severity}"
|
||||
icon="#{activity.icon}" styleClass="mr-2"/>
|
||||
</p:column>
|
||||
<p:column headerText="Description">
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{activity.titre}</div>
|
||||
<div class="text-600 mt-1">#{activity.description}</div>
|
||||
<ui:fragment rendered="#{activity.montant != null}">
|
||||
<div class="mt-2">
|
||||
<span class="text-green-600 font-medium">#{activity.montant} FCFA</span>
|
||||
</div>
|
||||
</ui:fragment>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Acteur" style="width:150px">
|
||||
<div class="flex align-items-center">
|
||||
<p:graphicImage name="images/avatar/profile.jpg" library="demo"
|
||||
styleClass="w-2rem h-2rem border-circle mr-2"/>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{activity.userNom}</div>
|
||||
<small class="text-500">#{activity.userRole}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Action" style="width:80px">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="title" value="Voir détails" />
|
||||
</ui:include>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Actions rapides et Tâches -->
|
||||
<div class="col-12 lg:col-4">
|
||||
<h:form>
|
||||
<div class="card mb-4">
|
||||
<h5>Actions rapides</h5>
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Nouveau membre" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToNewMember}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Collecter" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToCotisation}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Événement" />
|
||||
<ui:param name="icon" value="pi pi-calendar-plus" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToEvenement}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Rapport" />
|
||||
<ui:param name="icon" value="pi pi-chart-bar" />
|
||||
<ui:param name="action" value="#{dashboardBean.generateRapport}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
<div class="card">
|
||||
<h5>Tâches prioritaires</h5>
|
||||
<div class="flex flex-column gap-3">
|
||||
<div class="flex align-items-center p-3 border-round bg-blue-50 border-blue-200">
|
||||
<i class="pi pi-check-circle text-blue-500 text-xl mr-3"></i>
|
||||
<div class="flex-1">
|
||||
<div class="text-900 font-medium">Valider #{dashboardBean.adhesionsPendantes} adhésions</div>
|
||||
<small class="text-600">Demandes en attente de validation</small>
|
||||
</div>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToAdhesionValidation}" />
|
||||
<ui:param name="severity" value="info" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex align-items-center p-3 border-round bg-orange-50 border-orange-200">
|
||||
<i class="pi pi-exclamation-triangle text-orange-500 text-xl mr-3"></i>
|
||||
<div class="flex-1">
|
||||
<div class="text-900 font-medium">Relancer #{dashboardBean.cotisationsRetard} cotisations</div>
|
||||
<small class="text-600">Paiements en retard</small>
|
||||
</div>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToRelances}" />
|
||||
<ui:param name="severity" value="warning" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex align-items-center p-3 border-round bg-green-50 border-green-200">
|
||||
<i class="pi pi-heart text-green-500 text-xl mr-3"></i>
|
||||
<div class="flex-1">
|
||||
<div class="text-900 font-medium">Traiter #{dashboardBean.aidesEnAttente} aides</div>
|
||||
<small class="text-600">Demandes d'aide à examiner</small>
|
||||
</div>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToAidesTraitement}" />
|
||||
<ui:param name="severity" value="success" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex align-items-center p-3 border-round bg-purple-50 border-purple-200">
|
||||
<i class="pi pi-calendar text-purple-500 text-xl mr-3"></i>
|
||||
<div class="flex-1">
|
||||
<div class="text-900 font-medium">Organiser prochains événements</div>
|
||||
<small class="text-600">#{dashboardBean.evenementsAPlanifier} événements à planifier</small>
|
||||
</div>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToEvenementPlanning}" />
|
||||
<ui:param name="styleClass" value="ui-button-help" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tableau de bord financier détaillé -->
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<h5>Résumé financier mensuel</h5>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<h:form>
|
||||
<p:calendar value="#{dashboardBean.moisSelectionne}" view="month"
|
||||
yearNavigator="true" yearRange="2020:2030">
|
||||
<p:ajax update="financialSummary" listener="#{dashboardBean.onMoisChange}"/>
|
||||
</p:calendar>
|
||||
<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="action" value="#{dashboardBean.exportFinancialReport}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h:panelGroup id="financialSummary" layout="block" styleClass="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center p-3 border-round bg-green-50">
|
||||
<div class="text-green-600 font-medium text-xl">#{dashboardBean.recettesMois} FCFA</div>
|
||||
<div class="text-500">Recettes totales</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center p-3 border-round bg-red-50">
|
||||
<div class="text-red-600 font-medium text-xl">#{dashboardBean.depensesMois} FCFA</div>
|
||||
<div class="text-500">Dépenses totales</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center p-3 border-round bg-blue-50">
|
||||
<div class="text-blue-600 font-medium text-xl">#{dashboardBean.soldeMois} FCFA</div>
|
||||
<div class="text-500">Solde net</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center p-3 border-round bg-purple-50">
|
||||
<div class="text-purple-600 font-medium text-xl">#{dashboardBean.tresorerie} FCFA</div>
|
||||
<div class="text-500">Trésorerie actuelle</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,198 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Bilan des Événements - 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-chart-bar text-green-500" />
|
||||
<ui:param name="title" value="Bilan des Événements" />
|
||||
<ui:param name="description" value="Analysez les performances et les résultats de vos événements" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsBilan">
|
||||
<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="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{evenementsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques globales -->
|
||||
<div class="grid mb-3">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.totalEvenements}" />
|
||||
<ui:param name="label" value="Total événements" />
|
||||
<ui:param name="icon" value="pi pi-calendar" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.participantsTotal}" />
|
||||
<ui:param name="label" value="Total participants" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.budgetTotal}" />
|
||||
<ui:param name="label" value="Budget total" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0%" />
|
||||
<ui:param name="label" value="Taux de participation moyen" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchBilan" value="Rechercher" />
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchBilan"
|
||||
placeholder="Titre événement..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" delay="500"/>
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtrePeriode" value="Période" />
|
||||
<p:selectOneMenu id="filtrePeriode" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes périodes" itemValue="" />
|
||||
<f:selectItem itemLabel="Ce mois" itemValue="MOIS" />
|
||||
<f:selectItem itemLabel="Ce trimestre" itemValue="TRIMESTRE" />
|
||||
<f:selectItem itemLabel="Cette année" itemValue="ANNEE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreType" value="Type" />
|
||||
<p:selectOneMenu id="filtreType" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous types" itemValue="" />
|
||||
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Activité Sociale" itemValue="ACTIVITE_SOCIALE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Tableau de bord des bilans -->
|
||||
<div class="grid">
|
||||
<!-- Liste des événements avec bilans -->
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h:form id="formBilans">
|
||||
<h5>Bilans par Événement</h5>
|
||||
|
||||
<p:dataTable id="dtBilans"
|
||||
value="#{evenementsBean.evenementsFiltres}"
|
||||
var="evenement"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
emptyMessage="Aucun bilan trouvé"
|
||||
styleClass="table-responsive">
|
||||
|
||||
<p:column headerText="Événement" sortBy="#{evenement.titre}">
|
||||
<div>
|
||||
<span class="font-semibold">#{evenement.titre}</span>
|
||||
<br/>
|
||||
<span class="text-sm text-600">#{evenement.typeEvenementLibelle}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date">
|
||||
<span>#{evenement.dateDebutFormatee}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Participants">
|
||||
<div>
|
||||
<span class="font-medium">0</span>
|
||||
<span class="text-sm text-600"> / 0 prévus</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Budget">
|
||||
<div>
|
||||
<span class="font-medium">0 XOF</span>
|
||||
<br/>
|
||||
<span class="text-sm text-600">0 XOF prévu</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Taux participation">
|
||||
<p:tag value="0%" severity="info" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width: 150px;">
|
||||
<p:commandButton value="Voir bilan"
|
||||
icon="pi pi-chart-bar"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
outcome="/pages/secure/evenement/bilan-detail" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Graphiques et analyses -->
|
||||
<div class="grid mt-3">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Évolution des participations</h5>
|
||||
<p class="text-600">Graphique en développement</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Répartition par type</h5>
|
||||
<p class="text-600">Graphique en développement</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Calendrier des Événements - UnionFlow</ui:define>
|
||||
<ui:define name="content">
|
||||
<!-- Redirection vers calendrier.xhtml (WOU/DRY - réutiliser la même page) -->
|
||||
<h:form>
|
||||
<p:commandButton value="Voir le calendrier"
|
||||
action="evenementCalendrierPage?faces-redirect=true"
|
||||
styleClass="ui-button-primary"/>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,183 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Calendrier des Événements - 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-calendar-plus text-blue-500" />
|
||||
<ui:param name="title" value="Calendrier des Événements" />
|
||||
<ui:param name="description" value="Vue calendrier de tous les événements de l'organisation" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsCalendrier">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouvel événement" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="outcome" value="/pages/secure/evenement/creation.xhtml" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{evenementsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Calendrier -->
|
||||
<div class="card">
|
||||
<h:form id="formCalendrier">
|
||||
<h5>Calendrier</h5>
|
||||
|
||||
<div class="text-center p-4">
|
||||
<i class="pi pi-calendar text-4xl text-blue-500 mb-3"></i>
|
||||
<h5>Calendrier des Événements</h5>
|
||||
<p class="text-600">La vue calendrier interactive sera disponible prochainement</p>
|
||||
<p class="text-600 mt-2">En attendant, utilisez la liste des événements à venir ci-dessous</p>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Liste des événements à venir -->
|
||||
<div class="card">
|
||||
<h:form id="formListeProchains">
|
||||
<h5>Événements à Venir</h5>
|
||||
|
||||
<p:dataTable id="dtProchains"
|
||||
value="#{evenementsBean.evenementsProchains}"
|
||||
var="evenement"
|
||||
paginator="false"
|
||||
emptyMessage="Aucun événement à venir"
|
||||
rowKey="#{evenement.id}">
|
||||
|
||||
<p:column headerText="Date">
|
||||
<div>
|
||||
<div class="font-medium">#{evenement.dateDebutFormatee}</div>
|
||||
<div class="text-sm text-600">#{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Événement">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="#{evenement.typeEvenementIcon} text-#{evenement.typeEvenementSeverity}"></i>
|
||||
<div>
|
||||
<div class="font-semibold">#{evenement.titre}</div>
|
||||
<div class="text-sm text-600">#{evenement.lieu}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="#{evenement.statutLibelle}"
|
||||
severity="#{evenement.statutSeverity}"
|
||||
icon="#{evenement.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Participants">
|
||||
<div>#{evenement.participantsInscrits} / #{evenement.capaciteMax}</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir détails"
|
||||
styleClass="p-button-text p-button-rounded"
|
||||
action="#{evenementsBean.selectionnerEvenement(evenement)}"
|
||||
update=":formCalendrier:dlgDetails"
|
||||
oncomplete="PF('dlgDetails').show();" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Détails -->
|
||||
<h:form id="formDetails">
|
||||
<p:dialog id="dlgDetails" header="Détails de l'Événement"
|
||||
widgetVar="dlgDetails"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 700px;">
|
||||
<div class="grid" rendered="#{evenementsBean.evenementSelectionne != null}">
|
||||
<div class="col-12">
|
||||
<h4>#{evenementsBean.evenementSelectionne.titre}</h4>
|
||||
<p class="text-600">#{evenementsBean.evenementSelectionne.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Type</label>
|
||||
<p:tag value="#{evenementsBean.evenementSelectionne.typeEvenementLibelle}"
|
||||
severity="#{evenementsBean.evenementSelectionne.typeEvenementSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Statut</label>
|
||||
<p:tag value="#{evenementsBean.evenementSelectionne.statutLibelle}"
|
||||
severity="#{evenementsBean.evenementSelectionne.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Date de début</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.dateDebutFormatee}</div>
|
||||
<div class="text-sm text-600">#{evenementsBean.evenementSelectionne.heureDebutFormatee}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Lieu</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.lieu}</div>
|
||||
<div class="text-sm text-600">#{evenementsBean.evenementSelectionne.adresseComplete}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Participants</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.participantsInscrits} / #{evenementsBean.evenementSelectionne.capaciteMax}</div>
|
||||
<p:progressBar value="#{evenementsBean.evenementSelectionne.tauxRemplissage}"
|
||||
showValue="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Budget</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.budgetFormate}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Voir détails"
|
||||
icon="pi pi-eye"
|
||||
outcome="/pages/secure/evenement/gestion.xhtml"
|
||||
styleClass="p-button-outlined" />
|
||||
<p:commandButton value="Fermer"
|
||||
icon="pi pi-times"
|
||||
onclick="PF('dlgDetails').hide();"
|
||||
styleClass="p-button-secondary p-button-outlined" />
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,18 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Créer un Événement - UnionFlow</ui:define>
|
||||
<ui:define name="content">
|
||||
<!-- Redirection vers creation.xhtml (WOU/DRY - réutiliser la même page) -->
|
||||
<h:form>
|
||||
<p:commandButton value="Créer un événement"
|
||||
action="evenementCreationPage?faces-redirect=true"
|
||||
styleClass="ui-button-primary"/>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,268 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Création d'Événement - 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-plus-circle text-green-500" />
|
||||
<ui:param name="title" value="Créer un Nouvel Événement" />
|
||||
<ui:param name="description" value="Remplissez le formulaire pour créer un nouvel événement" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsCreation">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Retour" />
|
||||
<ui:param name="icon" value="pi pi-arrow-left" />
|
||||
<ui:param name="outcome" value="/pages/secure/evenement/gestion.xhtml" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Formulaire de création -->
|
||||
<div class="card">
|
||||
<h:form id="formCreation">
|
||||
<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">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="titre" />
|
||||
<ui:param name="label" value="Titre de l'événement *" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.titre}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="placeholder" value="Ex: Assemblée Générale Annuelle 2025" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="description" />
|
||||
<ui:param name="label" value="Description" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.description}" />
|
||||
<ui:param name="rows" value="4" />
|
||||
<ui:param name="placeholder" value="Description détaillée de l'événement..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="typeEvenement" />
|
||||
<ui:param name="label" value="Type d'événement *" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.typeEvenement}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Sélectionner un type" itemValue="" />
|
||||
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Activité Sociale" itemValue="ACTIVITE_SOCIALE" />
|
||||
<f:selectItem itemLabel="Action Caritative" itemValue="ACTION_CARITATIVE" />
|
||||
<f:selectItem itemLabel="Réunion de Bureau" itemValue="REUNION_BUREAU" />
|
||||
<f:selectItem itemLabel="Conférence" itemValue="CONFERENCE" />
|
||||
<f:selectItem itemLabel="Atelier" itemValue="ATELIER" />
|
||||
<f:selectItem itemLabel="Cérémonie" itemValue="CEREMONIE" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="priorite" />
|
||||
<ui:param name="label" value="Priorité" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.priorite}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
|
||||
<f:selectItem itemLabel="Basse" itemValue="BASSE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="title">Dates et Horaires</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateDebut" />
|
||||
<ui:param name="label" value="Date de début *" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.dateDebut}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateFin" />
|
||||
<ui:param name="label" value="Date de fin" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.dateFin}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="heureDebut" value="Heure de début" />
|
||||
<p:inputMask id="heureDebut"
|
||||
value="#{evenementsBean.nouvelEvenement.heureDebut}"
|
||||
mask="99:99"
|
||||
placeholder="HH:mm" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="heureFin" value="Heure de fin" />
|
||||
<p:inputMask id="heureFin"
|
||||
value="#{evenementsBean.nouvelEvenement.heureFin}"
|
||||
mask="99:99"
|
||||
placeholder="HH:mm" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="title">Localisation</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="lieu" />
|
||||
<ui:param name="label" value="Lieu *" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.lieu}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="placeholder" value="Ex: Salle de conférence" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="adresse" />
|
||||
<ui:param name="label" value="Adresse" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.adresse}" />
|
||||
<ui:param name="placeholder" value="Adresse complète" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="ville" />
|
||||
<ui:param name="label" value="Ville" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.ville}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="region" />
|
||||
<ui:param name="label" value="Région" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.region}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="title">Organisation et Participants</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="organisateur" />
|
||||
<ui:param name="label" value="Organisateur" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.organisateur}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="capaciteMax" />
|
||||
<ui:param name="label" value="Capacité maximale" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.capaciteMax}" />
|
||||
<ui:param name="min" value="1" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateLimiteInscription" />
|
||||
<ui:param name="label" value="Date limite d'inscription" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.dateLimiteInscription}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-boolean.xhtml">
|
||||
<ui:param name="id" value="inscriptionObligatoire" />
|
||||
<ui:param name="label" value="Inscription obligatoire" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.inscriptionObligatoire}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="title">Budget</ui:define>
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="budget" />
|
||||
<ui:param name="label" value="Budget prévu" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.budget}" />
|
||||
<ui:param name="min" value="0" />
|
||||
<ui:param name="suffix" value=" FCFA" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="codeDevise" />
|
||||
<ui:param name="label" value="Devise" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.codeDevise}" />
|
||||
<ui:param name="placeholder" value="XOF" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="outcome" value="/pages/secure/evenement/gestion.xhtml" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Créer l'événement" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{evenementsBean.creerEvenement}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,528 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Gestion des Événements - 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-calendar text-blue-500" />
|
||||
<ui:param name="title" value="Gestion des Événements" />
|
||||
<ui:param name="description" value="Création, suivi et gestion des événements de l'organisation" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsEvenements">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouvel événement" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="onclick" value="PF('dlgNouvelEvenement').show();" />
|
||||
</ui:include>
|
||||
<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="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{evenementsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.totalEvenements}" />
|
||||
<ui:param name="label" value="Total Événements" />
|
||||
<ui:param name="icon" value="pi pi-calendar" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.evenementsActifs}" />
|
||||
<ui:param name="label" value="Événements Actifs" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.participantsTotal}" />
|
||||
<ui:param name="label" value="Total Participants" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.statistiques.budgetTotal}" />
|
||||
<ui:param name="label" value="Budget Total" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des événements -->
|
||||
<div class="card">
|
||||
<h:form id="formEvenements">
|
||||
<h5>Liste des Événements</h5>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchTitre" value="Rechercher" />
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchTitre"
|
||||
placeholder="Rechercher par titre..."
|
||||
value="#{evenementsBean.filtres.titre}"
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" update="dtEvenements" delay="500"/>
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreType" value="Type" />
|
||||
<p:selectOneMenu id="filtreType"
|
||||
value="#{evenementsBean.filtres.type}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Activité Sociale" itemValue="ACTIVITE_SOCIALE" />
|
||||
<f:selectItem itemLabel="Action Caritative" itemValue="ACTION_CARITATIVE" />
|
||||
<f:selectItem itemLabel="Réunion de Bureau" itemValue="REUNION_BUREAU" />
|
||||
<f:selectItem itemLabel="Conférence" itemValue="CONFERENCE" />
|
||||
<f:selectItem itemLabel="Atelier" itemValue="ATELIER" />
|
||||
<f:selectItem itemLabel="Cérémonie" itemValue="CEREMONIE" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
<p:ajax event="change" update="dtEvenements" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filtreStatut"
|
||||
value="#{evenementsBean.filtres.statut}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Planifié" itemValue="PLANIFIE" />
|
||||
<f:selectItem itemLabel="Confirmé" itemValue="CONFIRME" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
|
||||
<f:selectItem itemLabel="Terminé" itemValue="TERMINE" />
|
||||
<f:selectItem itemLabel="Annulé" itemValue="ANNULE" />
|
||||
<f:selectItem itemLabel="Reporté" itemValue="REPORTE" />
|
||||
<p:ajax event="change" update="dtEvenements" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtrePriorite" value="Priorité" />
|
||||
<p:selectOneMenu id="filtrePriorite"
|
||||
value="#{evenementsBean.filtres.priorite}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les priorités" itemValue="" />
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
|
||||
<f:selectItem itemLabel="Haute" itemValue="HAUTE" />
|
||||
<f:selectItem itemLabel="Normale" itemValue="NORMALE" />
|
||||
<f:selectItem itemLabel="Basse" itemValue="BASSE" />
|
||||
<p:ajax event="change" update="dtEvenements" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
action="#{evenementsBean.reinitialiserFiltres}"
|
||||
update="dtEvenements searchTitre filtreType filtreStatut filtrePriorite"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Tableau des événements -->
|
||||
<p:dataTable id="dtEvenements"
|
||||
value="#{evenementsBean.evenementsFiltres}"
|
||||
var="evenement"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
emptyMessage="Aucun événement trouvé"
|
||||
selection="#{evenementsBean.evenementSelectionne}"
|
||||
selectionMode="single"
|
||||
rowKey="#{evenement.id}">
|
||||
|
||||
<p:column headerText="Titre" sortBy="#{evenement.titre}" filterBy="#{evenement.titre}">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="#{evenement.typeEvenementIcon} text-#{evenement.typeEvenementSeverity}"></i>
|
||||
<span class="font-semibold">#{evenement.titre}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{evenement.typeEvenement}">
|
||||
<p:tag value="#{evenement.typeEvenementLibelle}"
|
||||
severity="#{evenement.typeEvenementSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date" sortBy="#{evenement.dateDebut}">
|
||||
<div>
|
||||
<div class="font-medium">#{evenement.dateDebutFormatee}</div>
|
||||
<div class="text-sm text-600">#{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Lieu">
|
||||
<div>
|
||||
<div class="font-medium">#{evenement.lieu}</div>
|
||||
<div class="text-sm text-600">#{evenement.ville}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{evenement.statut}">
|
||||
<p:tag value="#{evenement.statutLibelle}"
|
||||
severity="#{evenement.statutSeverity}"
|
||||
icon="#{evenement.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Priorité" sortBy="#{evenement.priorite}">
|
||||
<p:tag value="#{evenement.prioriteLibelle}"
|
||||
severity="#{evenement.prioriteSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Participants">
|
||||
<div>
|
||||
<div class="font-medium">#{evenement.participantsInscrits} / #{evenement.capaciteMax}</div>
|
||||
<p:progressBar value="#{evenement.tauxRemplissage}"
|
||||
styleClass="mt-1"
|
||||
showValue="false" />
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width: 200px;">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir détails"
|
||||
styleClass="p-button-text p-button-rounded"
|
||||
action="#{evenementsBean.selectionnerEvenement(evenement)}"
|
||||
update=":formEvenements:dlgDetails"
|
||||
oncomplete="PF('dlgDetails').show();" />
|
||||
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
title="Modifier"
|
||||
styleClass="p-button-text p-button-rounded p-button-success"
|
||||
action="#{evenementsBean.selectionnerEvenement(evenement)}"
|
||||
update=":formEvenements:dlgModifier"
|
||||
oncomplete="PF('dlgModifier').show();" />
|
||||
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
title="Supprimer"
|
||||
styleClass="p-button-text p-button-rounded p-button-danger"
|
||||
action="#{evenementsBean.supprimerEvenement}"
|
||||
update="@form"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir supprimer cet événement ?');" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Nouvel Événement -->
|
||||
<h:form id="formNouvelEvenement">
|
||||
<p:dialog id="dlgNouvelEvenement" header="Nouvel Événement"
|
||||
widgetVar="dlgNouvelEvenement"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 800px;"
|
||||
rendered="#{evenementsBean.nouvelEvenement != null}">
|
||||
<ui:include src="/templates/components/forms/form-section.xhtml">
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="titre" />
|
||||
<ui:param name="label" value="Titre *" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.titre}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="description" />
|
||||
<ui:param name="label" value="Description" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.description}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="typeEvenement" />
|
||||
<ui:param name="label" value="Type d'événement *" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.typeEvenement}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Activité Sociale" itemValue="ACTIVITE_SOCIALE" />
|
||||
<f:selectItem itemLabel="Action Caritative" itemValue="ACTION_CARITATIVE" />
|
||||
<f:selectItem itemLabel="Réunion de Bureau" itemValue="REUNION_BUREAU" />
|
||||
<f:selectItem itemLabel="Conférence" itemValue="CONFERENCE" />
|
||||
<f:selectItem itemLabel="Atelier" itemValue="ATELIER" />
|
||||
<f:selectItem itemLabel="Cérémonie" itemValue="CEREMONIE" />
|
||||
<f:selectItem itemLabel="Autre" itemValue="AUTRE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="priorite" />
|
||||
<ui:param name="label" value="Priorité" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.priorite}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
|
||||
<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="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateDebut" />
|
||||
<ui:param name="label" value="Date de début *" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.dateDebut}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateFin" />
|
||||
<ui:param name="label" value="Date de fin" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.dateFin}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="lieu" />
|
||||
<ui:param name="label" value="Lieu *" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.lieu}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="capaciteMax" />
|
||||
<ui:param name="label" value="Capacité maximale" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.capaciteMax}" />
|
||||
<ui:param name="min" value="1" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="budget" />
|
||||
<ui:param name="label" value="Budget prévu" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.budget}" />
|
||||
<ui:param name="min" value="0" />
|
||||
<ui:param name="suffix" value=" FCFA" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="organisateur" />
|
||||
<ui:param name="label" value="Organisateur" />
|
||||
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.organisateur}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex justify-content-end gap-2" rendered="#{evenementsBean.nouvelEvenement != null}">
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
onclick="PF('dlgNouvelEvenement').hide();"
|
||||
styleClass="p-button-outlined" />
|
||||
<p:commandButton value="Créer"
|
||||
icon="pi pi-check"
|
||||
action="#{evenementsBean.creerEvenement}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) { PF('dlgNouvelEvenement').hide(); }" />
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
|
||||
<!-- Dialog Détails -->
|
||||
<h:form id="formDetails">
|
||||
<p:dialog id="dlgDetails" header="Détails de l'Événement"
|
||||
widgetVar="dlgDetails"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 700px;">
|
||||
<div class="grid" rendered="#{evenementsBean.evenementSelectionne != null}">
|
||||
<div class="col-12">
|
||||
<h4>#{evenementsBean.evenementSelectionne.titre}</h4>
|
||||
<p class="text-600">#{evenementsBean.evenementSelectionne.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Type</label>
|
||||
<p:tag value="#{evenementsBean.evenementSelectionne.typeEvenementLibelle}"
|
||||
severity="#{evenementsBean.evenementSelectionne.typeEvenementSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Statut</label>
|
||||
<p:tag value="#{evenementsBean.evenementSelectionne.statutLibelle}"
|
||||
severity="#{evenementsBean.evenementSelectionne.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Date de début</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.dateDebutFormatee}</div>
|
||||
<div class="text-sm text-600">#{evenementsBean.evenementSelectionne.heureDebutFormatee}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Lieu</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.lieu}</div>
|
||||
<div class="text-sm text-600">#{evenementsBean.evenementSelectionne.adresseComplete}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Participants</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.participantsInscrits} / #{evenementsBean.evenementSelectionne.capaciteMax}</div>
|
||||
<p:progressBar value="#{evenementsBean.evenementSelectionne.tauxRemplissage}"
|
||||
showValue="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Budget</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.budgetFormate}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<p:commandButton value="Fermer"
|
||||
icon="pi pi-times"
|
||||
onclick="PF('dlgDetails').hide();"
|
||||
styleClass="p-button-outlined" />
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
|
||||
<!-- Dialog Modifier -->
|
||||
<h:form id="formModifier">
|
||||
<p:dialog id="dlgModifier" header="Modifier l'Événement"
|
||||
widgetVar="dlgModifier"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 800px;">
|
||||
<div class="grid" rendered="#{evenementsBean.evenementSelectionne != null}">
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="titreModif" />
|
||||
<ui:param name="label" value="Titre *" />
|
||||
<ui:param name="value" value="#{evenementsBean.evenementSelectionne.titre}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="descriptionModif" />
|
||||
<ui:param name="label" value="Description" />
|
||||
<ui:param name="value" value="#{evenementsBean.evenementSelectionne.description}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="statutModif" />
|
||||
<ui:param name="label" value="Statut" />
|
||||
<ui:param name="value" value="#{evenementsBean.evenementSelectionne.statut}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Planifié" itemValue="PLANIFIE" />
|
||||
<f:selectItem itemLabel="Confirmé" itemValue="CONFIRME" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
|
||||
<f:selectItem itemLabel="Terminé" itemValue="TERMINE" />
|
||||
<f:selectItem itemLabel="Annulé" itemValue="ANNULE" />
|
||||
<f:selectItem itemLabel="Reporté" itemValue="REPORTE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateDebutModif" />
|
||||
<ui:param name="label" value="Date de début *" />
|
||||
<ui:param name="value" value="#{evenementsBean.evenementSelectionne.dateDebut}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex justify-content-end gap-2">
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
onclick="PF('dlgModifier').hide();"
|
||||
styleClass="p-button-outlined" />
|
||||
<p:commandButton value="Enregistrer"
|
||||
icon="pi pi-check"
|
||||
action="#{evenementsBean.modifierEvenement}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) { PF('dlgModifier').hide(); }" />
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,180 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Logistique des Événements - 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-truck text-purple-500" />
|
||||
<ui:param name="title" value="Logistique des Événements" />
|
||||
<ui:param name="description" value="Gérez le matériel, les équipements et les ressources nécessaires pour vos événements" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsLogistique">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouvelle demande" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="onclick" value="PF('dlgNouvelleDemande').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{evenementsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid mb-3">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Demandes actives" />
|
||||
<ui:param name="icon" value="pi pi-shopping-cart" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Matériel disponible" />
|
||||
<ui:param name="icon" value="pi pi-box" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="En attente livraison" />
|
||||
<ui:param name="icon" value="pi pi-hourglass" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Fournisseurs" />
|
||||
<ui:param name="icon" value="pi pi-building" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchLogistique" value="Rechercher" />
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchLogistique"
|
||||
placeholder="Événement, matériel..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" delay="500"/>
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreTypeMateriel" value="Type matériel" />
|
||||
<p:selectOneMenu id="filtreTypeMateriel" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous types" itemValue="" />
|
||||
<f:selectItem itemLabel="Sonorisation" itemValue="SONO" />
|
||||
<f:selectItem itemLabel="Éclairage" itemValue="ECLAIRAGE" />
|
||||
<f:selectItem itemLabel="Mobilier" itemValue="MOBILIER" />
|
||||
<f:selectItem itemLabel="Catering" itemValue="CATERING" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filtreStatut" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="Validé" itemValue="VALIDE" />
|
||||
<f:selectItem itemLabel="Livré" itemValue="LIVRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Liste des demandes logistiques -->
|
||||
<div class="card">
|
||||
<h:form id="formLogistique">
|
||||
<h5>Demandes Logistiques</h5>
|
||||
|
||||
<p:dataTable id="dtLogistique"
|
||||
value="#{evenementsBean.evenementsFiltres}"
|
||||
var="evenement"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
emptyMessage="Aucune demande logistique trouvée"
|
||||
styleClass="table-responsive">
|
||||
|
||||
<p:column headerText="Événement" sortBy="#{evenement.titre}">
|
||||
<span class="font-semibold">#{evenement.titre}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type matériel">
|
||||
<p:tag value="À définir" severity="info" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Quantité">
|
||||
<span>0</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date livraison">
|
||||
<span class="text-600">À planifier</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="En attente" severity="warning" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width: 200px;">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir détails"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary mr-2" />
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
title="Modifier"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary mr-2" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Message d'information -->
|
||||
<div class="card">
|
||||
<div class="flex align-items-center gap-3 p-3">
|
||||
<i class="pi pi-info-circle text-blue-500 text-2xl"></i>
|
||||
<div>
|
||||
<h6 class="m-0">Fonctionnalité en développement</h6>
|
||||
<p class="m-0 text-600">La gestion logistique complète des événements sera disponible prochainement.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Gestion des Participants - 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-users text-green-500" />
|
||||
<ui:param name="title" value="Gestion des Participants" />
|
||||
<ui:param name="description" value="Gérer les participants et les inscriptions aux événements" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsParticipants">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Retour" />
|
||||
<ui:param name="icon" value="pi pi-arrow-left" />
|
||||
<ui:param name="outcome" value="/pages/secure/evenement/gestion.xhtml" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{evenementsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Sélection d'événement -->
|
||||
<div class="card">
|
||||
<h:form id="formSelection">
|
||||
<h5>Sélectionner un Événement</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<p:selectOneMenu value="#{evenementsBean.evenementSelectionne}"
|
||||
styleClass="w-full"
|
||||
filter="true"
|
||||
filterMatchMode="contains"
|
||||
placeholder="Sélectionner un événement...">
|
||||
<f:selectItem itemLabel="Sélectionner un événement" itemValue="#{null}" />
|
||||
<f:selectItems value="#{evenementsBean.tousLesEvenements}"
|
||||
var="evt"
|
||||
itemLabel="#{evt.titre} - #{evt.dateDebutFormatee}"
|
||||
itemValue="#{evt}" />
|
||||
<p:ajax event="change" update=":formParticipants" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Liste des participants -->
|
||||
<div class="card" rendered="#{evenementsBean.evenementSelectionne != null}">
|
||||
<h:form id="formParticipants">
|
||||
<h5>Participants - #{evenementsBean.evenementSelectionne.titre}</h5>
|
||||
|
||||
<div class="grid mb-3">
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.evenementSelectionne.participantsInscrits}" />
|
||||
<ui:param name="label" value="Inscrits" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.evenementSelectionne.participantsPresents}" />
|
||||
<ui:param name="label" value="Présents" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{evenementsBean.evenementSelectionne.placesDisponibles}" />
|
||||
<ui:param name="label" value="Places disponibles" />
|
||||
<ui:param name="icon" value="pi pi-ticket" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center p-4">
|
||||
<i class="pi pi-info-circle text-4xl text-blue-500 mb-3"></i>
|
||||
<h5>Gestion des Participants</h5>
|
||||
<p class="text-600">La gestion détaillée des participants sera disponible prochainement</p>
|
||||
<p class="text-600 mt-2">
|
||||
Participants inscrits: <strong>#{evenementsBean.evenementSelectionne.participantsInscrits}</strong> /
|
||||
Capacité: <strong>#{evenementsBean.evenementSelectionne.capaciteMax}</strong>
|
||||
</p>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Message si aucun événement sélectionné -->
|
||||
<div class="card" rendered="#{evenementsBean.evenementSelectionne == null}">
|
||||
<div class="text-center p-4">
|
||||
<i class="pi pi-info-circle text-4xl text-blue-500 mb-3"></i>
|
||||
<h5>Sélectionnez un événement</h5>
|
||||
<p class="text-600">Veuillez sélectionner un événement pour voir ses participants</p>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,255 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Participation aux Événements - 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-calendar-check text-purple-500" />
|
||||
<ui:param name="title" value="Participation aux Événements" />
|
||||
<ui:param name="description" value="Consultez et inscrivez-vous aux événements disponibles" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsParticipation">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{evenementsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Filtres -->
|
||||
<div class="card">
|
||||
<h:form id="formFiltres">
|
||||
<h5>Filtres</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<p:selectOneMenu value="#{evenementsBean.filtres.type}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
|
||||
<f:selectItem itemLabel="Formation" itemValue="FORMATION" />
|
||||
<f:selectItem itemLabel="Activité Sociale" itemValue="ACTIVITE_SOCIALE" />
|
||||
<f:selectItem itemLabel="Action Caritative" itemValue="ACTION_CARITATIVE" />
|
||||
<p:ajax event="change" update=":formListe" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<p:selectOneMenu value="#{evenementsBean.filtres.statut}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Planifié" itemValue="PLANIFIE" />
|
||||
<f:selectItem itemLabel="Confirmé" itemValue="CONFIRME" />
|
||||
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
|
||||
<p:ajax event="change" update=":formListe" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Rechercher"
|
||||
icon="pi pi-search"
|
||||
action="#{evenementsBean.rechercher}"
|
||||
update=":formListe"
|
||||
styleClass="p-button-primary" />
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
action="#{evenementsBean.reinitialiserFiltres}"
|
||||
update="@form :formListe"
|
||||
styleClass="p-button-outlined" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Liste des événements disponibles -->
|
||||
<div class="card">
|
||||
<h:form id="formListe">
|
||||
<h5>Événements Disponibles</h5>
|
||||
|
||||
<p:dataTable id="dtEvenements"
|
||||
value="#{evenementsBean.evenementsFiltres}"
|
||||
var="evenement"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
emptyMessage="Aucun événement disponible"
|
||||
rowKey="#{evenement.id}">
|
||||
|
||||
<p:column headerText="Événement" style="width: 40%;">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="#{evenement.typeEvenementIcon} text-2xl text-#{evenement.typeEvenementSeverity}"></i>
|
||||
<div>
|
||||
<div class="font-semibold text-lg">#{evenement.titre}</div>
|
||||
<div class="text-sm text-600">#{evenement.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date et Heure">
|
||||
<div>
|
||||
<div class="font-medium">#{evenement.dateDebutFormatee}</div>
|
||||
<div class="text-sm text-600">
|
||||
<i class="pi pi-clock"></i> #{evenement.heureDebutFormatee} - #{evenement.heureFinFormatee}
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Lieu">
|
||||
<div>
|
||||
<div class="font-medium">#{evenement.lieu}</div>
|
||||
<div class="text-sm text-600">#{evenement.ville}</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Places">
|
||||
<div>
|
||||
<div class="font-medium">#{evenement.participantsInscrits} / #{evenement.capaciteMax}</div>
|
||||
<p:progressBar value="#{evenement.tauxRemplissage}"
|
||||
showValue="true"
|
||||
styleClass="mt-1" />
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="#{evenement.statutLibelle}"
|
||||
severity="#{evenement.statutSeverity}"
|
||||
icon="#{evenement.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width: 150px;">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton value="Voir détails"
|
||||
icon="pi pi-eye"
|
||||
styleClass="p-button-text p-button-sm"
|
||||
action="#{evenementsBean.selectionnerEvenement(evenement)}"
|
||||
update=":formDetails:dlgDetails"
|
||||
oncomplete="PF('dlgDetails').show();" />
|
||||
|
||||
<p:commandButton value="S'inscrire"
|
||||
icon="pi pi-check"
|
||||
styleClass="p-button-success p-button-sm"
|
||||
rendered="#{evenement.sontInscriptionsOuvertes()}"
|
||||
action="#{evenementsBean.sinscrireEvenement(evenement)}"
|
||||
update="@form"
|
||||
onclick="return confirm('Confirmer votre inscription à cet événement ?');" />
|
||||
|
||||
<p:tag value="Complet"
|
||||
severity="error"
|
||||
rendered="#{evenement.isComplet()}" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Détails -->
|
||||
<h:form id="formDetails">
|
||||
<p:dialog id="dlgDetails" header="Détails de l'Événement"
|
||||
widgetVar="dlgDetails"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 800px;">
|
||||
<div class="grid" rendered="#{evenementsBean.evenementSelectionne != null}">
|
||||
<div class="col-12">
|
||||
<h3>#{evenementsBean.evenementSelectionne.titre}</h3>
|
||||
<p class="text-600 mt-2">#{evenementsBean.evenementSelectionne.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Type</label>
|
||||
<p:tag value="#{evenementsBean.evenementSelectionne.typeEvenementLibelle}"
|
||||
severity="#{evenementsBean.evenementSelectionne.typeEvenementSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Statut</label>
|
||||
<p:tag value="#{evenementsBean.evenementSelectionne.statutLibelle}"
|
||||
severity="#{evenementsBean.evenementSelectionne.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Date de début</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.dateDebutFormatee}</div>
|
||||
<div class="text-sm text-600">#{evenementsBean.evenementSelectionne.heureDebutFormatee}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Date de fin</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.dateFinFormatee}</div>
|
||||
<div class="text-sm text-600">#{evenementsBean.evenementSelectionne.heureFinFormatee}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Lieu</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.adresseComplete}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Participants</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.participantsInscrits} / #{evenementsBean.evenementSelectionne.capaciteMax}</div>
|
||||
<p:progressBar value="#{evenementsBean.evenementSelectionne.tauxRemplissage}"
|
||||
showValue="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Organisateur</label>
|
||||
<div>#{evenementsBean.evenementSelectionne.organisateur}</div>
|
||||
<div class="text-sm text-600">#{evenementsBean.evenementSelectionne.emailOrganisateur}</div>
|
||||
<div class="text-sm text-600">#{evenementsBean.evenementSelectionne.telephoneOrganisateur}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12" rendered="#{evenementsBean.evenementSelectionne.instructions != null}">
|
||||
<div class="field">
|
||||
<label class="font-semibold">Instructions</label>
|
||||
<div class="surface-50 p-3 border-round">#{evenementsBean.evenementSelectionne.instructions}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="S'inscrire"
|
||||
icon="pi pi-check"
|
||||
rendered="#{evenementsBean.evenementSelectionne != null and evenementsBean.evenementSelectionne.sontInscriptionsOuvertes()}"
|
||||
action="#{evenementsBean.sinscrireEvenement(evenementsBean.evenementSelectionne)}"
|
||||
update="@form"
|
||||
onclick="PF('dlgDetails').hide(); return confirm('Confirmer votre inscription ?');" />
|
||||
<p:commandButton value="Fermer"
|
||||
icon="pi pi-times"
|
||||
onclick="PF('dlgDetails').hide();"
|
||||
styleClass="p-button-secondary p-button-outlined" />
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,179 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Planification des Événements - 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-clock text-orange-500" />
|
||||
<ui:param name="title" value="Planification des Événements" />
|
||||
<ui:param name="description" value="Planifiez et organisez vos événements à l'avance" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsPlanification">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouvelle planification" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="onclick" value="PF('dlgNouvellePlanification').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{evenementsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid mb-3">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Événements planifiés" />
|
||||
<ui:param name="icon" value="pi pi-calendar-check" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="À venir (7 jours)" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="En attente validation" />
|
||||
<ui:param name="icon" value="pi pi-hourglass" />
|
||||
<ui:param name="bgColor" value="yellow" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Taux de réalisation" />
|
||||
<ui:param name="icon" value="pi pi-percentage" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchPlanification" value="Rechercher" />
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchPlanification"
|
||||
placeholder="Titre, description..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" delay="500"/>
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtrePeriode" value="Période" />
|
||||
<p:selectOneMenu id="filtrePeriode" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes périodes" itemValue="" />
|
||||
<f:selectItem itemLabel="Cette semaine" itemValue="SEMAINE" />
|
||||
<f:selectItem itemLabel="Ce mois" itemValue="MOIS" />
|
||||
<f:selectItem itemLabel="Ce trimestre" itemValue="TRIMESTRE" />
|
||||
<f:selectItem itemLabel="Cette année" itemValue="ANNEE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filtreStatut" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Planifié" itemValue="PLANIFIE" />
|
||||
<f:selectItem itemLabel="Confirmé" itemValue="CONFIRME" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Liste des planifications -->
|
||||
<div class="card">
|
||||
<h:form id="formPlanifications">
|
||||
<h5>Planifications</h5>
|
||||
|
||||
<p:dataTable id="dtPlanifications"
|
||||
value="#{evenementsBean.evenementsFiltres}"
|
||||
var="evenement"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
emptyMessage="Aucune planification trouvée"
|
||||
styleClass="table-responsive">
|
||||
|
||||
<p:column headerText="Titre" sortBy="#{evenement.titre}">
|
||||
<span class="font-semibold">#{evenement.titre}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date prévue">
|
||||
<div>
|
||||
<div class="font-medium">Date à définir</div>
|
||||
<div class="text-sm text-600">Période: À planifier</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="Planifié" severity="info" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Priorité">
|
||||
<p:tag value="Normale" severity="info" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width: 200px;">
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
title="Modifier"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary mr-2" />
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
title="Supprimer"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Message d'information -->
|
||||
<div class="card">
|
||||
<div class="flex align-items-center gap-3 p-3">
|
||||
<i class="pi pi-info-circle text-blue-500 text-2xl"></i>
|
||||
<div>
|
||||
<h6 class="m-0">Fonctionnalité en développement</h6>
|
||||
<p class="m-0 text-600">La planification avancée des événements sera disponible prochainement.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
<!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:param name="page" value="#{evenementsBean}"/>
|
||||
<ui:define name="title">Réservations d'Événements - 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-ticket text-cyan-500" />
|
||||
<ui:param name="title" value="Réservations d'Événements" />
|
||||
<ui:param name="description" value="Gérez les réservations et inscriptions aux événements" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsReservations">
|
||||
<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="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{evenementsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid mb-3">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Réservations totales" />
|
||||
<ui:param name="icon" value="pi pi-ticket" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="En attente" />
|
||||
<ui:param name="icon" value="pi pi-hourglass" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Confirmées" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="0" />
|
||||
<ui:param name="label" value="Annulées" />
|
||||
<ui:param name="icon" value="pi pi-times-circle" />
|
||||
<ui:param name="bgColor" value="red" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchReservation" value="Rechercher" />
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchReservation"
|
||||
placeholder="Membre, événement..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" delay="500"/>
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filtreStatut" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE" />
|
||||
<f:selectItem itemLabel="Confirmée" itemValue="CONFIRMEE" />
|
||||
<f:selectItem itemLabel="Annulée" itemValue="ANNULEE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreEvenement" value="Événement" />
|
||||
<p:selectOneMenu id="filtreEvenement" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous événements" itemValue="" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Liste des réservations -->
|
||||
<div class="card">
|
||||
<h:form id="formReservations">
|
||||
<h5>Réservations</h5>
|
||||
|
||||
<p:dataTable id="dtReservations"
|
||||
value="#{evenementsBean.evenementsFiltres}"
|
||||
var="evenement"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
emptyMessage="Aucune réservation trouvée"
|
||||
styleClass="table-responsive">
|
||||
|
||||
<p:column headerText="Membre">
|
||||
<div>
|
||||
<span class="font-semibold">Nom du membre</span>
|
||||
<br/>
|
||||
<span class="text-sm text-600">email@example.com</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Événement" sortBy="#{evenement.titre}">
|
||||
<span class="font-semibold">#{evenement.titre}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date réservation">
|
||||
<span>À définir</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Nombre places">
|
||||
<span class="font-medium">1</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant">
|
||||
<span class="font-medium">0 XOF</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="En attente" severity="warning" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width: 250px;">
|
||||
<p:commandButton icon="pi pi-check"
|
||||
title="Confirmer"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success mr-2" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
title="Annuler"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger mr-2" />
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir détails"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Message d'information -->
|
||||
<div class="card">
|
||||
<div class="flex align-items-center gap-3 p-3">
|
||||
<i class="pi pi-info-circle text-blue-500 text-2xl"></i>
|
||||
<div>
|
||||
<h6 class="m-0">Fonctionnalité en développement</h6>
|
||||
<p class="m-0 text-600">Le système de réservations complet sera disponible prochainement.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
<!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">
|
||||
|
||||
<f:metadata>
|
||||
<f:viewParam name="id" value="#{membreCotisationBean.membreId}"/>
|
||||
<f:event type="preRenderView" listener="#{membreCotisationBean.init}"/>
|
||||
</f:metadata>
|
||||
|
||||
<ui:param name="page" value="#{membreCotisationBean}"/>
|
||||
<ui:define name="title">Cotisations du Membre - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formCotisations">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<i class="pi pi-dollar text-green-500 mr-2"></i>
|
||||
Cotisations du Membre
|
||||
</h3>
|
||||
<p class="text-600 m-0 mt-2">
|
||||
Membre: #{membreCotisationBean.numeroMembre} •
|
||||
Statut: #{membreCotisationBean.statutCotisations}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-2 md:mt-0">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Retour au profil"/>
|
||||
<ui:param name="icon" value="pi pi-arrow-left"/>
|
||||
<ui:param name="outcome" value="membreProfilPage"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Résumé cotisations -->
|
||||
<div class="grid mb-3">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Payées" />
|
||||
<ui:param name="value" value="#{membreCotisationBean.cotisationsPayees}" />
|
||||
<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-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="En Attente" />
|
||||
<ui:param name="value" value="#{membreCotisationBean.cotisationsEnAttente}" />
|
||||
<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-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Montant Dû" />
|
||||
<ui:param name="value" value="#{membreCotisationBean.montantDu}" />
|
||||
<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-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Total Versé" />
|
||||
<ui:param name="value" value="#{membreCotisationBean.totalVerse}" />
|
||||
<ui:param name="icon" value="pi-dollar" />
|
||||
<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-3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des cotisations -->
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Historique des Cotisations</h5>
|
||||
|
||||
<!-- Filtres -->
|
||||
<p:toolbar>
|
||||
<p:toolbarGroup>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<p:selectOneMenu value="#{membreCotisationBean.anneeFilter}">
|
||||
<f:selectItem itemLabel="Cette année" itemValue="2024"/>
|
||||
<f:selectItem itemLabel="2023" itemValue="2023"/>
|
||||
<f:selectItem itemLabel="2022" itemValue="2022"/>
|
||||
<f:selectItem itemLabel="Toutes" itemValue=""/>
|
||||
<p:ajax event="change" update="dtCotisations"/>
|
||||
</p:selectOneMenu>
|
||||
|
||||
<p:selectOneMenu value="#{membreCotisationBean.statutFilter}">
|
||||
<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"/>
|
||||
<p:ajax event="change" update="dtCotisations"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</p:toolbarGroup>
|
||||
<p:toolbarGroup align="right">
|
||||
<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="#{membreCotisationBean.actualiser}" />
|
||||
<ui:param name="update" value=":formCotisations:dtCotisations" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtCotisations"
|
||||
var="cotisation"
|
||||
value="#{membreCotisationBean.cotisations}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="5,10,25"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column headerText="Référence" sortBy="#{cotisation.reference}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.reference}" styleClass="font-mono font-bold"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Période" sortBy="#{cotisation.periode}">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.libelle}</div>
|
||||
<small class="text-600">#{cotisation.periode}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{cotisation.type}" style="width:140px">
|
||||
<p:tag value="#{cotisation.type}"
|
||||
severity="#{cotisation.typeSeverity}"
|
||||
icon="pi #{cotisation.typeIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant" sortBy="#{cotisation.montant}" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-green-500">#{cotisation.montant}</div>
|
||||
<small class="text-600">FCFA</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{cotisation.statut}" style="width:120px">
|
||||
<p:tag value="#{cotisation.statut}"
|
||||
severity="#{cotisation.statutSeverity}"
|
||||
icon="pi #{cotisation.statutIcon}"/>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Échéance" sortBy="#{cotisation.dateEcheance}" style="width:120px">
|
||||
<div>
|
||||
<div class="font-medium">#{cotisation.dateEcheance}</div>
|
||||
<small class="#{cotisation.retardColor}">#{cotisation.statutEcheance}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date paiement" sortBy="#{cotisation.datePaiement}" style="width:120px">
|
||||
<h:outputText value="#{cotisation.datePaiement}" rendered="#{cotisation.datePaiement != null}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate"/>
|
||||
</h:outputText>
|
||||
<span class="text-400" rendered="#{cotisation.datePaiement == null}">Non payée</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-credit-card"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{membreCotisationBean.payerCotisation(cotisation)}"
|
||||
title="Payer"
|
||||
rendered="#{cotisation.statut != 'PAYE' and cotisation.statut != 'PAYEE'}"/>
|
||||
<p:commandButton icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{membreCotisationBean.telechargerRecu(cotisation)}"
|
||||
title="Télécharger reçu"
|
||||
rendered="#{cotisation.statut == 'PAYE' or cotisation.statut == 'PAYEE'}"/>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
<!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:param name="page" value="#{membreExportBean}"/>
|
||||
<ui:define name="title">Export des Membres - 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-download text-blue-500" />
|
||||
<ui:param name="title" value="Export des Membres" />
|
||||
<ui:param name="description" value="Exportez les données des membres dans différents formats" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsEntete">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Retour" />
|
||||
<ui:param name="icon" value="pi pi-arrow-left" />
|
||||
<ui:param name="outcome" value="/pages/secure/membre/liste" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques -->
|
||||
<div class="grid mb-3">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Total Membres" />
|
||||
<ui:param name="value" value="#{membreExportBean.totalMembres}" />
|
||||
<ui:param name="icon" value="pi-users" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="colSize" value="col-12 md:col-4" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Membres Actifs" />
|
||||
<ui:param name="value" value="#{membreExportBean.membresActifs}" />
|
||||
<ui:param name="icon" value="pi-check-circle" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="colSize" value="col-12 md:col-4" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Membres Inactifs" />
|
||||
<ui:param name="value" value="#{membreExportBean.membresInactifs}" />
|
||||
<ui:param name="icon" value="pi-times-circle" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="colSize" value="col-12 md:col-4" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Formulaire d'export -->
|
||||
<div class="card">
|
||||
<h:form id="formExport">
|
||||
<h5 class="mb-4">Configuration de l'export</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="formatExport" value="Format d'export *" />
|
||||
<p:selectOneMenu id="formatExport" value="#{membreExportBean.formatExport}" required="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Excel (.xlsx)" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="CSV (.csv)" itemValue="CSV" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="scopeExport" value="Portée de l'export *" />
|
||||
<p:selectOneMenu id="scopeExport" value="#{membreExportBean.scopeExport}" required="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les membres" itemValue="TOUS" />
|
||||
<f:selectItem itemLabel="Membres actifs uniquement" itemValue="ACTIFS" />
|
||||
<f:selectItem itemLabel="Membres inactifs uniquement" itemValue="INACTIFS" />
|
||||
<f:selectItem itemLabel="Membres sélectionnés" itemValue="SELECTION" />
|
||||
<p:ajax event="change" listener="#{membreExportBean.actualiserCompteur}" update=":formExport" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Colonnes à exporter" />
|
||||
<ui:define name="content">
|
||||
<div class="field">
|
||||
<p:outputLabel for="colonnesExport" value="Sélectionnez les colonnes à inclure *" />
|
||||
<p:selectCheckboxMenu id="colonnesExport"
|
||||
value="#{membreExportBean.colonnesExport}"
|
||||
multiple="true"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Informations personnelles (Nom, Prénom, Date naissance, Genre)" itemValue="PERSO" />
|
||||
<f:selectItem itemLabel="Coordonnées (Email, Téléphone, Adresse)" itemValue="CONTACT" />
|
||||
<f:selectItem itemLabel="Informations adhésion (Date adhésion, Type membre, Statut)" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Cotisations (Statut cotisations, Dernier paiement)" itemValue="COTISATIONS" />
|
||||
<f:selectItem itemLabel="Participation événements (Taux participation, Événements)" itemValue="EVENEMENTS" />
|
||||
<f:selectItem itemLabel="Organisation (Entité, Ville)" itemValue="ORGANISATION" />
|
||||
<f:selectItem itemLabel="Famille (Membres de famille déclarés)" itemValue="FAMILLE" />
|
||||
</p:selectCheckboxMenu>
|
||||
<small class="text-600">Sélectionnez au moins une catégorie de colonnes</small>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Filtres optionnels" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="statutFilter" value="Statut" />
|
||||
<p:selectOneMenu id="statutFilter" value="#{membreExportBean.statutFilter}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Inactif" itemValue="INACTIF" />
|
||||
<f:selectItem itemLabel="Suspendu" itemValue="SUSPENDU" />
|
||||
<f:selectItem itemLabel="Radié" itemValue="RADIE" />
|
||||
<p:ajax event="change" listener="#{membreExportBean.actualiserCompteur}" update=":formExport" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="typeFilter" value="Type de membre" />
|
||||
<p:selectOneMenu id="typeFilter" value="#{membreExportBean.typeFilter}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Associé" itemValue="ASSOCIE" />
|
||||
<f:selectItem itemLabel="Bienfaiteur" itemValue="BIENFAITEUR" />
|
||||
<f:selectItem itemLabel="Honoraire" itemValue="HONORAIRE" />
|
||||
<p:ajax event="change" listener="#{membreExportBean.actualiserCompteur}" update=":formExport" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="organisationFilter" value="Organisation" />
|
||||
<p:selectOneMenu id="organisationFilter" value="#{membreExportBean.organisationId}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Toutes les organisations" itemValue="" />
|
||||
<f:selectItems value="#{membreExportBean.organisationsDisponibles}"
|
||||
var="org"
|
||||
itemLabel="#{org.nom} (#{org.ville})"
|
||||
itemValue="#{org.id}" />
|
||||
<p:ajax event="change" listener="#{membreExportBean.actualiserCompteur}" update=":formExport" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="dateAdhesionDebut" value="Adhésion après le" />
|
||||
<p:calendar id="dateAdhesionDebut"
|
||||
value="#{membreExportBean.dateAdhesionDebut}"
|
||||
showIcon="true"
|
||||
navigator="true"
|
||||
locale="fr"
|
||||
pattern="dd/MM/yyyy"
|
||||
styleClass="w-full">
|
||||
<p:ajax event="dateSelect" listener="#{membreExportBean.actualiserCompteur}" update=":formExport" />
|
||||
</p:calendar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="dateAdhesionFin" value="Adhésion avant le" />
|
||||
<p:calendar id="dateAdhesionFin"
|
||||
value="#{membreExportBean.dateAdhesionFin}"
|
||||
showIcon="true"
|
||||
navigator="true"
|
||||
locale="fr"
|
||||
pattern="dd/MM/yyyy"
|
||||
styleClass="w-full">
|
||||
<p:ajax event="dateSelect" listener="#{membreExportBean.actualiserCompteur}" update=":formExport" />
|
||||
</p:calendar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Options d'export -->
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Options d'export" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="inclureHeaders" value="#{membreExportBean.inclureHeaders}" />
|
||||
<p:outputLabel for="inclureHeaders" value="Inclure les en-têtes de colonnes" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="formaterDates" value="#{membreExportBean.formaterDates}" />
|
||||
<p:outputLabel for="formaterDates" value="Formater les dates (DD/MM/YYYY)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="inclureStatistiques" value="#{membreExportBean.inclureStatistiques}" />
|
||||
<p:outputLabel for="inclureStatistiques" value="Inclure un onglet statistiques (Excel uniquement)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="chiffrerDonnees" value="#{membreExportBean.chiffrerDonnees}" />
|
||||
<p:outputLabel for="chiffrerDonnees" value="Chiffrer le fichier exporté" />
|
||||
<small class="text-600 block mt-1">Le fichier sera protégé par un mot de passe (généré automatiquement ou personnalisé ci-dessous)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12" rendered="#{membreExportBean.chiffrerDonnees}">
|
||||
<div class="field">
|
||||
<p:outputLabel for="motDePasseExport" value="Mot de passe personnalisé (optionnel)" />
|
||||
<p:password id="motDePasseExport" value="#{membreExportBean.motDePasseExport}"
|
||||
placeholder="Laisser vide pour générer automatiquement"
|
||||
styleClass="w-full" />
|
||||
<small class="text-600 block mt-1">Si vide, un mot de passe aléatoire sera généré et affiché après l'export</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Aperçu du nombre de membres à exporter -->
|
||||
<div class="surface-50 p-3 border-round mb-4">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<div class="font-medium mb-1">Nombre de membres à exporter :</div>
|
||||
<div class="text-600">#{membreExportBean.nombreMembresAExporter} membre(s) correspond(ent) aux critères sélectionnés</div>
|
||||
</div>
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Actualiser le compteur" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{membreExportBean.actualiserCompteur}" />
|
||||
<ui:param name="update" value=":formExport" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Générer l'export" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreExportBean.exporterMembres}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="disabled" value="#{membreExportBean.colonnesExport == null or membreExportBean.colonnesExport.isEmpty() or membreExportBean.nombreMembresAExporter == 0}" />
|
||||
</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="#{membreExportBean.reinitialiser}" />
|
||||
<ui:param name="update" value=":formExport" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Historique des exports -->
|
||||
<div class="card mt-3">
|
||||
<h5 class="mb-3">Historique des exports</h5>
|
||||
<p:dataTable value="#{membreExportBean.historiqueExports}" var="export"
|
||||
styleClass="p-datatable-sm"
|
||||
emptyMessage="Aucun export effectué">
|
||||
<p:column headerText="Date">
|
||||
<h:outputText value="#{export.date}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy HH:mm" type="localDateTime" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Format">
|
||||
<p:tag value="#{export.format}" severity="info" />
|
||||
</p:column>
|
||||
<p:column headerText="Nombre de membres">
|
||||
<h:outputText value="#{export.nombreMembres}" />
|
||||
</p:column>
|
||||
<p:column headerText="Taille">
|
||||
<h:outputText value="#{export.taille}" />
|
||||
</p:column>
|
||||
<p:column headerText="Actions">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreExportBean.telechargerExport(export)}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="title" value="Télécharger" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
<!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:param name="page" value="#{membreImportBean}"/>
|
||||
<ui:define name="title">Import en Masse des Membres - 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-upload text-green-500" />
|
||||
<ui:param name="title" value="Import en Masse des Membres" />
|
||||
<ui:param name="description" value="Importez plusieurs membres à la fois depuis un fichier Excel" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsEntete">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Retour" />
|
||||
<ui:param name="icon" value="pi pi-arrow-left" />
|
||||
<ui:param name="outcome" value="/pages/secure/membre/liste" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Instructions -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex align-items-start">
|
||||
<i class="pi pi-info-circle text-blue-500 text-2xl mr-3"></i>
|
||||
<div class="flex-1">
|
||||
<h5 class="mt-0 mb-2">Instructions d'import</h5>
|
||||
<p class="text-600 mb-3">
|
||||
Téléchargez le modèle Excel, remplissez-le avec les données des membres, puis importez-le ici.
|
||||
</p>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-2">Format du fichier :</h6>
|
||||
<ul class="text-600 text-sm m-0 pl-3">
|
||||
<li>Format Excel (.xlsx) ou CSV (.csv)</li>
|
||||
<li>Maximum 1000 lignes par import</li>
|
||||
<li>Taille maximale : 10 MB</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-2">Colonnes requises :</h6>
|
||||
<ul class="text-600 text-sm m-0 pl-3">
|
||||
<li>Nom, Prénom (obligatoires)</li>
|
||||
<li>Email, Téléphone (obligatoires)</li>
|
||||
<li>Date de naissance, Adresse</li>
|
||||
<li>Profession, Type membre</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Formulaire d'import -->
|
||||
<div class="card">
|
||||
<h:form id="formImport" enctype="multipart/form-data">
|
||||
<h5 class="mb-4">Fichier à importer</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<div class="field">
|
||||
<p:outputLabel for="fichierImport" value="Fichier Excel/CSV *" />
|
||||
<p:fileUpload id="fichierImport"
|
||||
mode="advanced"
|
||||
dragDropSupport="true"
|
||||
skinSimple="false"
|
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,text/csv"
|
||||
fileLimit="1"
|
||||
sizeLimit="10485760"
|
||||
uploadLabel="Importer"
|
||||
cancelLabel="Annuler"
|
||||
chooseLabel="Sélectionner le fichier"
|
||||
invalidFileMessage="Type de fichier non supporté"
|
||||
fileLimitMessage="Un seul fichier autorisé"
|
||||
invalidSizeMessage="Taille de fichier trop importante (max 10MB)"
|
||||
fileUploadListener="#{membreImportBean.handleFileUpload}"
|
||||
update=":formImport"
|
||||
styleClass="w-full" />
|
||||
<small class="text-600">Formats acceptés : .xlsx, .xls, .csv - Maximum 10 MB</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel />
|
||||
<div class="flex flex-column gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Télécharger modèle" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreImportBean.telechargerModele}" />
|
||||
<ui:param name="update" value="none" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Options d'import" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="mettreAJourExistants" value="#{membreImportBean.mettreAJourExistants}" />
|
||||
<p:outputLabel for="mettreAJourExistants" value="Mettre à jour les membres existants" />
|
||||
<small class="text-600 block mt-1">Si coché, les membres existants (même email) seront mis à jour</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="ignorerErreurs" value="#{membreImportBean.ignorerErreurs}" />
|
||||
<p:outputLabel for="ignorerErreurs" value="Ignorer les lignes en erreur" />
|
||||
<small class="text-600 block mt-1">Continuer l'import même si certaines lignes contiennent des erreurs</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="organisationImport" value="Organisation par défaut" />
|
||||
<p:selectOneMenu id="organisationImport" value="#{membreImportBean.organisationId}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionner une organisation..." itemValue="" />
|
||||
<f:selectItems value="#{membreImportBean.organisationsDisponibles}"
|
||||
var="org"
|
||||
itemLabel="#{org.nom} (#{org.ville})"
|
||||
itemValue="#{org.id}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="typeMembreImport" value="Type de membre par défaut" />
|
||||
<p:selectOneMenu id="typeMembreImport" value="#{membreImportBean.typeMembreDefaut}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Associé" itemValue="ASSOCIE" />
|
||||
<f:selectItem itemLabel="Bienfaiteur" itemValue="BIENFAITEUR" />
|
||||
<f:selectItem itemLabel="Honoraire" itemValue="HONORAIRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Résultats de l'import -->
|
||||
<div class="mt-4" rendered="#{membreImportBean.resultatImport != null}">
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Résultat de l'import" />
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Total traité" />
|
||||
<ui:param name="value" value="#{membreImportBean.resultatImport.totalTraite}" />
|
||||
<ui:param name="icon" value="pi-file" />
|
||||
<ui:param name="iconColor" value="blue-600" />
|
||||
<ui:param name="colSize" value="col-12" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Réussis" />
|
||||
<ui:param name="value" value="#{membreImportBean.resultatImport.reussis}" />
|
||||
<ui:param name="icon" value="pi-check" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="colSize" value="col-12" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Échecs" />
|
||||
<ui:param name="value" value="#{membreImportBean.resultatImport.echecs}" />
|
||||
<ui:param name="icon" value="pi-times" />
|
||||
<ui:param name="iconColor" value="red-600" />
|
||||
<ui:param name="colSize" value="col-12" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Ignorés" />
|
||||
<ui:param name="value" value="#{membreImportBean.resultatImport.ignores}" />
|
||||
<ui:param name="icon" value="pi-eye-slash" />
|
||||
<ui:param name="iconColor" value="orange-600" />
|
||||
<ui:param name="colSize" value="col-12" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3" rendered="#{not empty membreImportBean.resultatImport.erreurs}">
|
||||
<h6 class="mb-2">Détails des erreurs :</h6>
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<ui:repeat value="#{membreImportBean.resultatImport.erreurs}" var="erreur">
|
||||
<div class="mb-2">
|
||||
<span class="font-medium">Ligne #{erreur.ligne}:</span>
|
||||
<span class="text-red-500 ml-2">#{erreur.message}</span>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="flex gap-2 mt-4">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Lancer l'import" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="action" value="#{membreImportBean.importerMembres}" />
|
||||
<ui:param name="update" value=":formImport" />
|
||||
<ui:param name="disabled" value="#{membreImportBean.fichierImport == null}" />
|
||||
</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="#{membreImportBean.reinitialiser}" />
|
||||
<ui:param name="update" value=":formImport" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,759 @@
|
||||
<!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:param name="page" value="#{membreInscriptionBean}"/>
|
||||
<ui:define name="title">Inscription Membre - 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-user-plus text-primary" />
|
||||
<ui:param name="title" value="Inscription Nouveau Membre" />
|
||||
<ui:param name="description" value="Formulaire complet d'inscription avec photo et documents" />
|
||||
<ui:define name="actions">
|
||||
<div>
|
||||
<div class="text-900 font-medium">Numéro: #{membreInscriptionBean.numeroGenere}</div>
|
||||
<small class="text-600">Généré automatiquement</small>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<h:form>
|
||||
<p:messages id="messages" showDetail="true" closable="true" globalOnly="false" />
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Informations personnelles" />
|
||||
<ui:param name="fluid" value="true" />
|
||||
<ui:define name="content">
|
||||
<!-- Section photo intégrée -->
|
||||
<div class="text-center mb-4 pb-3" style="border-bottom: 1px solid var(--surface-border);">
|
||||
<div class="mb-3 relative">
|
||||
<div id="photoContainer" style="width: 120px; height: 120px; margin: 0 auto; position: relative; overflow: hidden; border-radius: 50%; border: 3px solid var(--surface-border); background: #f8f9fa;">
|
||||
<img id="photoPreview"
|
||||
alt="Photo du membre"
|
||||
style="width: auto; height: 120px; min-width: 120px; object-fit: cover; display: none; position: absolute; cursor: move; user-select: none;"
|
||||
draggable="false" />
|
||||
<div id="photoPlaceholder"
|
||||
style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; position: absolute; top: 0; left: 0;">
|
||||
<i class="pi pi-camera" style="font-size: 2rem; color: #6c757d;"></i>
|
||||
</div>
|
||||
<div id="photoOverlay"
|
||||
style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.1); display: none; pointer-events: none; border-radius: 50%;">
|
||||
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 0.75rem; text-align: center;">
|
||||
<i class="pi pi-arrows-alt"></i><br/>
|
||||
<small>Glisser pour positionner<br/>Molette pour zoomer</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-center gap-2">
|
||||
<input type="file"
|
||||
id="photoInput"
|
||||
accept="image/*"
|
||||
style="position: absolute; left: -9999px; opacity: 0;" />
|
||||
<h:inputHidden id="photoCadree" value="#{membreInscriptionBean.photoBase64}" />
|
||||
<label for="photoInput"
|
||||
class="ui-button ui-button-outlined ui-button-secondary"
|
||||
style="cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; min-height: 2.5rem; padding: 0.75rem 1rem;">
|
||||
<i class="pi pi-camera"></i>
|
||||
<span>Choisir une photo</span>
|
||||
</label>
|
||||
<button type="button"
|
||||
id="removePhotoBtn"
|
||||
class="ui-button ui-button-outlined ui-button-danger"
|
||||
onclick="removePhoto()"
|
||||
style="display: none; min-height: 2.5rem; padding: 0.75rem 1rem;">
|
||||
<i class="pi pi-trash"></i>
|
||||
<span>Supprimer</span>
|
||||
</button>
|
||||
</div>
|
||||
<small class="text-600">JPG, PNG ou GIF - Maximum 2MB</small>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Champs d'informations personnelles -->
|
||||
<div class="field">
|
||||
<p:outputLabel for="prenom" value="Prénom" />
|
||||
<p:inputText id="prenom" value="#{membreInscriptionBean.prenom}" required="true"
|
||||
requiredMessage="Le prénom est obligatoire" styleClass="w-full" />
|
||||
<p:message for="prenom" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="nom" value="Nom" />
|
||||
<p:inputText id="nom" value="#{membreInscriptionBean.nom}" required="true"
|
||||
requiredMessage="Le nom est obligatoire" styleClass="w-full" />
|
||||
<p:message for="nom" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="dateNaissance" value="Date de naissance" />
|
||||
<p:calendar id="dateNaissance" value="#{membreInscriptionBean.dateNaissance}" required="true"
|
||||
pattern="dd/MM/yyyy" showIcon="true" yearNavigator="true" yearRange="1920:2030"
|
||||
monthNavigator="true" requiredMessage="La date de naissance est obligatoire"
|
||||
styleClass="w-full" />
|
||||
<p:message for="dateNaissance" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="lieuNaissance" value="Lieu de naissance" />
|
||||
<p:inputText id="lieuNaissance" value="#{membreInscriptionBean.lieuNaissance}" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="sexe" value="Sexe" />
|
||||
<p:selectOneMenu id="sexe" value="#{membreInscriptionBean.sexe}" required="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" noSelectionOption="true" />
|
||||
<f:selectItems value="#{membreInscriptionBean.sexeOptions}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="nationalite" value="Nationalité" />
|
||||
<p:inputText id="nationalite" value="#{membreInscriptionBean.nationalite}" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="situationMatrimoniale" value="Situation matrimoniale" />
|
||||
<p:selectOneMenu id="situationMatrimoniale" value="#{membreInscriptionBean.situationMatrimoniale}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" noSelectionOption="true" />
|
||||
<f:selectItems value="#{membreInscriptionBean.situationMatrimonialeOptions}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="profession" value="Profession" />
|
||||
<p:inputText id="profession" value="#{membreInscriptionBean.profession}" styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="employeur" value="Employeur / Entreprise" />
|
||||
<p:inputText id="employeur" value="#{membreInscriptionBean.employeur}" styleClass="w-full" />
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Contact d'urgence" />
|
||||
<ui:param name="fluid" value="true" />
|
||||
<ui:define name="content">
|
||||
<div class="field">
|
||||
<p:outputLabel for="contactUrgenceNom" value="Nom complet" />
|
||||
<p:inputText id="contactUrgenceNom" value="#{membreInscriptionBean.contactUrgenceNom}"
|
||||
required="true" requiredMessage="Le nom du contact d'urgence est obligatoire"
|
||||
styleClass="w-full" />
|
||||
<p:message for="contactUrgenceNom" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="contactUrgenceTelephone" value="Téléphone" />
|
||||
<p:inputText id="contactUrgenceTelephone" value="#{membreInscriptionBean.contactUrgenceTelephone}"
|
||||
required="true" requiredMessage="Le téléphone du contact d'urgence est obligatoire"
|
||||
styleClass="w-full" />
|
||||
<p:message for="contactUrgenceTelephone" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="contactUrgenceLien" value="Lien de parenté" />
|
||||
<p:selectOneMenu id="contactUrgenceLien" value="#{membreInscriptionBean.contactUrgenceLien}" required="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" noSelectionOption="true" />
|
||||
<f:selectItems value="#{membreInscriptionBean.contactUrgenceLienOptions}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Documents justificatifs" />
|
||||
<ui:define name="content">
|
||||
<p:fileUpload listener="#{membreInscriptionBean.handleFileUpload}"
|
||||
mode="advanced"
|
||||
dragDropSupport="true"
|
||||
multiple="true"
|
||||
update="messages documentsListPanel"
|
||||
sizeLimit="5000000"
|
||||
fileLimit="5"
|
||||
allowTypes="/(\.|\/)(pdf|doc|docx|jpg|jpeg|png)$/"
|
||||
uploadLabel="Télécharger"
|
||||
cancelLabel="Annuler"
|
||||
chooseLabel="Sélectionner les fichiers"
|
||||
invalidFileMessage="Type de fichier non supporté"
|
||||
fileLimitMessage="Nombre maximum de fichiers dépassé"
|
||||
invalidSizeMessage="Taille de fichier trop importante"
|
||||
style="width:100%" />
|
||||
|
||||
<h:panelGroup id="documentsListPanel" layout="block" styleClass="mt-3">
|
||||
<h6 class="mb-2" rendered="#{not empty membreInscriptionBean.documentsJoints}">Fichiers ajoutés:</h6>
|
||||
<ui:repeat value="#{membreInscriptionBean.documentsJoints}" var="document">
|
||||
<div class="flex align-items-center justify-content-between p-2 border-round mb-2"
|
||||
style="background: var(--surface-50);">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-file text-blue-500 mr-2"></i>
|
||||
<span class="text-900">#{document}</span>
|
||||
</div>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.supprimerDocument(document)}" />
|
||||
<ui:param name="update" value="documentsListPanel" />
|
||||
<ui:param name="title" value="Supprimer le fichier" />
|
||||
<ui:param name="severity" value="danger" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</h:panelGroup>
|
||||
|
||||
<small class="text-600">Formats acceptés: PDF, DOC, DOCX, JPG, PNG - Maximum 5 fichiers de 5MB chacun</small>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Coordonnées" />
|
||||
<ui:param name="fluid" value="true" />
|
||||
<ui:define name="content">
|
||||
<div class="field">
|
||||
<p:outputLabel for="adresse" value="Adresse complète" />
|
||||
<p:inputTextarea id="adresse" value="#{membreInscriptionBean.adresse}" rows="4"
|
||||
required="true" requiredMessage="L'adresse est obligatoire"
|
||||
styleClass="w-full" />
|
||||
<p:message for="adresse" />
|
||||
</div>
|
||||
|
||||
<div class="formgrid grid">
|
||||
<div class="field col">
|
||||
<p:outputLabel for="ville" value="Ville" />
|
||||
<p:inputText id="ville" value="#{membreInscriptionBean.ville}" required="true"
|
||||
requiredMessage="La ville est obligatoire" styleClass="w-full" />
|
||||
<p:message for="ville" />
|
||||
</div>
|
||||
<div class="field col">
|
||||
<p:outputLabel for="codePostal" value="Code postal" />
|
||||
<p:inputText id="codePostal" value="#{membreInscriptionBean.codePostal}" styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="pays" value="Pays" />
|
||||
<p:inputText id="pays" value="#{membreInscriptionBean.pays}" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="email" value="Email" />
|
||||
<p:inputText id="email" value="#{membreInscriptionBean.email}" required="true" styleClass="w-full">
|
||||
<f:validateRegex pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
<div class="formgrid grid">
|
||||
<div class="field col">
|
||||
<p:outputLabel for="telephone" value="Téléphone fixe" />
|
||||
<p:inputText id="telephone" value="#{membreInscriptionBean.telephone}" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col">
|
||||
<p:outputLabel for="telephoneMobile" value="Téléphone mobile" />
|
||||
<p:inputText id="telephoneMobile" value="#{membreInscriptionBean.telephoneMobile}"
|
||||
required="true" requiredMessage="Le téléphone mobile est obligatoire"
|
||||
styleClass="w-full" />
|
||||
<p:message for="telephoneMobile" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Adhésion" />
|
||||
<ui:param name="fluid" value="true" />
|
||||
<ui:define name="content">
|
||||
<div class="field">
|
||||
<p:outputLabel for="organisationId" value="Organisation *" styleClass="font-bold text-primary" />
|
||||
<p:selectOneMenu id="organisationId" value="#{membreInscriptionBean.organisationId}" required="true" requiredMessage="Vous devez sélectionner une organisation" styleClass="w-full">
|
||||
<f:selectItem itemLabel="--- Sélectionner une organisation ---" itemValue="" noSelectionOption="true" />
|
||||
<f:selectItems value="#{membreInscriptionBean.organisationsDisponibles}"
|
||||
var="org"
|
||||
itemLabel="#{org.nom} (#{org.ville})"
|
||||
itemValue="#{org.id}" />
|
||||
</p:selectOneMenu>
|
||||
<p:message for="organisationId" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="typeAdhesion" value="Type d'adhésion" />
|
||||
<p:selectOneMenu id="typeAdhesion" value="#{membreInscriptionBean.typeAdhesion}" required="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Sélectionner..." itemValue="" noSelectionOption="true" />
|
||||
<f:selectItems value="#{membreInscriptionBean.typeAdhesionOptions}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="numeroParrain" value="N° Membre parrain" />
|
||||
<div class="ui-inputgroup">
|
||||
<p:inputText id="numeroParrain" value="#{membreInscriptionBean.numeroParrain}" styleClass="w-full" />
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-search" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.rechercherParrain}" />
|
||||
<ui:param name="severity" value="info" />
|
||||
<ui:param name="rounded" value="false" />
|
||||
<ui:param name="text" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="nomParrain" value="Nom du parrain" />
|
||||
<p:inputText id="nomParrain" value="#{membreInscriptionBean.nomParrain}" readonly="true" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="motifAdhesion" value="Motif d'adhésion" />
|
||||
<p:inputTextarea id="motifAdhesion" value="#{membreInscriptionBean.motifAdhesion}"
|
||||
rows="3" styleClass="w-full" />
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<ui:decorate template="/templates/components/forms/form-section.xhtml">
|
||||
<ui:param name="title" value="Informations complémentaires" />
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid formgrid grid">
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:outputLabel for="nomBanque" value="Nom de la banque" />
|
||||
<p:inputText id="nomBanque" value="#{membreInscriptionBean.nomBanque}" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:outputLabel for="numeroBanque" value="Numéro de compte" />
|
||||
<p:inputText id="numeroBanque" value="#{membreInscriptionBean.numeroBanque}" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-4">
|
||||
<p:outputLabel for="ribIban" value="RIB / IBAN" />
|
||||
<p:inputText id="ribIban" value="#{membreInscriptionBean.ribIban}" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="competencesSpeciales" value="Compétences spéciales" />
|
||||
<p:inputTextarea id="competencesSpeciales" value="#{membreInscriptionBean.competencesSpeciales}"
|
||||
rows="3" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12 md:col-6">
|
||||
<p:outputLabel for="centresInteret" value="Centres d'intérêt" />
|
||||
<p:inputTextarea id="centresInteret" value="#{membreInscriptionBean.centresInteret}"
|
||||
rows="3" styleClass="w-full" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<p:outputLabel for="commentaires" value="Commentaires" />
|
||||
<p:inputTextarea id="commentaires" value="#{membreInscriptionBean.commentaires}"
|
||||
rows="3" styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5>Autorisations</h5>
|
||||
<div class="formgroup-inline">
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="accepteReglement" value="#{membreInscriptionBean.accepteReglement}" />
|
||||
<p:outputLabel for="accepteReglement" value="J'accepte le règlement intérieur" />
|
||||
</div>
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="acceptePrelevement" value="#{membreInscriptionBean.acceptePrelevement}" />
|
||||
<p:outputLabel for="acceptePrelevement" value="J'autorise le prélèvement automatique" />
|
||||
</div>
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="autorisationMarketing" value="#{membreInscriptionBean.autorisationMarketing}" />
|
||||
<p:outputLabel for="autorisationMarketing" value="J'accepte de recevoir des communications" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions finales -->
|
||||
<div class="card">
|
||||
<h5>Finaliser l'inscription</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">Assurez-vous que tous les champs requis sont remplis correctement</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="🎯 Inscrire le membre" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.inscrire}" />
|
||||
<ui:param name="update" value="messages" />
|
||||
<ui:param name="onclick" value="PF('statusDialog').show();" />
|
||||
<ui:param name="oncomplete" value="PF('statusDialog').hide();" />
|
||||
<ui:param name="title" value="Soumettre l'inscription" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="💾 Enregistrer brouillon" />
|
||||
<ui:param name="icon" value="pi pi-save" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.enregistrerBrouillon}" />
|
||||
<ui:param name="update" value="messages" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="🔄 Réinitialiser" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="onclick" value="removePhoto(); return confirm('Êtes-vous sûr de vouloir réinitialiser le formulaire ?');" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="❌ Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.annuler}" />
|
||||
<ui:param name="onclick" value="return confirm('Êtes-vous sûr de vouloir annuler l\'inscription ?');" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-600">
|
||||
<small>
|
||||
<i class="pi pi-shield mr-1"></i>
|
||||
Toutes les données sont chiffrées et sécurisées selon les standards RGPD
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
<ui:define name="head">
|
||||
<script type="text/javascript">
|
||||
// Configuration de la previsualisation photo
|
||||
window.addEventListener('load', function() {
|
||||
var photoInput = document.getElementById('photoInput');
|
||||
if (photoInput) {
|
||||
photoInput.addEventListener('change', function(event) {
|
||||
previewPhoto(event.target);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function previewPhoto(input) {
|
||||
if (input.files && input.files.length > 0) {
|
||||
var file = input.files[0];
|
||||
|
||||
// Verifier que c'est une image
|
||||
if (!file.type.startsWith('image/')) {
|
||||
alert('Veuillez selectionner un fichier image');
|
||||
input.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// Verifier la taille (2MB max)
|
||||
if (file.size > 2097152) {
|
||||
alert('La taille du fichier depasse 2MB');
|
||||
input.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
var preview = document.getElementById('photoPreview');
|
||||
var placeholder = document.getElementById('photoPlaceholder');
|
||||
var removeBtn = document.getElementById('removePhotoBtn');
|
||||
|
||||
if (preview && placeholder && removeBtn) {
|
||||
preview.src = e.target.result;
|
||||
preview.style.display = 'block';
|
||||
preview.style.left = '0px';
|
||||
preview.style.top = '0px';
|
||||
placeholder.style.display = 'none';
|
||||
removeBtn.style.display = 'inline-block';
|
||||
|
||||
// Stocker l'image originale pour le recadrage
|
||||
preview.originalSrc = e.target.result;
|
||||
|
||||
// Activer le positionnement interactif
|
||||
enablePhotoPositioning(preview);
|
||||
}
|
||||
};
|
||||
|
||||
reader.onerror = function() {
|
||||
alert('Erreur lors de la lecture du fichier');
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
|
||||
function enablePhotoPositioning(photoElement) {
|
||||
var isDragging = false;
|
||||
var startX, startY, initialLeft, initialTop;
|
||||
var overlay = document.getElementById('photoOverlay');
|
||||
var currentScale = 1;
|
||||
var minScale = 0.5;
|
||||
var maxScale = 3;
|
||||
|
||||
// Fonctionnalité de zoom avec la molette
|
||||
var container = document.getElementById('photoContainer');
|
||||
container.addEventListener('wheel', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var delta = e.deltaY > 0 ? -0.1 : 0.1;
|
||||
var newScale = Math.max(minScale, Math.min(maxScale, currentScale + delta));
|
||||
|
||||
if (newScale !== currentScale) {
|
||||
currentScale = newScale;
|
||||
photoElement.style.transform = 'scale(' + currentScale + ')';
|
||||
|
||||
// Ajuster la position si l'image sort des limites après zoom
|
||||
var currentLeft = parseInt(photoElement.style.left) || 0;
|
||||
var currentTop = parseInt(photoElement.style.top) || 0;
|
||||
|
||||
var containerWidth = container.offsetWidth;
|
||||
var containerHeight = container.offsetHeight;
|
||||
var photoWidth = photoElement.offsetWidth * currentScale;
|
||||
var photoHeight = photoElement.offsetHeight * currentScale;
|
||||
|
||||
var maxLeft = photoWidth > containerWidth ? 0 : (containerWidth - photoWidth) / 2;
|
||||
var minLeft = photoWidth > containerWidth ? -(photoWidth - containerWidth) : (containerWidth - photoWidth) / 2;
|
||||
var maxTop = photoHeight > containerHeight ? 0 : (containerHeight - photoHeight) / 2;
|
||||
var minTop = photoHeight > containerHeight ? -(photoHeight - containerHeight) : (containerHeight - photoHeight) / 2;
|
||||
|
||||
var adjustedLeft = Math.max(minLeft, Math.min(maxLeft, currentLeft));
|
||||
var adjustedTop = Math.max(minTop, Math.min(maxTop, currentTop));
|
||||
|
||||
photoElement.style.left = adjustedLeft + 'px';
|
||||
photoElement.style.top = adjustedTop + 'px';
|
||||
|
||||
// Afficher temporairement l'overlay avec le niveau de zoom
|
||||
if (overlay) {
|
||||
overlay.style.display = 'block';
|
||||
overlay.innerHTML = '<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 0.8rem; text-align: center;"><i class="pi pi-search-plus"></i><br/><small>Zoom: ' + Math.round(currentScale * 100) + '%</small></div>';
|
||||
|
||||
// Masquer l'overlay après 1 seconde
|
||||
setTimeout(function() {
|
||||
if (overlay && !isDragging) {
|
||||
overlay.style.display = 'none';
|
||||
overlay.innerHTML = '<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 0.75rem; text-align: center;"><i class="pi pi-arrows-alt"></i><br/><small>Glisser pour positionner<br/>Molette pour zoomer</small></div>';
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
photoElement.addEventListener('mousedown', function(e) {
|
||||
isDragging = true;
|
||||
startX = e.clientX;
|
||||
startY = e.clientY;
|
||||
initialLeft = parseInt(photoElement.style.left) || 0;
|
||||
initialTop = parseInt(photoElement.style.top) || 0;
|
||||
|
||||
if (overlay) overlay.style.display = 'block';
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', function(e) {
|
||||
if (!isDragging) return;
|
||||
|
||||
var deltaX = e.clientX - startX;
|
||||
var deltaY = e.clientY - startY;
|
||||
|
||||
var newLeft = initialLeft + deltaX;
|
||||
var newTop = initialTop + deltaY;
|
||||
|
||||
// Limiter le déplacement en tenant compte du zoom
|
||||
var container = document.getElementById('photoContainer');
|
||||
var containerWidth = container.offsetWidth;
|
||||
var containerHeight = container.offsetHeight;
|
||||
var photoWidth = photoElement.offsetWidth * currentScale;
|
||||
var photoHeight = photoElement.offsetHeight * currentScale;
|
||||
|
||||
// Calculer les limites en fonction du zoom
|
||||
var maxLeft = photoWidth > containerWidth ? 0 : (containerWidth - photoWidth) / 2;
|
||||
var minLeft = photoWidth > containerWidth ? -(photoWidth - containerWidth) : (containerWidth - photoWidth) / 2;
|
||||
var maxTop = photoHeight > containerHeight ? 0 : (containerHeight - photoHeight) / 2;
|
||||
var minTop = photoHeight > containerHeight ? -(photoHeight - containerHeight) : (containerHeight - photoHeight) / 2;
|
||||
|
||||
newLeft = Math.max(minLeft, Math.min(maxLeft, newLeft));
|
||||
newTop = Math.max(minTop, Math.min(maxTop, newTop));
|
||||
|
||||
photoElement.style.left = newLeft + 'px';
|
||||
photoElement.style.top = newTop + 'px';
|
||||
});
|
||||
|
||||
document.addEventListener('mouseup', function() {
|
||||
isDragging = false;
|
||||
if (overlay) overlay.style.display = 'none';
|
||||
});
|
||||
|
||||
// Support tactile pour mobile
|
||||
photoElement.addEventListener('touchstart', function(e) {
|
||||
var touch = e.touches[0];
|
||||
isDragging = true;
|
||||
startX = touch.clientX;
|
||||
startY = touch.clientY;
|
||||
initialLeft = parseInt(photoElement.style.left) || 0;
|
||||
initialTop = parseInt(photoElement.style.top) || 0;
|
||||
|
||||
if (overlay) overlay.style.display = 'block';
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
document.addEventListener('touchmove', function(e) {
|
||||
if (!isDragging) return;
|
||||
|
||||
var touch = e.touches[0];
|
||||
var deltaX = touch.clientX - startX;
|
||||
var deltaY = touch.clientY - startY;
|
||||
|
||||
var newLeft = initialLeft + deltaX;
|
||||
var newTop = initialTop + deltaY;
|
||||
|
||||
// Limiter le déplacement en tenant compte du zoom pour mobile
|
||||
var container = document.getElementById('photoContainer');
|
||||
var containerWidth = container.offsetWidth;
|
||||
var containerHeight = container.offsetHeight;
|
||||
var photoWidth = photoElement.offsetWidth * currentScale;
|
||||
var photoHeight = photoElement.offsetHeight * currentScale;
|
||||
|
||||
// Calculer les limites en fonction du zoom
|
||||
var maxLeft = photoWidth > containerWidth ? 0 : (containerWidth - photoWidth) / 2;
|
||||
var minLeft = photoWidth > containerWidth ? -(photoWidth - containerWidth) : (containerWidth - photoWidth) / 2;
|
||||
var maxTop = photoHeight > containerHeight ? 0 : (containerHeight - photoHeight) / 2;
|
||||
var minTop = photoHeight > containerHeight ? -(photoHeight - containerHeight) : (containerHeight - photoHeight) / 2;
|
||||
|
||||
newLeft = Math.max(minLeft, Math.min(maxLeft, newLeft));
|
||||
newTop = Math.max(minTop, Math.min(maxTop, newTop));
|
||||
|
||||
photoElement.style.left = newLeft + 'px';
|
||||
photoElement.style.top = newTop + 'px';
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
document.addEventListener('touchend', function() {
|
||||
isDragging = false;
|
||||
if (overlay) overlay.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
function capturePhoto() {
|
||||
var preview = document.getElementById('photoPreview');
|
||||
var container = document.getElementById('photoContainer');
|
||||
|
||||
if (!preview || !preview.originalSrc || preview.style.display === 'none') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
// Taille du cercle de sortie (120px)
|
||||
var outputSize = 120;
|
||||
canvas.width = outputSize;
|
||||
canvas.height = outputSize;
|
||||
|
||||
// Obtenir les paramètres actuels
|
||||
var currentScale = parseFloat(preview.style.transform.replace(/[^\d.]/g, '')) || 1;
|
||||
var currentLeft = parseInt(preview.style.left) || 0;
|
||||
var currentTop = parseInt(preview.style.top) || 0;
|
||||
|
||||
// Calculer les dimensions de l'image affichée
|
||||
var displayWidth = preview.offsetWidth;
|
||||
var displayHeight = preview.offsetHeight;
|
||||
|
||||
// Calculer le ratio entre l'image originale et l'affichage
|
||||
var ratioX = img.width / displayWidth;
|
||||
var ratioY = img.height / displayHeight;
|
||||
|
||||
// Calculer la zone source dans l'image originale
|
||||
var sourceX = Math.abs(currentLeft) * ratioX;
|
||||
var sourceY = Math.abs(currentTop) * ratioY;
|
||||
var sourceWidth = (outputSize / currentScale) * ratioX;
|
||||
var sourceHeight = (outputSize / currentScale) * ratioY;
|
||||
|
||||
// S'assurer que la zone source reste dans les limites de l'image
|
||||
sourceX = Math.max(0, Math.min(img.width - sourceWidth, sourceX));
|
||||
sourceY = Math.max(0, Math.min(img.height - sourceHeight, sourceY));
|
||||
sourceWidth = Math.min(sourceWidth, img.width - sourceX);
|
||||
sourceHeight = Math.min(sourceHeight, img.height - sourceY);
|
||||
|
||||
// Créer un masque circulaire
|
||||
ctx.beginPath();
|
||||
ctx.arc(outputSize/2, outputSize/2, outputSize/2, 0, 2 * Math.PI);
|
||||
ctx.clip();
|
||||
|
||||
// Dessiner la portion cadrée de l'image
|
||||
ctx.drawImage(img, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, outputSize, outputSize);
|
||||
|
||||
// Convertir en blob
|
||||
canvas.toBlob(function(blob) {
|
||||
resolve(blob);
|
||||
}, 'image/jpeg', 0.9);
|
||||
};
|
||||
img.src = preview.originalSrc;
|
||||
});
|
||||
}
|
||||
|
||||
function removePhoto() {
|
||||
var photoInput = document.getElementById('photoInput');
|
||||
var preview = document.getElementById('photoPreview');
|
||||
var placeholder = document.getElementById('photoPlaceholder');
|
||||
var removeBtn = document.getElementById('removePhotoBtn');
|
||||
|
||||
if (photoInput) photoInput.value = '';
|
||||
if (preview) {
|
||||
preview.style.display = 'none';
|
||||
preview.style.transform = 'scale(1)';
|
||||
preview.style.left = '0px';
|
||||
preview.style.top = '0px';
|
||||
preview.originalSrc = null;
|
||||
}
|
||||
if (placeholder) placeholder.style.display = 'flex';
|
||||
if (removeBtn) removeBtn.style.display = 'none';
|
||||
}
|
||||
|
||||
function preparePhotoForSubmission(button) {
|
||||
var preview = document.getElementById('photoPreview');
|
||||
if (preview && preview.style.display !== 'none') {
|
||||
// Empêcher la soumission immédiate
|
||||
button.disabled = true;
|
||||
button.innerHTML = '<i class="pi pi-spin pi-spinner"></i> <span>Traitement...</span>';
|
||||
|
||||
capturePhoto().then(function(blob) {
|
||||
if (blob) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
var base64Data = e.target.result.split(',')[1];
|
||||
var hiddenInput = document.getElementById('photoCadree');
|
||||
if (hiddenInput) {
|
||||
hiddenInput.value = base64Data;
|
||||
}
|
||||
|
||||
// Maintenant soumettre le formulaire
|
||||
button.click();
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
} else {
|
||||
// Pas de photo, soumettre directement
|
||||
button.click();
|
||||
}
|
||||
});
|
||||
return false; // Empêcher la soumission immédiate
|
||||
}
|
||||
return true; // Permettre la soumission si pas de photo
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Dialogue de chargement -->
|
||||
<p:dialog id="statusDialog" widgetVar="statusDialog" modal="true" closable="false"
|
||||
showHeader="false" styleClass="no-border" resizable="false">
|
||||
<div class="flex flex-column align-items-center p-4">
|
||||
<i class="pi pi-spin pi-spinner text-4xl text-primary mb-3"></i>
|
||||
<div class="text-xl font-medium text-900">Traitement en cours...</div>
|
||||
<div class="text-600">Veuillez patienter pendant l'enregistrement</div>
|
||||
</div>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,657 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:uf="http://xmlns.jcp.org/jsf/composite/components"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:param name="page" value="#{membreListeBean}"/>
|
||||
<ui:define name="title">Liste des Membres - 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-users text-blue-500" />
|
||||
<ui:param name="title" value="Liste des Membres" />
|
||||
<ui:param name="description" value="Gestion et suivi des membres de l'association" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsMembres">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouveau membre" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="outcome" value="/pages/secure/membre/inscription" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Import/Export" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="onclick" value="PF('dlgImportExport').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
|
||||
<!-- Liste des membres -->
|
||||
<div class="card">
|
||||
<h:form id="formMembres">
|
||||
<h5>Tous les Membres</h5>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar avec composants réutilisables) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<!-- Recherche globale (DRY/WOU: form-field-search-text avec icône) -->
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchFilter" value="Rechercher" />
|
||||
<span class="p-input-icon-left w-full">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="searchFilter"
|
||||
placeholder="Nom, prénom, email..."
|
||||
value="#{membreListeBean.searchFilter}"
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" update="dtMembres" delay="500"/>
|
||||
</p:inputText>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statut (DRY/WOU: form-field-select avec AJAX) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="statutFilter" />
|
||||
<ui:param name="label" value="Statut" />
|
||||
<ui:param name="value" value="#{membreListeBean.statutFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous les statuts" itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Inactif" itemValue="INACTIF" />
|
||||
<f:selectItem itemLabel="Suspendu" itemValue="SUSPENDU" />
|
||||
<f:selectItem itemLabel="Radié" itemValue="RADIE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax event="change" update="dtMembres" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Type (DRY/WOU: form-field-select avec AJAX) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="typeFilter" />
|
||||
<ui:param name="label" value="Type" />
|
||||
<ui:param name="value" value="#{membreListeBean.typeFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Associé" itemValue="ASSOCIE" />
|
||||
<f:selectItem itemLabel="Bienfaiteur" itemValue="BIENFAITEUR" />
|
||||
<f:selectItem itemLabel="Honoraire" itemValue="HONORAIRE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax event="change" update="dtMembres" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Cotisation (DRY/WOU: form-field-select avec AJAX) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="cotisationFilter" />
|
||||
<ui:param name="label" value="Cotisation" />
|
||||
<ui:param name="value" value="#{membreListeBean.cotisationFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Toutes cotisations" itemValue="" />
|
||||
<f:selectItem itemLabel="À jour" itemValue="A_JOUR" />
|
||||
<f:selectItem itemLabel="En retard" itemValue="EN_RETARD" />
|
||||
<f:selectItem itemLabel="Jamais payé" itemValue="JAMAIS_PAYE" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax event="change" update="dtMembres" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Entité/Organisation (DRY/WOU: form-field-select avec AJAX) -->
|
||||
<div class="col-12 md:col-2">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="entiteFilter" />
|
||||
<ui:param name="label" value="Entité" />
|
||||
<ui:param name="value" value="#{membreListeBean.entiteFilter}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Toutes entités" itemValue="" />
|
||||
<f:selectItems value="#{membreListeBean.entitesDisponibles}"
|
||||
var="entite"
|
||||
itemLabel="#{entite.nom}"
|
||||
itemValue="#{entite.id}" />
|
||||
</ui:define>
|
||||
<ui:define name="ajax">
|
||||
<p:ajax event="change" update="dtMembres" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<!-- Filtres avancés (DRY/WOU: button-secondary) -->
|
||||
<div class="col-12 md:col-auto">
|
||||
<div class="field">
|
||||
<label class="invisible">Filtres avancés</label>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Filtres avancés" />
|
||||
<ui:param name="icon" value="pi pi-filter" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').show();" />
|
||||
<ui:param name="styleClass" value="w-full" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actualiser (DRY/WOU: button-secondary avec icône seule) -->
|
||||
<div class="col-12 md:col-auto">
|
||||
<div class="field">
|
||||
<label class="invisible">Actualiser</label>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{membreListeBean.actualiser}" />
|
||||
<ui:param name="update" value=":formMembres:dtMembres" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Réinitialiser (DRY/WOU: button-secondary) -->
|
||||
<div class="col-12 md:col-auto">
|
||||
<div class="field">
|
||||
<label class="invisible">Réinitialiser</label>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Réinitialiser" />
|
||||
<ui:param name="icon" value="pi pi-filter-slash" />
|
||||
<ui:param name="action" value="#{membreListeBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value="dtMembres searchFilter statutFilter typeFilter cotisationFilter entiteFilter" />
|
||||
<ui:param name="styleClass" value="w-full" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dtMembres"
|
||||
var="membre"
|
||||
value="#{membreListeBean.membres}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="10,15,25,50"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{membreListeBean.selectedMembres}"
|
||||
rowKey="#{membre.id}"
|
||||
selectionMode="multiple"
|
||||
styleClass="mt-3">
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="N° Membre" sortBy="#{membre.numeroMembre}" style="width:120px">
|
||||
<h:outputText value="#{membre.numeroMembre}" styleClass="font-mono font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{membre.nom}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle overflow-hidden mr-3"
|
||||
style="width: 40px; height: 40px;">
|
||||
<h:graphicImage value="#{membre.photoUrl}"
|
||||
style="width: 100%; height: 100%; object-fit: cover;"
|
||||
rendered="#{membre.photoUrl != null}" />
|
||||
<div class="bg-primary text-white flex align-items-center justify-content-center w-full h-full"
|
||||
rendered="#{membre.photoUrl == null}">
|
||||
<span style="font-size: 0.9rem;">#{membre.initiales}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-900">#{membre.nomComplet}</div>
|
||||
<div class="text-600 text-sm">
|
||||
<span>#{membre.telephone}</span>
|
||||
<span class="mx-2">•</span>
|
||||
<span>#{membre.email}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{membre.typeMembre}" style="width:120px">
|
||||
<p:tag value="#{membre.typeMembre}"
|
||||
severity="#{membre.typeSeverity != null ? membre.typeSeverity : 'info'}"
|
||||
icon="pi #{membre.typeIcon != null ? membre.typeIcon : 'pi-user'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{membre.statut}" style="width:100px">
|
||||
<p:tag value="#{membre.statut}"
|
||||
severity="#{membre.statutSeverity}"
|
||||
icon="pi #{membre.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Organisation" sortBy="#{membre.associationNom}" style="width:150px">
|
||||
<h:outputText value="#{membre.associationNom != null ? membre.associationNom : 'Non renseigné'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Adhésion" sortBy="#{membre.dateAdhesion}" style="width:120px">
|
||||
<div>
|
||||
<div class="font-medium">#{membre.dateAdhesion != null ? membre.dateAdhesion : 'Non renseigné'}</div>
|
||||
<small class="text-600">#{membre.anciennete}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Cotisations" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold #{membre.cotisationColor}">#{membre.cotisationStatut}</div>
|
||||
<small class="text-600">#{membre.dernierPaiement}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Participation" style="width:100px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-blue-500">#{membre.tauxParticipation}%</div>
|
||||
<small class="text-600">#{membre.evenementsAnnee} événements</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<!-- DRY/WOU: Composite Component action-button-view -->
|
||||
<uf:action-button-view itemId="#{membre.id}"
|
||||
detailPage="/pages/secure/membre/profil.xhtml"
|
||||
iconOnly="true"/>
|
||||
<!-- DRY/WOU: Composite Component action-button-edit-nav -->
|
||||
<uf:action-button-edit-nav itemId="#{membre.id}"
|
||||
editPage="/pages/secure/membre/modifier.xhtml"
|
||||
iconOnly="true"/>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-dollar" />
|
||||
<ui:param name="action" value="#{membreListeBean.gererCotisations(membre)}" />
|
||||
<ui:param name="title" value="Cotisations" />
|
||||
<ui:param name="severity" value="success" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="action" value="#{membreListeBean.contacterMembre(membre)}" />
|
||||
<ui:param name="update" value=":formMembres :formContact" />
|
||||
<ui:param name="oncomplete" value="PF('dlgContact').show();" />
|
||||
<ui:param name="title" value="Contacter" />
|
||||
<ui:param name="severity" value="" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-ban" />
|
||||
<ui:param name="action" value="#{membreListeBean.suspendreMembre(membre)}" />
|
||||
<ui:param name="onclick" value="return confirm('Êtes-vous sûr de vouloir suspendre ce membre ?');" />
|
||||
<ui:param name="title" value="Suspendre" />
|
||||
<ui:param name="severity" value="danger" />
|
||||
<ui:param name="rendered" value="#{membre.statut == 'ACTIF'}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreListeBean.reactiverMembre(membre)}" />
|
||||
<ui:param name="title" value="Réactiver" />
|
||||
<ui:param name="severity" value="success" />
|
||||
<ui:param name="rendered" value="#{membre.statut == 'SUSPENDU'}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Actions groupées -->
|
||||
<div class="mt-3 flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<span class="text-600">#{membreListeBean.selectedMembres.size()} membre(s) sélectionné(s)</span>
|
||||
<span class="text-400 ml-2" rendered="#{empty membreListeBean.selectedMembres}">
|
||||
- Cochez des cases pour activer les actions
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Envoyer message" />
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="onclick" value="PF('dlgMessageGroupe').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Rappel cotisations" />
|
||||
<ui:param name="icon" value="pi pi-bell" />
|
||||
<ui:param name="action" value="#{membreListeBean.rappelCotisationsGroupe}" />
|
||||
<ui:param name="update" value=":formMembres" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Exporter sélection" />
|
||||
<ui:param name="icon" value="pi pi-file-excel" />
|
||||
<ui:param name="action" value="#{membreListeBean.exporterSelection}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Modifier en lot" />
|
||||
<ui:param name="icon" value="pi pi-pencil" />
|
||||
<ui:param name="onclick" value="PF('dlgModificationLot').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Filtres Avancés -->
|
||||
<p:dialog header="Filtres Avancés" widgetVar="dlgFiltresAvances" modal="true" width="600">
|
||||
<h:form id="formFiltresAvances">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="ageMin" value="Âge minimum" />
|
||||
<p:inputNumber id="ageMin" value="#{membreListeBean.ageMin}" symbol="" styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="ageMax" value="Âge maximum" />
|
||||
<p:inputNumber id="ageMax" value="#{membreListeBean.ageMax}" symbol="" styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="genre" value="Genre" />
|
||||
<p:selectOneMenu id="genre" value="#{membreListeBean.genreFilter}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tous" itemValue="" />
|
||||
<f:selectItem itemLabel="Homme" itemValue="M" />
|
||||
<f:selectItem itemLabel="Femme" itemValue="F" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="ville" value="Ville" />
|
||||
<p:autoComplete id="ville"
|
||||
value="#{membreListeBean.villeFilter}"
|
||||
completeMethod="#{membreListeBean.completerVilles}"
|
||||
placeholder="Saisir une ville..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateAdhesionDebut" />
|
||||
<ui:param name="label" value="Adhésion après le" />
|
||||
<ui:param name="value" value="#{membreListeBean.dateAdhesionDebut}" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateAdhesionFin" />
|
||||
<ui:param name="label" value="Adhésion avant le" />
|
||||
<ui:param name="value" value="#{membreListeBean.dateAdhesionFin}" />
|
||||
</ui:include>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="profession" value="Profession" />
|
||||
<p:autoComplete id="profession"
|
||||
value="#{membreListeBean.professionFilter}"
|
||||
completeMethod="#{membreListeBean.completerProfessions}"
|
||||
placeholder="Saisir une profession..."
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="desEnfants" value="#{membreListeBean.desEnfants}" />
|
||||
<p:outputLabel for="desEnfants" value=" A des enfants déclarés" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Appliquer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreListeBean.appliquerFiltresAvances}" />
|
||||
<ui:param name="update" value=":formMembres:dtMembres" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Réinitialiser" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{membreListeBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value=":formFiltresAvances :formMembres:dtMembres" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-danger" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Message Groupé -->
|
||||
<p:dialog header="Envoyer un Message Groupé" widgetVar="dlgMessageGroupe" modal="true" width="600">
|
||||
<h:form id="formMessageGroupe">
|
||||
<div class="ui-fluid">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="sujetMessage" />
|
||||
<ui:param name="label" value="Sujet" />
|
||||
<ui:param name="value" value="#{membreListeBean.sujetMessage}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="placeholder" value="Objet du message" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="contenuMessage" />
|
||||
<ui:param name="label" value="Message" />
|
||||
<ui:param name="value" value="#{membreListeBean.contenuMessage}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="6" />
|
||||
</ui:include>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="canauxMessage" value="Canaux de diffusion" />
|
||||
<p:selectCheckboxMenu id="canauxMessage" value="#{membreListeBean.canauxMessage}"
|
||||
multiple="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="📧 Email" itemValue="EMAIL" />
|
||||
<f:selectItem itemLabel="📱 SMS" itemValue="SMS" />
|
||||
<f:selectItem itemLabel="💬 WhatsApp" itemValue="WHATSAPP" />
|
||||
<f:selectItem itemLabel="🔔 Notification push" itemValue="PUSH" />
|
||||
</p:selectCheckboxMenu>
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Destinataires :</div>
|
||||
<div class="text-600">#{membreListeBean.selectedMembres.size()} membre(s) recevront ce message</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Envoyer" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{membreListeBean.envoyerMessageGroupe}" />
|
||||
<ui:param name="update" value=":formMessageGroupe :formMembres" />
|
||||
<ui:param name="onclick" value="if(!args.validationFailed) PF('dlgMessageGroupe').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgMessageGroupe').hide();" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Import/Export -->
|
||||
<p:dialog header="Import/Export des Membres" widgetVar="dlgImportExport" modal="true" width="500">
|
||||
<h:form id="formImportExport">
|
||||
<p:tabView>
|
||||
<p:tab title="Import">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="fichierImport" value="Fichier Excel" />
|
||||
<p:fileUpload id="fichierImport" mode="simple" skinSimple="true"
|
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="mettreAJourExistants" value="#{membreListeBean.mettreAJourExistants}" />
|
||||
<p:outputLabel for="mettreAJourExistants" value=" Mettre à jour les membres existants" />
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Format attendu :</div>
|
||||
<small class="text-600">
|
||||
Colonnes : Nom, Prénom, Email, Téléphone, Date naissance, Adresse, Profession, Type membre
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Importer" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="action" value="#{membreListeBean.importerMembres}" />
|
||||
<ui:param name="update" value=":formImportExport :formMembres" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Télécharger modèle" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreListeBean.telechargerModele}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<p:tab title="Export">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="formatExport" value="Format" />
|
||||
<p:selectOneMenu id="formatExport" value="#{membreListeBean.formatExport}">
|
||||
<f:selectItem itemLabel="Excel (.xlsx)" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="CSV (.csv)" itemValue="CSV" />
|
||||
<f:selectItem itemLabel="PDF (.pdf)" itemValue="PDF" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="colonnesExport" value="Colonnes à exporter" />
|
||||
<p:selectCheckboxMenu id="colonnesExport" value="#{membreListeBean.colonnesExport}"
|
||||
multiple="true">
|
||||
<f:selectItem itemLabel="Informations personnelles" itemValue="PERSO" />
|
||||
<f:selectItem itemLabel="Coordonnées" itemValue="CONTACT" />
|
||||
<f:selectItem itemLabel="Informations adhésion" itemValue="ADHESION" />
|
||||
<f:selectItem itemLabel="Cotisations" itemValue="COTISATIONS" />
|
||||
<f:selectItem itemLabel="Participation événements" itemValue="EVENEMENTS" />
|
||||
</p:selectCheckboxMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="exporterSelection" value="#{membreListeBean.exporterSelection}" />
|
||||
<p:outputLabel for="exporterSelection" value=" Exporter seulement la sélection" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Exporter" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreListeBean.exporterMembres}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
|
||||
<div class="flex justify-content-end mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Fermer" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgImportExport').hide();" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Contact Membre -->
|
||||
<h:form id="formContact">
|
||||
<p:dialog id="dlgContact"
|
||||
header="Contacter #{membreListeBean.membreAContacter != null ? membreListeBean.membreAContacter.nomComplet : 'Membre'}"
|
||||
widgetVar="dlgContact"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 600px;"
|
||||
visible="#{membreListeBean.dialogContactVisible}">
|
||||
<div class="ui-fluid" rendered="#{membreListeBean.membreAContacter != null}">
|
||||
<div class="field mb-4">
|
||||
<div class="surface-100 border-round p-3">
|
||||
<div class="flex align-items-center">
|
||||
<div class="w-3rem h-3rem border-circle bg-primary-100 flex align-items-center justify-content-center mr-3">
|
||||
<i class="pi pi-user text-primary text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-semibold text-900">#{membreListeBean.membreAContacter.nomComplet}</div>
|
||||
<div class="text-600 text-sm">#{membreListeBean.membreAContacter.email != null ? membreListeBean.membreAContacter.email : 'Email non renseigné'}</div>
|
||||
<div class="text-600 text-sm">#{membreListeBean.membreAContacter.telephone != null ? membreListeBean.membreAContacter.telephone : 'Téléphone non renseigné'}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="sujetContact" />
|
||||
<ui:param name="label" value="Sujet" />
|
||||
<ui:param name="value" value="#{membreListeBean.sujetContact}" />
|
||||
<ui:param name="placeholder" value="Sujet du message (optionnel)" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="messageContact" />
|
||||
<ui:param name="label" value="Message *" />
|
||||
<ui:param name="value" value="#{membreListeBean.messageContact}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="6" />
|
||||
<ui:param name="placeholder" value="Saisissez votre message..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex justify-content-end gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="action" value="#{membreListeBean.annulerContact}" />
|
||||
<ui:param name="update" value=":formContact" />
|
||||
<ui:param name="oncomplete" value="PF('dlgContact').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Envoyer" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{membreListeBean.envoyerMessageContact}" />
|
||||
<ui:param name="update" value=":formContact :formMembres" />
|
||||
<ui:param name="oncomplete" value="if(!args.validationFailed) { PF('dlgContact').hide(); }" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,660 @@
|
||||
<!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">Profil de #{membreProfilBean.membre.nomComplet} - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête avec photo et informations principales -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="flex align-items-start justify-content-between">
|
||||
<div class="flex align-items-start">
|
||||
<!-- Photo de profil -->
|
||||
<div class="mr-4">
|
||||
<ui:include src="/templates/components/profile-photo.xhtml">
|
||||
<ui:param name="photoId" value="photoProfil" />
|
||||
<ui:param name="photoUrl" value="#{membreProfilBean.membre.photoUrl}" />
|
||||
<ui:param name="initiales" value="#{membreProfilBean.membre.initiales}" />
|
||||
<ui:param name="formId" value="formPhoto" />
|
||||
<ui:param name="listener" value="#{membreProfilBean.changerPhoto}" />
|
||||
<ui:param name="update" value=":photoProfil" />
|
||||
<ui:param name="size" value="120" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Informations principales -->
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center mb-3">
|
||||
<h2 class="m-0 mr-3">#{membreProfilBean.membre.nomComplet}</h2>
|
||||
<p:tag value="#{membreProfilBean.membre.statut}"
|
||||
severity="#{membreProfilBean.membre.statutSeverity}"
|
||||
icon="pi #{membreProfilBean.membre.statutIcon}" />
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Numéro membre" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.numeroMembre}" />
|
||||
<ui:param name="valueClass" value="font-bold text-primary" />
|
||||
</ui:include>
|
||||
<div class="mb-2">
|
||||
<span class="font-medium text-900">Type:</span>
|
||||
<p:tag value="#{membreProfilBean.membre.typeMembre}"
|
||||
severity="#{membreProfilBean.membre.typeSeverity}"
|
||||
icon="pi #{membreProfilBean.membre.typeIcon}"
|
||||
styleClass="ml-2" />
|
||||
</div>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Entité" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.entite}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Adhésion" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.dateAdhesion}" />
|
||||
<ui:param name="suffix" value="(#{membreProfilBean.membre.anciennete})" />
|
||||
</ui:include>
|
||||
<div class="mb-2">
|
||||
<span class="font-medium text-900">Cotisations:</span>
|
||||
<span class="ml-2 #{membreProfilBean.membre.cotisationColor}">#{membreProfilBean.membre.cotisationStatut}</span>
|
||||
</div>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Participation" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.tauxParticipation}%" />
|
||||
<ui:param name="valueClass" value="font-bold text-blue-500" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions principales -->
|
||||
<h:form id="formActionsPrincipales">
|
||||
<div class="flex flex-column gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Modifier" />
|
||||
<ui:param name="icon" value="pi pi-pencil" />
|
||||
<ui:param name="onclick" value="PF('dlgModifierProfil').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Cotisations" />
|
||||
<ui:param name="icon" value="pi pi-dollar" />
|
||||
<ui:param name="action" value="#{membreProfilBean.gererCotisations}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Contacter" />
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="onclick" value="PF('dlgContacter').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Actions" />
|
||||
<ui:param name="icon" value="pi pi-cog" />
|
||||
<ui:param name="onclick" value="PF('dlgActions').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques et KPIs -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Événements" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.evenementsParticipes}" />
|
||||
<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-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Cotisations" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.cotisationsPayees}" />
|
||||
<ui:param name="icon" value="pi-dollar" />
|
||||
<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-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Aides reçues" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.aidesRecues}" />
|
||||
<ui:param name="icon" value="pi-heart" />
|
||||
<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-3" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Score engagement" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.scoreEngagement}" />
|
||||
<ui:param name="icon" value="pi-star" />
|
||||
<ui:param name="iconColor" value="purple-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
<ui:param name="colSize" value="col-12 md:col-3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Contenu principal avec onglets -->
|
||||
<div class="card">
|
||||
<p:tabView>
|
||||
<!-- Onglet Informations personnelles -->
|
||||
<p:tab title="👤 Informations personnelles">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-3">Informations de base</h6>
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Nom complet" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.nomComplet}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Date de naissance" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.dateNaissance}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Genre" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.genre}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Situation familiale" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.situationFamiliale}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Profession" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.profession}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-3">Coordonnées</h6>
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Email" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.email}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Téléphone" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.telephone}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Adresse" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.adresse}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Ville" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.ville}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Pays" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membre.pays}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<h6 class="mb-3">Famille</h6>
|
||||
<p:dataTable value="#{membreProfilBean.membre.famille}" var="membre_famille"
|
||||
styleClass="p-datatable-sm" emptyMessage="Aucun membre de famille déclaré">
|
||||
<p:column headerText="Nom complet">
|
||||
<h:outputText value="#{membre_famille.nomComplet}" />
|
||||
</p:column>
|
||||
<p:column headerText="Relation">
|
||||
<p:tag value="#{membre_famille.relation}" severity="info" />
|
||||
</p:column>
|
||||
<p:column headerText="Date de naissance">
|
||||
<h:outputText value="#{membre_famille.dateNaissance}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Bénéficiaire">
|
||||
<p:tag value="#{membre_famille.beneficiaire ? 'Oui' : 'Non'}"
|
||||
severity="#{membre_famille.beneficiaire ? 'success' : 'secondary'}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Cotisations -->
|
||||
<p:tab title="💰 Cotisations">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-3">État des cotisations</h6>
|
||||
<div class="surface-50 p-3 border-round mb-3">
|
||||
<div class="flex justify-content-between align-items-center mb-2">
|
||||
<span class="font-medium">Statut actuel:</span>
|
||||
<p:tag value="#{membreProfilBean.cotisations.statutActuel}"
|
||||
severity="#{membreProfilBean.cotisations.statutSeverity}" />
|
||||
</div>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Dernier paiement" />
|
||||
<ui:param name="value" value="#{membreProfilBean.cotisations.dernierPaiement}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Prochaine échéance" />
|
||||
<ui:param name="value" value="#{membreProfilBean.cotisations.prochaineEcheance}" />
|
||||
<ui:param name="valueClass" value="#{membreProfilBean.cotisations.prochaineEcheanceClass}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Total payé cette année" />
|
||||
<ui:param name="value" value="#{membreProfilBean.cotisations.totalAnnee}" />
|
||||
<ui:param name="valueClass" value="font-bold text-green-500" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<h:form id="formCotisationsActions">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouveau paiement" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="onclick" value="PF('dlgNouveauPaiement').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Envoyer rappel" />
|
||||
<ui:param name="icon" value="pi pi-bell" />
|
||||
<ui:param name="action" value="#{membreProfilBean.envoyerRappelCotisation}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-3">Historique des paiements</h6>
|
||||
<p:dataTable value="#{membreProfilBean.cotisations.historique}" var="paiement"
|
||||
rows="5" paginator="true" styleClass="p-datatable-sm">
|
||||
<p:column headerText="Date">
|
||||
<h:outputText value="#{paiement.date}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Montant">
|
||||
<h:outputText value="#{paiement.montant}" styleClass="font-bold">
|
||||
<f:convertNumber type="currency" currencySymbol="FCFA " />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Mode">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi #{paiement.modeIcon} mr-2"></i>
|
||||
<span>#{paiement.modePaiement}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="#{paiement.statut}" severity="#{paiement.statutSeverity}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Participation -->
|
||||
<p:tab title="📅 Participation">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-8">
|
||||
<h6 class="mb-3">Événements récents</h6>
|
||||
<ui:repeat value="#{membreProfilBean.evenements.recents}" var="evenement">
|
||||
<div class="flex align-items-center p-3 mb-2 border-round surface-50">
|
||||
<div class="border-round p-2 mr-3 bg-#{evenement.typeEvenementSeverity}">
|
||||
<i class="pi #{evenement.typeEvenementIcon} text-white"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="font-medium text-900">#{evenement.titre}</div>
|
||||
<div class="text-600 text-sm">
|
||||
#{evenement.date} • #{evenement.lieu}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p:tag value="#{evenement.participation}"
|
||||
severity="#{evenement.participationSeverity}" />
|
||||
<div class="text-sm text-600 mt-1">
|
||||
#{evenement.role}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<h6 class="mb-3">Statistiques participation</h6>
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Taux de participation" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.tauxParticipation}%" />
|
||||
<ui:param name="valueClass" value="font-bold text-blue-500" />
|
||||
</ui:include>
|
||||
<p:progressBar value="#{membreProfilBean.statistiques.tauxParticipation}"
|
||||
labelTemplate="" styleClass="mb-3" />
|
||||
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Cette année" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.evenementsAnnee}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Total" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.evenementsTotal}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="En tant qu'organisateur" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.evenementsOrganises}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field-row.xhtml">
|
||||
<ui:param name="label" value="Absences" />
|
||||
<ui:param name="value" value="#{membreProfilBean.statistiques.absences}" />
|
||||
<ui:param name="valueClass" value="text-red-500" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Aides et Services -->
|
||||
<p:tab title="🤝 Aides et Services">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-3">Aides reçues</h6>
|
||||
<p:dataTable value="#{membreProfilBean.aides.recues}" var="aide"
|
||||
styleClass="p-datatable-sm" emptyMessage="Aucune aide reçue">
|
||||
<p:column headerText="Type">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi #{aide.typeIcon} mr-2 #{aide.typeColor}"></i>
|
||||
<span>#{aide.type}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Montant">
|
||||
<h:outputText value="#{aide.montant}" styleClass="font-bold">
|
||||
<f:convertNumber type="currency" currencySymbol="FCFA " />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Date">
|
||||
<h:outputText value="#{aide.date}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="#{aide.statut}" severity="#{aide.statutSeverity}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h6 class="mb-3">Demandes en cours</h6>
|
||||
<p:dataTable value="#{membreProfilBean.demandes.enCours}" var="demande"
|
||||
styleClass="p-datatable-sm" emptyMessage="Aucune demande en cours">
|
||||
<p:column headerText="Type">
|
||||
<h:outputText value="#{demande.type}" />
|
||||
</p:column>
|
||||
<p:column headerText="Objet">
|
||||
<h:outputText value="#{demande.objet}" />
|
||||
</p:column>
|
||||
<p:column headerText="Date">
|
||||
<h:outputText value="#{demande.dateDepot}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="#{demande.statut}" severity="#{demande.statutSeverity}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<h:form id="formNouvelleDemande">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouvelle demande" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="onclick" value="PF('dlgNouvelleDemande').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mt-3" />
|
||||
</ui:include>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Historique -->
|
||||
<p:tab title="📋 Historique">
|
||||
<h6 class="mb-3">Activité récente</h6>
|
||||
<ui:repeat value="#{membreProfilBean.historique.activites}" var="activite" varStatus="status">
|
||||
<div class="flex align-items-start p-3 mb-3 border-round surface-50">
|
||||
<div class="border-circle bg-primary text-white flex align-items-center justify-content-center mr-3"
|
||||
style="width: 40px; height: 40px; min-width: 40px;">
|
||||
<i class="pi #{activite.icone}"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="font-medium text-900">#{activite.description}</span>
|
||||
<small class="text-600">#{activite.date}</small>
|
||||
</div>
|
||||
<div class="text-600 text-sm mb-1">
|
||||
Par #{activite.auteur}
|
||||
</div>
|
||||
<div class="text-sm text-700" rendered="#{activite.details != null}">
|
||||
#{activite.details}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ligne de connexion pour les éléments suivants -->
|
||||
<div class="flex justify-content-center mb-3" rendered="#{!status.last}">
|
||||
<div class="bg-300" style="width: 2px; height: 20px;"></div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<!-- Message si aucune activité -->
|
||||
<div class="text-center p-4 text-600" rendered="#{empty membreProfilBean.historique.activites}">
|
||||
<i class="pi pi-info-circle text-3xl mb-3"></i>
|
||||
<div>Aucune activité récente</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Modifier Profil -->
|
||||
<p:dialog header="Modifier le Profil" widgetVar="dlgModifierProfil" modal="true" width="800">
|
||||
<h:form id="formModifierProfil">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="editPrenom" />
|
||||
<ui:param name="label" value="Prénom" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membreEdit.prenom}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="editNom" />
|
||||
<ui:param name="label" value="Nom" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membreEdit.nom}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="editEmail" />
|
||||
<ui:param name="label" value="Email" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membreEdit.email}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="editTelephone" />
|
||||
<ui:param name="label" value="Téléphone" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membreEdit.telephone}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="editDateNaissance" />
|
||||
<ui:param name="label" value="Date de naissance" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membreEdit.dateNaissance}" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="editProfession" />
|
||||
<ui:param name="label" value="Profession" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membreEdit.profession}" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="editAdresse" />
|
||||
<ui:param name="label" value="Adresse" />
|
||||
<ui:param name="value" value="#{membreProfilBean.membreEdit.adresse}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreProfilBean.sauvegarderModifications}" />
|
||||
<ui:param name="update" value=":formModifierProfil :photoProfil" />
|
||||
<ui:param name="onclick" value="if(!args.validationFailed) PF('dlgModifierProfil').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgModifierProfil').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Contacter -->
|
||||
<p:dialog header="Contacter #{membreProfilBean.membre.prenom}" widgetVar="dlgContacter" modal="true" width="500">
|
||||
<h:form id="formContacter">
|
||||
<div class="ui-fluid">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="sujetContact" />
|
||||
<ui:param name="label" value="Sujet" />
|
||||
<ui:param name="value" value="#{membreProfilBean.contact.sujet}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="messageContact" />
|
||||
<ui:param name="label" value="Message" />
|
||||
<ui:param name="value" value="#{membreProfilBean.contact.message}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="5" />
|
||||
</ui:include>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="canalContact" value="Canal de communication" />
|
||||
<p:selectCheckboxMenu id="canalContact" value="#{membreProfilBean.contact.canaux}" multiple="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="📧 Email" itemValue="EMAIL" />
|
||||
<f:selectItem itemLabel="📱 SMS" itemValue="SMS" />
|
||||
<f:selectItem itemLabel="💬 WhatsApp" itemValue="WHATSAPP" />
|
||||
</p:selectCheckboxMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Envoyer" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{membreProfilBean.envoyerMessage}" />
|
||||
<ui:param name="update" value=":formContacter" />
|
||||
<ui:param name="oncomplete" value="if(!args.validationFailed) PF('dlgContacter').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgContacter').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Actions -->
|
||||
<p:dialog header="Actions sur le Membre" widgetVar="dlgActions" modal="true" width="400">
|
||||
<h:form id="formActions">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Suspendre membre" />
|
||||
<ui:param name="icon" value="pi pi-ban" />
|
||||
<ui:param name="action" value="#{membreProfilBean.suspendre}" />
|
||||
<ui:param name="onclick" value="return confirm('Êtes-vous sûr de vouloir suspendre ce membre ?');" />
|
||||
<ui:param name="styleClass" value="ui-button-danger w-full mb-2" />
|
||||
<ui:param name="rendered" value="#{membreProfilBean.membre.statut == 'ACTIF'}" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Réactiver membre" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreProfilBean.reactiver}" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
<ui:param name="rendered" value="#{membreProfilBean.membre.statut == 'SUSPENDU'}" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Changer de type" />
|
||||
<ui:param name="icon" value="pi pi-user-edit" />
|
||||
<ui:param name="onclick" value="PF('dlgChangerType').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Transférer vers entité" />
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="onclick" value="PF('dlgTransferer').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Exporter données" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreProfilBean.exporterDonnees}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
<ui:param name="update" value="none" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Supprimer membre" />
|
||||
<ui:param name="icon" value="pi pi-trash" />
|
||||
<ui:param name="action" value="#{membreProfilBean.supprimer}" />
|
||||
<ui:param name="onclick" value="return confirm('ATTENTION: Cette action est irréversible. Confirmer la suppression ?');" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-danger w-full" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Fermer" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgActions').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,713 @@
|
||||
<!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">Recherche Avancée des Membres - 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-search text-blue-500" />
|
||||
<ui:param name="title" value="Recherche Avancée des Membres" />
|
||||
<ui:param name="description" value="Outil de recherche puissant pour retrouver et analyser les membres" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActionsEntete">
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Recherches sauvegardées" />
|
||||
<ui:param name="icon" value="pi pi-bookmark" />
|
||||
<ui:param name="onclick" value="PF('dlgRecherchesSauvegardees').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouvelle recherche" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.nouvelleRecherche}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques de recherche -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Total Membres" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.statistiques.totalMembres}" />
|
||||
<ui:param name="icon" value="pi-users" />
|
||||
<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="Résultats trouvés" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.statistiques.resultatsActuels}" />
|
||||
<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>
|
||||
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Filtres actifs" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.statistiques.filtresActifs}" />
|
||||
<ui:param name="icon" value="pi-filter" />
|
||||
<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="Temps de recherche" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.statistiques.tempsRecherche}ms" />
|
||||
<ui:param name="icon" value="pi-clock" />
|
||||
<ui:param name="iconColor" value="purple-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>
|
||||
|
||||
<!-- Formulaire de recherche avancée -->
|
||||
<div class="card">
|
||||
<h:form id="formRechercheAvancee">
|
||||
<h5>
|
||||
<i class="pi pi-filter mr-2"></i>
|
||||
Critères de Recherche
|
||||
</h5>
|
||||
|
||||
<p:tabView>
|
||||
<!-- Onglet Informations de base -->
|
||||
<p:tab title="👤 Informations Personnelles">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-search-text.xhtml">
|
||||
<ui:param name="id" value="searchNom" />
|
||||
<ui:param name="label" value="Nom" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.nom}" />
|
||||
<ui:param name="placeholder" value="Rechercher par nom..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-search-text.xhtml">
|
||||
<ui:param name="id" value="searchPrenom" />
|
||||
<ui:param name="label" value="Prénom" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.prenom}" />
|
||||
<ui:param name="placeholder" value="Rechercher par prénom..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-search-text.xhtml">
|
||||
<ui:param name="id" value="searchEmail" />
|
||||
<ui:param name="label" value="Email" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.email}" />
|
||||
<ui:param name="placeholder" value="Rechercher par email..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-search-text.xhtml">
|
||||
<ui:param name="id" value="searchTelephone" />
|
||||
<ui:param name="label" value="Téléphone" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.telephone}" />
|
||||
<ui:param name="placeholder" value="Rechercher par téléphone..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-search-text.xhtml">
|
||||
<ui:param name="id" value="searchNumeroMembre" />
|
||||
<ui:param name="label" value="Numéro membre" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.numeroMembre}" />
|
||||
<ui:param name="placeholder" value="Ex: M2024001" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-autocomplete.xhtml">
|
||||
<ui:param name="id" value="searchProfession" />
|
||||
<ui:param name="label" value="Profession" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.profession}" />
|
||||
<ui:param name="completeMethod" value="#{membreRechercheBean.completerProfessions}" />
|
||||
<ui:param name="placeholder" value="Saisir une profession..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Critères d'adhésion -->
|
||||
<p:tab title="🏢 Adhésion et Statut">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-checkbox-menu.xhtml">
|
||||
<ui:param name="id" value="searchStatut" />
|
||||
<ui:param name="label" value="Statut" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.statuts}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Inactif" itemValue="INACTIF" />
|
||||
<f:selectItem itemLabel="Suspendu" itemValue="SUSPENDU" />
|
||||
<f:selectItem itemLabel="Radié" itemValue="RADIE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-checkbox-menu.xhtml">
|
||||
<ui:param name="id" value="searchTypeMembre" />
|
||||
<ui:param name="label" value="Type de membre" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.typesMembre}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Actif" itemValue="ACTIF" />
|
||||
<f:selectItem itemLabel="Associé" itemValue="ASSOCIE" />
|
||||
<f:selectItem itemLabel="Bienfaiteur" itemValue="BIENFAITEUR" />
|
||||
<f:selectItem itemLabel="Honoraire" itemValue="HONORAIRE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel for="searchEntite" value="Entité" />
|
||||
<p:selectCheckboxMenu id="searchEntite" value="#{membreRechercheBean.filtres.entites}"
|
||||
multiple="true" styleClass="w-full">
|
||||
<f:selectItems value="#{membreRechercheBean.entitesDisponibles}"
|
||||
var="entite"
|
||||
itemLabel="#{entite.nom}"
|
||||
itemValue="#{entite.id}" />
|
||||
<p:ajax update=":formResultats:dtResultats @(.search-summary)" />
|
||||
</p:selectCheckboxMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-checkbox-menu.xhtml">
|
||||
<ui:param name="id" value="searchCotisationStatut" />
|
||||
<ui:param name="label" value="Statut cotisations" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.statutsCotisation}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="À jour" itemValue="A_JOUR" />
|
||||
<f:selectItem itemLabel="En retard" itemValue="EN_RETARD" />
|
||||
<f:selectItem itemLabel="Jamais payé" itemValue="JAMAIS_PAYE" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="adhesionDateDebut" />
|
||||
<ui:param name="label" value="Adhésion après le" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.dateAdhesionDebut}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="adhesionDateFin" />
|
||||
<ui:param name="label" value="Adhésion avant le" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.dateAdhesionFin}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Critères démographiques -->
|
||||
<p:tab title="📊 Critères Démographiques">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-checkbox-menu.xhtml">
|
||||
<ui:param name="id" value="searchGenre" />
|
||||
<ui:param name="label" value="Genre" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.genres}" />
|
||||
<ui:define name="items">
|
||||
<f:selectItem itemLabel="Masculin" itemValue="M" />
|
||||
<f:selectItem itemLabel="Féminin" itemValue="F" />
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="ageMin" />
|
||||
<ui:param name="label" value="Âge minimum" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.ageMin}" />
|
||||
<ui:param name="placeholder" value="Ex: 25" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="ageMax" />
|
||||
<ui:param name="label" value="Âge maximum" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.ageMax}" />
|
||||
<ui:param name="placeholder" value="Ex: 65" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-autocomplete.xhtml">
|
||||
<ui:param name="id" value="searchVille" />
|
||||
<ui:param name="label" value="Ville" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.ville}" />
|
||||
<ui:param name="completeMethod" value="#{membreRechercheBean.completerVilles}" />
|
||||
<ui:param name="placeholder" value="Saisir une ville..." />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Critères d'activité -->
|
||||
<p:tab title="📈 Activité et Engagement">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="tauxParticipationMin" />
|
||||
<ui:param name="label" value="Taux participation min (%)" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.tauxParticipationMin}" />
|
||||
<ui:param name="minValue" value="0" />
|
||||
<ui:param name="maxValue" value="100" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="evenementsMin" />
|
||||
<ui:param name="label" value="Événements min (cette année)" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.evenementsMin}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<ui:include src="/templates/components/forms/form-field-number.xhtml">
|
||||
<ui:param name="id" value="cotisationsMin" />
|
||||
<ui:param name="label" value="Cotisations payées min" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.cotisationsMin}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-boolean.xhtml">
|
||||
<ui:param name="id" value="aDesEnfants" />
|
||||
<ui:param name="label" value=" A des enfants déclarés" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.aDesEnfants}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-boolean.xhtml">
|
||||
<ui:param name="id" value="aRecuAides" />
|
||||
<ui:param name="label" value=" A reçu des aides" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.filtres.aRecuAides}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
|
||||
<!-- Actions de recherche -->
|
||||
<div class="flex gap-2 mt-4">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Rechercher" />
|
||||
<ui:param name="icon" value="pi pi-search" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.effectuerRecherche}" />
|
||||
<ui:param name="update" value=":formResultats:dtResultats @(.search-summary)" />
|
||||
</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="#{membreRechercheBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value=":formRechercheAvancee :formResultats:dtResultats @(.search-summary)" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Sauvegarder recherche" />
|
||||
<ui:param name="icon" value="pi pi-bookmark" />
|
||||
<ui:param name="onclick" value="PF('dlgSauvegarderRecherche').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Exporter résultats" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="onclick" value="PF('dlgExporterResultats').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreRechercheBean.resultats}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Résumé de recherche -->
|
||||
<div class="card search-summary">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="mb-2">
|
||||
<i class="pi pi-list mr-2"></i>
|
||||
Résultats de recherche
|
||||
</h6>
|
||||
<p class="text-600 m-0">
|
||||
#{membreRechercheBean.resultats.size()} membre(s) trouvé(s)
|
||||
sur #{membreRechercheBean.statistiques.totalMembres} total
|
||||
<span class="ml-2" rendered="#{membreRechercheBean.statistiques.filtresActifs > 0}">
|
||||
• #{membreRechercheBean.statistiques.filtresActifs} filtre(s) actif(s)
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:tag value="#{membreRechercheBean.resultats.size()} résultats"
|
||||
severity="#{membreRechercheBean.resultats.size() > 0 ? 'success' : 'warning'}"
|
||||
icon="pi pi-check" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tableau des résultats -->
|
||||
<div class="card">
|
||||
<h:form id="formResultats">
|
||||
<p:dataTable id="dtResultats"
|
||||
var="membre"
|
||||
value="#{membreRechercheBean.resultats}"
|
||||
paginator="true"
|
||||
rows="15"
|
||||
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
|
||||
rowsPerPageTemplate="10,15,25,50"
|
||||
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
|
||||
selection="#{membreRechercheBean.selectedMembres}"
|
||||
rowKey="#{membre.id}"
|
||||
selectionMode="multiple"
|
||||
emptyMessage="Aucun membre ne correspond aux critères de recherche">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<span>Liste des membres</span>
|
||||
<div class="flex gap-2">
|
||||
<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="#{membreRechercheBean.actualiserResultats}" />
|
||||
<ui:param name="update" value=":formResultats:dtResultats" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-cog" />
|
||||
<ui:param name="onclick" value="PF('dlgOptionsAffichage').show();" />
|
||||
<ui:param name="title" value="Options d'affichage" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:column selectionMode="multiple" style="width:50px" />
|
||||
|
||||
<p:column headerText="N° Membre" sortBy="#{membre.numeroMembre}" style="width:120px">
|
||||
<h:outputText value="#{membre.numeroMembre}" styleClass="font-mono font-bold" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Membre" sortBy="#{membre.nom}">
|
||||
<div class="flex align-items-center">
|
||||
<div class="border-circle overflow-hidden mr-3"
|
||||
style="width: 40px; height: 40px;">
|
||||
<h:graphicImage value="#{membre.photoUrl}"
|
||||
style="width: 100%; height: 100%; object-fit: cover;"
|
||||
rendered="#{membre.photoUrl != null}" />
|
||||
<div class="bg-primary text-white flex align-items-center justify-content-center w-full h-full"
|
||||
rendered="#{membre.photoUrl == null}">
|
||||
<span style="font-size: 0.9rem;">#{membre.initiales}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-900">#{membre.nomComplet}</div>
|
||||
<div class="text-600 text-sm">
|
||||
<span>#{membre.telephone}</span>
|
||||
<span class="mx-2">•</span>
|
||||
<span>#{membre.email}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type" sortBy="#{membre.typeMembre}" style="width:120px">
|
||||
<p:tag value="#{membre.typeMembre}"
|
||||
severity="#{membre.typeSeverity}"
|
||||
icon="pi #{membre.typeIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut" sortBy="#{membre.statut}" style="width:100px">
|
||||
<p:tag value="#{membre.statut}"
|
||||
severity="#{membre.statutSeverity}"
|
||||
icon="pi #{membre.statutIcon}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Entité" sortBy="#{membre.entite}" style="width:150px">
|
||||
<h:outputText value="#{membre.entite}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Adhésion" sortBy="#{membre.dateAdhesion}" style="width:120px">
|
||||
<div>
|
||||
<div class="font-medium">#{membre.dateAdhesion}</div>
|
||||
<small class="text-600">#{membre.anciennete}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Cotisations" style="width:120px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold #{membre.cotisationColor}">#{membre.cotisationStatut}</div>
|
||||
<small class="text-600">#{membre.dernierPaiement}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Participation" style="width:100px">
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-blue-500">#{membre.tauxParticipation}%</div>
|
||||
<small class="text-600">#{membre.evenementsAnnee} événements</small>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" style="width:150px">
|
||||
<div class="flex gap-1">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.voirProfil(membre)}" />
|
||||
<ui:param name="title" value="Voir profil" />
|
||||
<ui:param name="severity" value="info" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.contacterMembre(membre)}" />
|
||||
<ui:param name="title" value="Contacter" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.ajouterAuGroupe(membre)}" />
|
||||
<ui:param name="title" value="Ajouter au groupe de travail" />
|
||||
<ui:param name="severity" value="success" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<!-- Actions groupées -->
|
||||
<div class="mt-3 flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<span class="text-600">#{membreRechercheBean.selectedMembres.size()} membre(s) sélectionné(s)</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-info.xhtml">
|
||||
<ui:param name="value" value="Envoyer message groupé" />
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="onclick" value="PF('dlgMessageGroupe').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreRechercheBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Créer groupe de travail" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="onclick" value="PF('dlgCreerGroupe').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreRechercheBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-warning.xhtml">
|
||||
<ui:param name="value" value="Exporter sélection" />
|
||||
<ui:param name="icon" value="pi pi-file-excel" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.exporterSelection}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreRechercheBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Sauvegarder Recherche -->
|
||||
<p:dialog header="Sauvegarder la Recherche" widgetVar="dlgSauvegarderRecherche" modal="true" width="500">
|
||||
<h:form id="formSauvegarderRecherche">
|
||||
<div class="ui-fluid">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="nomRecherche" />
|
||||
<ui:param name="label" value="Nom de la recherche" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.nouvelleRechercheSauvegardee.nom}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="placeholder" value="Ex: Membres actifs 2024" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="descriptionRecherche" />
|
||||
<ui:param name="label" value="Description" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.nouvelleRechercheSauvegardee.description}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="recherchePublique" value="#{membreRechercheBean.nouvelleRechercheSauvegardee.publique}" />
|
||||
<p:outputLabel for="recherchePublique" value=" Partager avec les autres administrateurs" />
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Critères à sauvegarder :</div>
|
||||
<div class="text-600 text-sm">#{membreRechercheBean.statistiques.filtresActifs} filtre(s) actif(s) seront sauvegardés</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Sauvegarder" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.sauvegarderRecherche}" />
|
||||
<ui:param name="update" value=":formSauvegarderRecherche" />
|
||||
<ui:param name="onclick" value="if(!args.validationFailed) PF('dlgSauvegarderRecherche').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgSauvegarderRecherche').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Recherches Sauvegardées -->
|
||||
<p:dialog header="Recherches Sauvegardées" widgetVar="dlgRecherchesSauvegardees" modal="true" width="700">
|
||||
<h:form id="formRecherchesSauvegardees">
|
||||
<p:dataTable value="#{membreRechercheBean.recherchesSauvegardees}" var="recherche"
|
||||
styleClass="p-datatable-sm" emptyMessage="Aucune recherche sauvegardée">
|
||||
<p:column headerText="Nom">
|
||||
<div>
|
||||
<div class="font-medium">#{recherche.nom}</div>
|
||||
<small class="text-600">#{recherche.description}</small>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Critères">
|
||||
<p:tag value="#{recherche.nombreCriteres} critères" severity="info" />
|
||||
</p:column>
|
||||
<p:column headerText="Créée le">
|
||||
<h:outputText value="#{recherche.dateCreation}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" type="localDate" />
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Publique">
|
||||
<p:tag value="#{recherche.publique ? 'Oui' : 'Non'}"
|
||||
severity="#{recherche.publique ? 'success' : 'secondary'}" />
|
||||
</p:column>
|
||||
<p:column headerText="Actions">
|
||||
<div class="flex gap-1">
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-play" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.chargerRecherche(recherche)}" />
|
||||
<ui:param name="update" value=":formRechercheAvancee :formResultats" />
|
||||
<ui:param name="onclick" value="PF('dlgRecherchesSauvegardees').hide();" />
|
||||
<ui:param name="title" value="Charger" />
|
||||
<ui:param name="severity" value="success" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-trash" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.supprimerRecherche(recherche)}" />
|
||||
<ui:param name="update" value=":formRecherchesSauvegardees" />
|
||||
<ui:param name="onclick" value="return confirm('Supprimer cette recherche ?');" />
|
||||
<ui:param name="title" value="Supprimer" />
|
||||
<ui:param name="severity" value="danger" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<div class="flex justify-content-end mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Fermer" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgRecherchesSauvegardees').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog Message Groupé -->
|
||||
<p:dialog header="Envoyer un Message Groupé" widgetVar="dlgMessageGroupe" modal="true" width="600">
|
||||
<h:form id="formMessageGroupe">
|
||||
<div class="ui-fluid">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="sujetMessageGroupe" />
|
||||
<ui:param name="label" value="Sujet" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.messageGroupe.sujet}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="placeholder" value="Objet du message" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="contenuMessageGroupe" />
|
||||
<ui:param name="label" value="Message" />
|
||||
<ui:param name="value" value="#{membreRechercheBean.messageGroupe.contenu}" />
|
||||
<ui:param name="required" value="true" />
|
||||
<ui:param name="rows" value="6" />
|
||||
</ui:include>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="canauxMessageGroupe" value="Canaux de diffusion" />
|
||||
<p:selectCheckboxMenu id="canauxMessageGroupe" value="#{membreRechercheBean.messageGroupe.canaux}"
|
||||
multiple="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="📧 Email" itemValue="EMAIL" />
|
||||
<f:selectItem itemLabel="📱 SMS" itemValue="SMS" />
|
||||
<f:selectItem itemLabel="💬 WhatsApp" itemValue="WHATSAPP" />
|
||||
<f:selectItem itemLabel="🔔 Notification push" itemValue="PUSH" />
|
||||
</p:selectCheckboxMenu>
|
||||
</div>
|
||||
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<div class="font-medium mb-2">Destinataires :</div>
|
||||
<div class="text-600">#{membreRechercheBean.selectedMembres.size()} membre(s) recevront ce message</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<ui:include src="/templates/components/buttons/button-success.xhtml">
|
||||
<ui:param name="value" value="Envoyer" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{membreRechercheBean.envoyerMessageGroupe}" />
|
||||
<ui:param name="update" value=":formMessageGroupe :formResultats" />
|
||||
<ui:param name="onclick" value="if(!args.validationFailed) PF('dlgMessageGroupe').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgMessageGroupe').hide();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,263 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<ui:composition template="/templates/main-template.xhtml">
|
||||
<ui:param name="page" value="#{organisationDetailBean}"/>
|
||||
<ui:define name="title">Détail de l'Organisation</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formDetail">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête résumé -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div class="flex align-items-center gap-3 mb-2 md:mb-0">
|
||||
<ui:include src="/templates/components/layout/organisation-logo.xhtml">
|
||||
<ui:param name="logo" value="#{organisationDetailBean.organisation.logo}"/>
|
||||
<ui:param name="size" value="64"/>
|
||||
</ui:include>
|
||||
<div>
|
||||
<h3 class="m-0">
|
||||
<h:outputText value="#{empty organisationDetailBean.organisation ? 'Organisation introuvable' : organisationDetailBean.organisation.nom}" />
|
||||
</h3>
|
||||
<div class="mt-2 flex align-items-center gap-2">
|
||||
<p:tag value="#{organisationDetailBean.organisation.typeLibelle}" severity="info" />
|
||||
<p:tag value="#{organisationDetailBean.organisation.statutLibelle}"
|
||||
severity="#{organisationDetailBean.organisation.statutSeverity}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Retour à la liste"/>
|
||||
<ui:param name="icon" value="pi pi-arrow-left"/>
|
||||
<ui:param name="outcome" value="/pages/secure/organisation/liste"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h:panelGroup rendered="#{not empty organisationDetailBean.organisation}">
|
||||
<div class="grid">
|
||||
<!-- Bloc identité -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Identité</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Nom complet"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.nom}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Nom court / Sigle"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.nomCourt}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Type"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.typeLibelle}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Statut"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.statutLibelle}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Date de fondation"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.dateFondation}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Numéro d'enregistrement"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.numeroRegistre}"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bloc contact -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Contacts</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Email"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.email}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Email secondaire"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.emailSecondaire}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Téléphone"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.telephone}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Téléphone secondaire"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.telephoneSecondaire}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Site web"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.siteWeb}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Responsable principal"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.responsablePrincipal}"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bloc localisation -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Localisation</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Adresse complète"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.adresseComplete}"/>
|
||||
<ui:param name="multiline" value="true"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Ville"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.ville}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Région"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.region}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Pays"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.pays}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Code postal"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.codePostal}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Latitude"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.latitude}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Longitude"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.longitude}"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bloc description, objectifs et activités -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Description, objectifs & activités</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Description"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.description}"/>
|
||||
<ui:param name="multiline" value="true"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Objectifs"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.objectifs}"/>
|
||||
<ui:param name="multiline" value="true"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Activités principales"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.activitesPrincipales}"/>
|
||||
<ui:param name="multiline" value="true"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bloc gouvernance & membres -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Gouvernance & membres</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Nombre de membres"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.nombreMembres}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Nombre d'administrateurs"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.nombreAdministrateurs}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Organisation publique"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.organisationPublique ? 'Oui' : 'Non'}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Accepte de nouveaux membres"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.accepteNouveauxMembres ? 'Oui' : 'Non'}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Cotisation obligatoire"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.cotisationObligatoire ? 'Oui' : 'Non'}"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bloc budget & cotisations -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Budget & cotisations</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Budget annuel"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.budgetAnnuel}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Devise"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.devise}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Montant cotisation annuelle"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.montantCotisationAnnuelle}"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bloc réseaux & partenariats -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Réseaux & partenariats</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Réseaux sociaux"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.reseauxSociaux}"/>
|
||||
<ui:param name="multiline" value="true"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Certifications / labels"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.certifications}"/>
|
||||
<ui:param name="multiline" value="true"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Partenaires principaux"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.partenaires}"/>
|
||||
<ui:param name="multiline" value="true"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bloc notes & hiérarchie -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Notes & hiérarchie</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Organisation parente"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.nomOrganisationParente}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="ID organisation parente"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.organisationParenteId}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Niveau hiérarchique"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.niveauHierarchique}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Notes administratives"/>
|
||||
<ui:param name="value" value="#{organisationDetailBean.organisation.notes}"/>
|
||||
<ui:param name="multiline" value="true"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
</html>
|
||||
@@ -0,0 +1,251 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:uf="http://xmlns.jcp.org/jsf/composite/components">
|
||||
|
||||
<ui:composition template="/templates/main-template.xhtml">
|
||||
<ui:param name="page" value="#{organisationsBean}"/>
|
||||
<ui:define name="title">Gestion des Organisations</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formOrganisations">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête avec titre et action principale (DRY/WOU: card-header) -->
|
||||
<ui:decorate template="/templates/components/cards/card-header.xhtml">
|
||||
<ui:param name="title" value="Gestion des Organisations" />
|
||||
<ui:param name="subtitle" value="Liste complète des organisations avec filtres et actions." />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="actions">
|
||||
<p:button value="Nouvelle Organisation"
|
||||
icon="pi pi-plus"
|
||||
outcome="/pages/secure/organisation/nouvelle"
|
||||
styleClass="ui-button-success" />
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Statistiques (DRY/WOU: stat-card) -->
|
||||
<div class="grid mb-3">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{organisationsBean.totalOrganisations}" />
|
||||
<ui:param name="label" value="Total" />
|
||||
<ui:param name="icon" value="pi pi-building" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{organisationsBean.organisationsActives}" />
|
||||
<ui:param name="label" value="Actives" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{organisationsBean.organisationsInactives}" />
|
||||
<ui:param name="label" value="Inactives" />
|
||||
<ui:param name="icon" value="pi pi-times-circle" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Filtres et recherche (DRY/WOU: filter-bar) -->
|
||||
<ui:decorate template="/templates/components/cards/filter-bar.xhtml">
|
||||
<ui:param name="title" value="Filtres" />
|
||||
<ui:param name="styleClass" value="mb-3" />
|
||||
<ui:define name="filters">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:outputLabel for="rechercheGlobale" value="Rechercher" />
|
||||
<p:inputText id="rechercheGlobale"
|
||||
value="#{organisationsBean.rechercheGlobale}"
|
||||
placeholder="Nom, ville, description..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup" update="dtOrganisations" listener="#{organisationsBean.appliquerFiltres}" delay="500"/>
|
||||
</p:inputText>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreStatut" value="Statut" />
|
||||
<p:selectOneMenu id="filtreStatut"
|
||||
value="#{organisationsBean.filtreStatut}"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{organisationsBean.statutsSelectItems}" />
|
||||
<p:ajax event="change" update="dtOrganisations" listener="#{organisationsBean.appliquerFiltres}"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<p:outputLabel for="filtreType" value="Type" />
|
||||
<p:selectOneMenu id="filtreType"
|
||||
value="#{organisationsBean.filtreType}"
|
||||
styleClass="w-full">
|
||||
<f:selectItems value="#{organisationsBean.typesSelectItems}" />
|
||||
<p:ajax event="change" update="dtOrganisations" listener="#{organisationsBean.appliquerFiltres}"/>
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
<ui:define name="actions">
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-filter-slash"
|
||||
action="#{organisationsBean.reinitialiserFiltres}"
|
||||
update="dtOrganisations rechercheGlobale filtreStatut filtreType"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-2">
|
||||
<div class="field">
|
||||
<label class="invisible">Actions</label>
|
||||
<p:commandButton value="Rafraîchir"
|
||||
icon="pi pi-refresh"
|
||||
action="#{organisationsBean.recharger}"
|
||||
update="@form"
|
||||
styleClass="ui-button-secondary w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Table des organisations (DRY/WOU: card-simple) -->
|
||||
<ui:decorate template="/templates/components/cards/card-simple.xhtml">
|
||||
<ui:param name="title" value="Liste des Organisations" />
|
||||
<ui:define name="content">
|
||||
<!-- Note: p:dataTable avec var, sortBy, filterBy doit être directement dans la page -->
|
||||
<p:dataTable id="dtOrganisations"
|
||||
value="#{organisationsBean.organisationsFiltrees}"
|
||||
var="org"
|
||||
paginator="true"
|
||||
rows="20"
|
||||
rowsPerPageTemplate="10,20,50,100"
|
||||
paginatorPosition="bottom"
|
||||
emptyMessage="Aucune organisation trouvée"
|
||||
styleClass="table-responsive"
|
||||
size="small">
|
||||
|
||||
<!-- Logo (DRY/WOU: organisation-logo) -->
|
||||
<p:column headerText="" style="width: 80px;">
|
||||
<ui:include src="/templates/components/layout/organisation-logo.xhtml">
|
||||
<ui:param name="logo" value="#{org.logo}"/>
|
||||
<ui:param name="size" value="40"/>
|
||||
</ui:include>
|
||||
</p:column>
|
||||
|
||||
<!-- Nom avec sous-titre -->
|
||||
<p:column headerText="Nom" sortBy="#{org.nom}" filterBy="#{org.nom}">
|
||||
<h:outputText value="#{org.nom}" styleClass="font-bold"/>
|
||||
<br/>
|
||||
<h:outputText value="#{org.typeLibelle}" styleClass="text-sm text-500"/>
|
||||
</p:column>
|
||||
|
||||
<!-- Type -->
|
||||
<p:column headerText="Type" sortBy="#{org.typeAssociation}" style="width: 150px;">
|
||||
<p:tag value="#{org.typeLibelle}"
|
||||
severity="#{org.typeAssociation == 'LIONS_CLUB' ? 'info' : 'primary'}"/>
|
||||
</p:column>
|
||||
|
||||
<!-- Localisation -->
|
||||
<p:column headerText="Localisation" style="width: 200px;">
|
||||
<i class="pi pi-map-marker mr-2 text-500"/>
|
||||
<h:outputText value="#{org.ville}, #{org.region}"/>
|
||||
</p:column>
|
||||
|
||||
<!-- Membres -->
|
||||
<p:column headerText="Membres" styleClass="text-center" style="width: 100px;">
|
||||
<p:tag value="#{org.nombreMembres}" severity="info" icon="pi pi-users"/>
|
||||
</p:column>
|
||||
|
||||
<!-- Statut -->
|
||||
<p:column headerText="Statut" sortBy="#{org.statut}" styleClass="text-center" style="width: 100px;">
|
||||
<p:tag value="#{org.statut}"
|
||||
severity="#{org.statut == organisationsBean.statutActive ? 'success' : 'warning'}"
|
||||
icon="#{org.statut == organisationsBean.statutActive ? 'pi pi-check' : 'pi pi-times'}"/>
|
||||
</p:column>
|
||||
|
||||
<!-- Actions (DRY/WOU: Composite Components) -->
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<!-- DRY/WOU: Composite Component action-button-view -->
|
||||
<uf:action-button-view itemId="#{org.id.toString()}"
|
||||
detailPage="/pages/secure/organisation/detail.xhtml"
|
||||
iconOnly="true"/>
|
||||
<!-- DRY/WOU: button-icon pour Modifier -->
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
actionListener="#{organisationsBean.setOrganisationSelectionnee(org)}"
|
||||
oncomplete="PF('dlgModifier').show();"
|
||||
update=":formModifier"
|
||||
styleClass="ui-button-rounded ui-button-warning"
|
||||
title="Modifier"/>
|
||||
<!-- DRY/WOU: button-icon pour Activer/Désactiver -->
|
||||
<p:commandButton icon="#{org.statut == organisationsBean.statutActive ? 'pi pi-ban' : 'pi pi-check'}"
|
||||
actionListener="#{organisationsBean.basculerStatutOrganisation(org)}"
|
||||
update=":formOrganisations:dtOrganisations :formOrganisations:messages"
|
||||
styleClass="ui-button-rounded #{org.statut == organisationsBean.statutActive ? 'ui-button-secondary' : 'ui-button-success'}"
|
||||
title="#{org.statut == organisationsBean.statutActive ? 'Désactiver' : 'Activer'}">
|
||||
<p:confirm header="Confirmation"
|
||||
message="Êtes-vous sûr de vouloir changer le statut de cette organisation ?"
|
||||
icon="pi pi-exclamation-triangle"/>
|
||||
</p:commandButton>
|
||||
<!-- DRY/WOU: button-icon pour Supprimer -->
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
actionListener="#{organisationsBean.supprimerOrganisation(org)}"
|
||||
update=":formOrganisations:dtOrganisations :formOrganisations:messages"
|
||||
styleClass="ui-button-rounded ui-button-danger"
|
||||
title="Supprimer">
|
||||
<p:confirm header="Confirmation"
|
||||
message="Êtes-vous sûr de vouloir supprimer cette organisation ? Cette action est irréversible."
|
||||
icon="pi pi-exclamation-triangle"/>
|
||||
</p:commandButton>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
|
||||
<!-- Dialogue de confirmation global (DRY/WOU: confirm-dialog) -->
|
||||
<ui:include src="/templates/components/dialogs/confirm-dialog.xhtml" />
|
||||
</h:form>
|
||||
|
||||
<!-- Dialogue Modifier Organisation (DRY/WOU: form-dialog) -->
|
||||
<ui:decorate template="/templates/components/dialogs/form-dialog.xhtml">
|
||||
<ui:param name="dialogId" value="dlgModifier" />
|
||||
<ui:param name="header" value="Modifier Organisation" />
|
||||
<ui:param name="widgetVar" value="dlgModifier" />
|
||||
<ui:param name="formId" value="formModifier" />
|
||||
<ui:param name="width" value="900" />
|
||||
<ui:param name="maximizable" value="true" />
|
||||
<ui:param name="fitViewport" value="true" />
|
||||
<ui:define name="content">
|
||||
<ui:fragment rendered="#{organisationsBean.organisationSelectionnee != null}">
|
||||
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||
<ui:param name="model" value="#{organisationsBean.organisationSelectionnee}" />
|
||||
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||
</ui:include>
|
||||
</ui:fragment>
|
||||
</ui:define>
|
||||
<ui:define name="footer">
|
||||
<!-- Bouton Annuler : type="button" pour éviter la soumission -->
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
type="button"
|
||||
onclick="PF('dlgModifier').hide();"
|
||||
styleClass="ui-button-secondary" />
|
||||
<!-- DRY/WOU: button-form-submit pour action backend -->
|
||||
<ui:decorate template="/templates/components/buttons/button-form-submit.xhtml">
|
||||
<ui:param name="value" value="Enregistrer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{organisationsBean.modifierOrganisation}" />
|
||||
<ui:param name="update" value=":formOrganisations:dtOrganisations :formOrganisations:messages" />
|
||||
<ui:param name="oncomplete" value="if(!args.validationFailed) PF('dlgModifier').hide();" />
|
||||
<ui:param name="severity" value="success" />
|
||||
</ui:decorate>
|
||||
</ui:define>
|
||||
</ui:decorate>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
</html>
|
||||
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<ui:composition template="/templates/main-template.xhtml">
|
||||
<ui:param name="page" value="#{organisationsBean}"/>
|
||||
<ui:define name="title">Nouvelle Organisation</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- Initialiser le modèle et le catalogue des types à chaque affichage de la vue -->
|
||||
<f:event type="preRenderView" listener="#{organisationsBean.preparerNouvelleOrganisation}" />
|
||||
|
||||
<h:form id="formNouvelleOrganisation">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div class="mb-2 md:mb-0">
|
||||
<h3 class="m-0">Nouvelle Organisation</h3>
|
||||
<span class="text-600">
|
||||
Renseignez l'ensemble des informations de l'organisation.
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler"/>
|
||||
<ui:param name="icon" value="pi pi-times"/>
|
||||
<ui:param name="outcome" value="/pages/secure/organisation/liste"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Informations de l'Organisation</h5>
|
||||
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||
<ui:param name="model" value="#{organisationsBean.nouvelleOrganisation}" />
|
||||
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 flex justify-content-end gap-2">
|
||||
<!-- DRY/WOU: button-secondary pour navigation -->
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler"/>
|
||||
<ui:param name="icon" value="pi pi-times"/>
|
||||
<ui:param name="outcome" value="/pages/secure/organisation/liste"/>
|
||||
</ui:include>
|
||||
<!-- Bouton Créer : p:commandButton direct car action avec méthode backend -->
|
||||
<p:commandButton value="Créer"
|
||||
icon="pi pi-check"
|
||||
action="#{organisationsBean.creerOrganisation}"
|
||||
update=":formNouvelleOrganisation:messages"
|
||||
styleClass="ui-button-success" />
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
<!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:param name="page" value="#{personnelBean}"/>
|
||||
<ui:define name="title">Mes Activités - 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-purple-500" />
|
||||
<ui:param name="title" value="Mes Activités" />
|
||||
<ui:param name="description" value="Suivez toutes vos interactions et participations dans UnionFlow" />
|
||||
<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="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Filtrer" />
|
||||
<ui:param name="icon" value="pi pi-filter" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltres').show();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques d'activité -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.actionsRealisees}" />
|
||||
<ui:param name="label" value="Actions Totales" />
|
||||
<ui:param name="subLabel" value="Toutes périodes" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.evenementsParticipes}" />
|
||||
<ui:param name="label" value="Événements" />
|
||||
<ui:param name="subLabel" value="Participés" />
|
||||
<ui:param name="icon" value="pi pi-calendar" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.tauxParticipation}%" />
|
||||
<ui:param name="label" value="Taux Participation" />
|
||||
<ui:param name="subLabel" value="Global" />
|
||||
<ui:param name="icon" value="pi pi-chart-line" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="8h" />
|
||||
<ui:param name="label" value="Temps Connecté" />
|
||||
<ui:param name="subLabel" value="Cette semaine" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Activités récentes -->
|
||||
<div class="card">
|
||||
<h5>Activités Récentes</h5>
|
||||
|
||||
<ui:repeat value="#{personnelBean.activitesRecentes}" var="activite">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-#{activite.couleur}-100 flex align-items-center justify-content-center">
|
||||
<i class="pi #{activite.icon} text-#{activite.couleur}-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#{activite.titre}</h6>
|
||||
<p class="text-600 text-sm mb-0">#{activite.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-900 font-semibold text-sm">#{activite.dateHeure}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<div class="text-center text-600 text-sm" rendered="#{empty personnelBean.activitesRecentes}">
|
||||
Aucune activité récente
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,87 @@
|
||||
<!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:param name="page" value="#{personnelBean}"/>
|
||||
<ui:define name="title">Mon Agenda - 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-calendar text-blue-500" />
|
||||
<ui:param name="title" value="Mon Agenda" />
|
||||
<ui:param name="description" value="Organisez votre planning et ne manquez aucun événement important" />
|
||||
<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="Synchroniser" />
|
||||
<ui:param name="icon" value="pi pi-sync" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Nouvel Événement" />
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="onclick" value="PF('nouvelEvenementDialog').show();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques agenda -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="7" />
|
||||
<ui:param name="label" value="Cette Semaine" />
|
||||
<ui:param name="subLabel" value="Événements" />
|
||||
<ui:param name="icon" value="pi pi-calendar" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="3" />
|
||||
<ui:param name="label" value="Aujourd'hui" />
|
||||
<ui:param name="subLabel" value="Rendez-vous" />
|
||||
<ui:param name="icon" value="pi pi-clock" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.evenementsParticipes}" />
|
||||
<ui:param name="label" value="Ce Mois" />
|
||||
<ui:param name="subLabel" value="Total" />
|
||||
<ui:param name="icon" value="pi pi-calendar-times" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.tauxParticipation}%" />
|
||||
<ui:param name="label" value="Taux Présence" />
|
||||
<ui:param name="subLabel" value="Moyenne" />
|
||||
<ui:param name="icon" value="pi pi-chart-bar" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Calendrier -->
|
||||
<div class="card">
|
||||
<h5>Calendrier Mensuel</h5>
|
||||
<p:schedule value="#{evenementsBean.evenementsCalendrier}"
|
||||
widgetVar="scheduleWidget"
|
||||
view="month"
|
||||
locale="fr"
|
||||
timeZone="Africa/Dakar"
|
||||
styleClass="w-full"
|
||||
height="600">
|
||||
<p:ajax event="dateSelect" listener="#{evenementsBean.onDateSelect}" />
|
||||
<p:ajax event="eventSelect" listener="#{evenementsBean.onEventSelect}" />
|
||||
</p:schedule>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,146 @@
|
||||
<!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:param name="page" value="#{personnelBean}"/>
|
||||
<ui:define name="title">Mes Documents - 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-folder text-green-500" />
|
||||
<ui:param name="title" value="Mes Documents" />
|
||||
<ui:param name="description" value="Gérez vos documents personnels et accédez aux fichiers partagés" />
|
||||
<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="Nouveau Dossier" />
|
||||
<ui:param name="icon" value="pi pi-folder-plus" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Télécharger" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="onclick" value="PF('uploadDialog').show();" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques stockage -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.documents != null ? personnelBean.documents.size() : 0}" />
|
||||
<ui:param name="label" value="Documents" />
|
||||
<ui:param name="subLabel" value="Personnels" />
|
||||
<ui:param name="icon" value="pi pi-file" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="2.4 GB" />
|
||||
<ui:param name="label" value="Utilisé" />
|
||||
<ui:param name="subLabel" value="Sur 5 GB" />
|
||||
<ui:param name="icon" value="pi pi-database" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des documents -->
|
||||
<div class="card">
|
||||
<h5>Mes Documents</h5>
|
||||
|
||||
<p:dataTable value="#{personnelBean.documents}" var="document"
|
||||
emptyMessage="Aucun document disponible"
|
||||
styleClass="p-datatable-sm">
|
||||
|
||||
<p:column headerText="Nom">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-file text-lg"></i>
|
||||
<span class="font-semibold">#{document.nom}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Type">
|
||||
<span>#{document.type}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date">
|
||||
<span>#{document.dateCreation}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Taille">
|
||||
<span>#{document.taille} bytes</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" styleClass="text-center">
|
||||
<div class="flex justify-content-center gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir"
|
||||
styleClass="p-button-sm p-button-rounded p-button-info" />
|
||||
<p:commandButton icon="pi pi-download"
|
||||
title="Télécharger"
|
||||
styleClass="p-button-sm p-button-rounded p-button-success" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Upload -->
|
||||
<h:form id="formUpload">
|
||||
<p:dialog id="uploadDialog"
|
||||
widgetVar="uploadDialog"
|
||||
header="Télécharger des Documents"
|
||||
modal="true"
|
||||
resizable="false"
|
||||
style="width: 90vw; max-width: 700px;">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="dossierDestination" value="Dossier de destination" />
|
||||
<p:selectOneMenu id="dossierDestination" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Documents Personnels" itemValue="personnel" />
|
||||
<f:selectItem itemLabel="Certificats" itemValue="certificats" />
|
||||
<f:selectItem itemLabel="Formations" itemValue="formations" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="fichierUpload" value="Fichier" />
|
||||
<p:fileUpload id="fichierUpload"
|
||||
mode="advanced"
|
||||
multiple="true"
|
||||
uploadLabel="Télécharger"
|
||||
cancelLabel="Annuler"
|
||||
chooseLabel="Choisir les fichiers"
|
||||
sizeLimit="10485760"
|
||||
allowTypes="/(\.|\/)(gif|jpe?g|png|pdf|docx?|xlsx?|pptx?)$/" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex justify-content-end gap-2">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('uploadDialog').hide();"
|
||||
type="button" />
|
||||
<p:commandButton value="Télécharger"
|
||||
icon="pi pi-upload"
|
||||
styleClass="p-button-primary"
|
||||
action="#{personnelBean.actualiser}" />
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,374 @@
|
||||
<!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:param name="page" value="#{personnelBean}"/>
|
||||
<ui:define name="title">Mes Favoris - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-star-fill text-yellow-500 mr-3"></i>
|
||||
Mes Favoris
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Accédez rapidement à vos pages, documents et fonctionnalités préférés
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Organiser"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-sort" />
|
||||
<p:commandButton value="Tout nettoyer"
|
||||
styleClass="p-button-secondary"
|
||||
icon="pi pi-trash"
|
||||
action="#{favorisBean.nettoyerTousFavoris}"
|
||||
update="@form"
|
||||
process="@this" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques favoris -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-yellow-500 mb-2">#{favorisBean.totalFavoris}</div>
|
||||
<div class="text-900 font-semibold mb-1">Favoris</div>
|
||||
<div class="text-600 text-sm">Total</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">#{favorisBean.totalPages}</div>
|
||||
<div class="text-900 font-semibold mb-1">Pages</div>
|
||||
<div class="text-600 text-sm">Fonctionnalités</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">#{favorisBean.totalDocuments}</div>
|
||||
<div class="text-900 font-semibold mb-1">Documents</div>
|
||||
<div class="text-600 text-sm">Fichiers</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 border-round p-4 text-center" style="min-height: 9rem">
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">#{favorisBean.totalContacts}</div>
|
||||
<div class="text-900 font-semibold mb-1">Contacts</div>
|
||||
<div class="text-600 text-sm">Personnes</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Accès rapide favoris -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-bolt mr-2"></i>
|
||||
Accès Rapide
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{favorisBean.pagesFavorites}" var="page" varStatus="status">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-#{page.couleur}-50 hover:surface-#{page.couleur}-100 border-round p-4 cursor-pointer transition-duration-200 border-2 border-#{page.couleur}-500">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<i class="pi #{page.icon} text-#{page.couleur}-600 text-2xl"></i>
|
||||
<p:tag value="#{page.estPlusUtilise ? 'PLUS UTILISÉ' : ''}" severity="info" styleClass="text-xs" rendered="#{page.estPlusUtilise}" />
|
||||
<i class="pi pi-star-fill text-yellow-500" rendered="#{!page.estPlusUtilise}"></i>
|
||||
</div>
|
||||
<h6 class="text-#{page.couleur}-800 font-bold mb-2">#{page.titre}</h6>
|
||||
<p class="text-#{page.couleur}-600 text-sm mb-2">#{page.description}</p>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-clock text-#{page.couleur}-500"></i>
|
||||
<span class="text-#{page.couleur}-600 text-xs">#{page.derniereVisite}</span>
|
||||
</div>
|
||||
<div class="flex justify-content-end mt-2">
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="p-button-text p-button-sm p-button-rounded"
|
||||
title="Retirer des favoris"
|
||||
action="#{favorisBean.retirerPageFavorite(page.id)}"
|
||||
update="@form"
|
||||
process="@this" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<!-- Favori 2 -->
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-green-50 hover:surface-green-100 border-round p-4 cursor-pointer transition-duration-200 border-2 border-green-500">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<i class="pi pi-calendar text-green-600 text-2xl"></i>
|
||||
<i class="pi pi-star-fill text-yellow-500"></i>
|
||||
</div>
|
||||
<h6 class="text-green-800 font-bold mb-2">Mon Agenda</h6>
|
||||
<p class="text-green-600 text-sm mb-2">Planning et événements personnels</p>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-clock text-green-500"></i>
|
||||
<span class="text-green-600 text-xs">Utilisé il y a 2h</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Favori 3 -->
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-purple-50 hover:surface-purple-100 border-round p-4 cursor-pointer transition-duration-200 border-2 border-purple-500">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<i class="pi pi-users text-purple-600 text-2xl"></i>
|
||||
<i class="pi pi-star-fill text-yellow-500"></i>
|
||||
</div>
|
||||
<h6 class="text-purple-800 font-bold mb-2">Liste des Membres</h6>
|
||||
<p class="text-purple-600 text-sm mb-2">Annuaire et contacts membres</p>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-clock text-purple-500"></i>
|
||||
<span class="text-purple-600 text-xs">Utilisé hier</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Favori 4 -->
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-orange-50 hover:surface-orange-100 border-round p-4 cursor-pointer transition-duration-200 border-2 border-orange-500">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<i class="pi pi-dollar text-orange-600 text-2xl"></i>
|
||||
<i class="pi pi-star-fill text-yellow-500"></i>
|
||||
</div>
|
||||
<h6 class="text-orange-800 font-bold mb-2">Cotisations</h6>
|
||||
<p class="text-orange-600 text-sm mb-2">Paiements et historique</p>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi pi-clock text-orange-500"></i>
|
||||
<span class="text-orange-600 text-xs">Utilisé il y a 3 jours</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pages favorites -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-window-maximize mr-2"></i>
|
||||
Pages Favorites
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{favorisBean.pagesFavorites}" var="page" varStatus="status">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="pi #{page.icon} text-#{page.couleur}-500 text-xl"></i>
|
||||
<h6 class="text-900 font-semibold mb-0">#{page.titre}</h6>
|
||||
</div>
|
||||
<div class="flex gap-1">
|
||||
<i class="pi pi-star-fill text-yellow-500"></i>
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="p-button-text p-button-sm p-button-rounded"
|
||||
title="Retirer des favoris"
|
||||
action="#{favorisBean.retirerPageFavorite(page.id)}"
|
||||
update="@form"
|
||||
process="@this" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">#{page.description}</p>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<p:tag value="#{page.categorie}" severity="success" styleClass="text-xs" />
|
||||
<span class="text-500 text-xs">#{page.nbVisites} visite#{page.nbVisites > 1 ? 's' : ''} cette semaine</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<p:commandButton value="Voir toutes les pages favorites"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-eye" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Documents favoris -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-file mr-2"></i>
|
||||
Documents Favoris
|
||||
</h4>
|
||||
|
||||
<ui:repeat value="#{favorisBean.documentsFavoris}" var="doc">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 mb-3 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-red-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-file-#{doc.type == 'PDF' ? 'pdf' : doc.type == 'XLSX' ? 'excel' : 'file'} text-red-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#{doc.nom}</h6>
|
||||
<div class="flex align-items-center gap-3 mb-1">
|
||||
<span class="text-600 text-sm">#{doc.tailleFormatee}</span>
|
||||
<span class="text-600 text-sm">Ajouté aux favoris le #{doc.dateAjout}</span>
|
||||
<p:tag value="#{doc.categorie}" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
<p class="text-700 text-sm mb-0">#{doc.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<i class="pi pi-star-fill text-yellow-500 text-xl"></i>
|
||||
<p:commandButton icon="pi pi-download"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
title="Télécharger" />
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="p-button-text p-button-sm"
|
||||
title="Retirer des favoris"
|
||||
action="#{favorisBean.retirerDocumentFavorite(doc.id)}"
|
||||
update="@form"
|
||||
process="@this" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contacts favoris -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-users mr-2"></i>
|
||||
Contacts Favoris
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{favorisBean.contactsFavoris}" var="contact">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<div class="w-3rem h-3rem border-circle bg-blue-100 flex align-items-center justify-content-center">
|
||||
<i class="pi pi-user text-blue-600 text-xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">#{contact.nom}</h6>
|
||||
<p class="text-600 text-sm mb-0">#{contact.fonction}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<i class="pi pi-star-fill text-yellow-500"></i>
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="p-button-text p-button-sm"
|
||||
title="Retirer des favoris"
|
||||
action="#{favorisBean.retirerContactFavorite(contact.id)}"
|
||||
update="@form"
|
||||
process="@this" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex align-items-center gap-3">
|
||||
<span class="text-600 text-sm">#{contact.email}</span>
|
||||
<p:tag value="#{contact.categorie}" severity="warning" styleClass="text-xs" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Raccourcis personnalisés -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-link mr-2"></i>
|
||||
Raccourcis Personnalisés
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{favorisBean.raccourcis}" var="racc">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<i class="pi #{racc.icon} text-#{racc.couleur}-500 text-2xl"></i>
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="p-button-text p-button-sm p-button-rounded"
|
||||
title="Supprimer"
|
||||
action="#{favorisBean.supprimerRaccourci(racc.id)}"
|
||||
update="@form"
|
||||
process="@this" />
|
||||
</div>
|
||||
<h6 class="text-900 font-semibold mb-2">#{racc.titre}</h6>
|
||||
<p class="text-600 text-sm mb-3">#{racc.description}</p>
|
||||
<p:commandButton value="Accéder"
|
||||
styleClass="p-button-outlined p-button-sm w-full"
|
||||
icon="pi pi-external-link"
|
||||
onclick="window.location.href='#{racc.url}'; return false;" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<!-- Ajouter nouveau raccourci -->
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200 border-dashed border-primary">
|
||||
<i class="pi pi-plus-circle text-primary text-3xl mb-3"></i>
|
||||
<h6 class="text-primary font-semibold mb-2">Ajouter</h6>
|
||||
<p class="text-600 text-sm mb-3">Créer un nouveau raccourci</p>
|
||||
<p:commandButton value="Créer"
|
||||
styleClass="p-button-primary p-button-sm w-full"
|
||||
icon="pi pi-plus" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Conseils d'utilisation -->
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-4 mt-4">
|
||||
<h6 class="text-blue-800 font-semibold mb-2">
|
||||
<i class="pi pi-info-circle mr-2"></i>Conseils d'utilisation
|
||||
</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-angle-right text-blue-500 mr-2 mt-1"></i>
|
||||
<span class="text-blue-700 text-sm">Cliquez sur l'étoile ⭐ à côté des éléments pour les ajouter aux favoris</span>
|
||||
</li>
|
||||
<li class="flex align-items-start mb-2">
|
||||
<i class="pi pi-angle-right text-blue-500 mr-2 mt-1"></i>
|
||||
<span class="text-blue-700 text-sm">Organisez vos favoris par catégorie pour un accès plus rapide</span>
|
||||
</li>
|
||||
<li class="flex align-items-start">
|
||||
<i class="pi pi-angle-right text-blue-500 mr-2 mt-1"></i>
|
||||
<span class="text-blue-700 text-sm">Créez des raccourcis personnalisés vers vos actions les plus fréquentes</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,99 @@
|
||||
<!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:param name="page" value="#{personnelBean}"/>
|
||||
<ui:define name="title">Mes Notifications - 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-bell text-orange-500" />
|
||||
<ui:param name="title" value="Mes Notifications" />
|
||||
<ui:param name="description" value="Gérez vos notifications et restez informé des événements importants" />
|
||||
<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="Marquer toutes comme lues" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Paramètres" />
|
||||
<ui:param name="icon" value="pi pi-cog" />
|
||||
<ui:param name="outcome" value="/pages/secure/personnel/parametres" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques notifications -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.notifications != null ? personnelBean.notifications.stream().filter(n -> !n.lue).count() : 0}" />
|
||||
<ui:param name="label" value="Non Lues" />
|
||||
<ui:param name="subLabel" value="Nouvelles" />
|
||||
<ui:param name="icon" value="pi pi-bell" />
|
||||
<ui:param name="bgColor" value="red" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.notifications != null ? personnelBean.notifications.size() : 0}" />
|
||||
<ui:param name="label" value="Total" />
|
||||
<ui:param name="subLabel" value="Notifications" />
|
||||
<ui:param name="icon" value="pi pi-inbox" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Liste des notifications -->
|
||||
<div class="card">
|
||||
<h5>Notifications Récentes</h5>
|
||||
|
||||
<p:dataTable value="#{personnelBean.notifications}" var="notification"
|
||||
emptyMessage="Aucune notification"
|
||||
styleClass="p-datatable-sm">
|
||||
|
||||
<p:column headerText="Titre">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<div class="w-1rem h-1rem border-circle"
|
||||
styleClass="#{notification.lue ? 'bg-gray-300' : 'bg-blue-500'}"></div>
|
||||
<span class="font-semibold">#{notification.titre}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Message">
|
||||
<span>#{notification.message}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date">
|
||||
<span>#{notification.dateCreation}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="#{notification.lue ? 'Lue' : 'Non lue'}"
|
||||
severity="#{notification.lue ? 'success' : 'warning'}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" styleClass="text-center">
|
||||
<div class="flex justify-content-center gap-1">
|
||||
<p:commandButton icon="pi pi-check"
|
||||
title="Marquer comme lue"
|
||||
styleClass="p-button-sm p-button-rounded p-button-success"
|
||||
rendered="#{!notification.lue}" />
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
title="Supprimer"
|
||||
styleClass="p-button-sm p-button-rounded p-button-danger" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,704 @@
|
||||
<!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:param name="page" value="#{personnelBean}"/>
|
||||
<ui:define name="title">Paramètres Compte - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-shield text-red-500 mr-3"></i>
|
||||
Paramètres de Compte
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Gérez la sécurité, la confidentialité et les paramètres avancés de votre compte
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Sauvegarder"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-save" />
|
||||
<p:commandButton value="Exporter mes données"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-download" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statut sécurité -->
|
||||
<div class="surface-green-50 border-left-3 border-green-500 p-4">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<i class="pi pi-shield text-green-600 text-2xl"></i>
|
||||
<div>
|
||||
<h6 class="text-green-800 font-semibold mb-1">Compte sécurisé</h6>
|
||||
<p class="text-green-700 text-sm mb-0">
|
||||
Votre compte respecte toutes les bonnes pratiques de sécurité. Score: #{parametresBean.scoreSecurite}/100
|
||||
</p>
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
<p:tag value="EXCELLENT" severity="success" styleClass="text-sm" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Onglets de paramètres -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<p:tabView styleClass="w-full">
|
||||
<!-- Onglet Sécurité -->
|
||||
<p:tab title="Sécurité">
|
||||
<div class="grid">
|
||||
<!-- Mot de passe -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-key text-blue-500 mr-2"></i>
|
||||
Mot de Passe
|
||||
</h6>
|
||||
|
||||
<h:form id="passwordForm">
|
||||
<div class="field">
|
||||
<label for="currentPassword" class="block text-900 font-semibold mb-2">Mot de passe actuel *</label>
|
||||
<p:password id="currentPassword"
|
||||
feedback="false"
|
||||
toggleMask="true"
|
||||
placeholder="Saisissez votre mot de passe actuel"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="newPassword" class="block text-900 font-semibold mb-2">Nouveau mot de passe *</label>
|
||||
<p:password id="newPassword"
|
||||
feedback="true"
|
||||
toggleMask="true"
|
||||
placeholder="Minimum 8 caractères"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="confirmPassword" class="block text-900 font-semibold mb-2">Confirmer le mot de passe *</label>
|
||||
<p:password id="confirmPassword"
|
||||
feedback="false"
|
||||
toggleMask="true"
|
||||
placeholder="Confirmez votre nouveau mot de passe"
|
||||
styleClass="w-full" />
|
||||
</div>
|
||||
|
||||
<div class="surface-blue-50 border-round p-3 mb-3">
|
||||
<h6 class="text-blue-800 font-semibold mb-2">Critères de sécurité</h6>
|
||||
<ul class="list-none p-0 m-0">
|
||||
<li class="flex align-items-center mb-1">
|
||||
<i class="pi pi-check-circle text-green-500 mr-2"></i>
|
||||
<span class="text-blue-700 text-sm">Au moins 8 caractères</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-1">
|
||||
<i class="pi pi-times-circle text-red-500 mr-2"></i>
|
||||
<span class="text-blue-700 text-sm">Une majuscule</span>
|
||||
</li>
|
||||
<li class="flex align-items-center mb-1">
|
||||
<i class="pi pi-check-circle text-green-500 mr-2"></i>
|
||||
<span class="text-blue-700 text-sm">Un chiffre</span>
|
||||
</li>
|
||||
<li class="flex align-items-center">
|
||||
<i class="pi pi-times-circle text-red-500 mr-2"></i>
|
||||
<span class="text-blue-700 text-sm">Un caractère spécial</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Modifier le mot de passe"
|
||||
styleClass="p-button-primary w-full"
|
||||
icon="pi pi-save" />
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Authentification à deux facteurs -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-mobile text-green-500 mr-2"></i>
|
||||
Authentification à Deux Facteurs (2FA)
|
||||
</h6>
|
||||
|
||||
<div class="surface-green-50 border-left-3 border-green-500 p-3 mb-4">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-green-800 font-semibold mb-1">2FA Activée</h6>
|
||||
<p class="text-green-700 text-sm mb-0">Votre compte est protégé par l'authentification à deux facteurs</p>
|
||||
</div>
|
||||
<p:inputSwitch value="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<h6 class="text-900 font-semibold mb-2">Méthode configurée</h6>
|
||||
<div class="surface-white border-round p-3 border-1 border-200">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<i class="pi pi-mobile text-blue-500 text-xl"></i>
|
||||
<div>
|
||||
<div class="text-900 font-semibold text-sm">Application Authenticator</div>
|
||||
<div class="text-600 text-xs">Google Authenticator, Authy, etc.</div>
|
||||
</div>
|
||||
<p:tag value="ACTIVE" severity="success" styleClass="text-xs ml-auto" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<div class="col-6">
|
||||
<p:commandButton value="Reconfigurer"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-cog" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p:commandButton value="Codes de secours"
|
||||
styleClass="p-button-secondary w-full"
|
||||
icon="pi pi-key" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sessions actives -->
|
||||
<div class="col-12">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-desktop text-purple-500 mr-2"></i>
|
||||
Sessions Actives
|
||||
</h6>
|
||||
|
||||
<!-- Session actuelle -->
|
||||
<div class="surface-white border-round p-4 mb-3 border-2 border-primary">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<i class="pi pi-desktop text-primary text-2xl"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Session Actuelle</h6>
|
||||
<div class="text-600 text-sm mb-1">Chrome 120.0 sur Windows 11</div>
|
||||
<div class="text-500 text-xs">IP: 192.168.1.45 • Dakar, Sénégal</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p:tag value="ACTIVE" severity="success" styleClass="text-xs mb-2" />
|
||||
<div class="text-600 text-xs">Connecté depuis 2h</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Autres sessions -->
|
||||
<div class="surface-white border-round p-4 mb-3">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<i class="pi pi-mobile text-blue-500 text-2xl"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">iPhone 14</h6>
|
||||
<div class="text-600 text-sm mb-1">Safari Mobile</div>
|
||||
<div class="text-500 text-xs">IP: 41.82.45.123 • Dernière activité: il y a 3h</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p:commandButton value="Déconnecter"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-sign-out" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-white border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center gap-3">
|
||||
<i class="pi pi-tablet text-green-500 text-2xl"></i>
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">iPad Pro</h6>
|
||||
<div class="text-600 text-sm mb-1">Safari</div>
|
||||
<div class="text-500 text-xs">IP: 197.25.78.156 • Dernière activité: il y a 1 jour</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p:commandButton value="Déconnecter"
|
||||
styleClass="p-button-outlined p-button-sm"
|
||||
icon="pi pi-sign-out" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<p:commandButton value="Déconnecter toutes les autres sessions"
|
||||
styleClass="p-button-danger"
|
||||
icon="pi pi-power-off" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Confidentialité -->
|
||||
<p:tab title="Confidentialité">
|
||||
<div class="grid">
|
||||
<!-- Visibilité du profil -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-eye text-blue-500 mr-2"></i>
|
||||
Visibilité du Profil
|
||||
</h6>
|
||||
|
||||
<h:form id="visibiliteForm">
|
||||
<div class="field-radiobutton mb-4">
|
||||
<p:radioButton id="visiPublic" name="visibilite" value="public" />
|
||||
<label for="visiPublic" class="ml-2">
|
||||
<div class="surface-white border-round p-3 cursor-pointer border-1 border-200">
|
||||
<h6 class="text-900 font-semibold mb-1">Public</h6>
|
||||
<p class="text-600 text-sm mb-0">
|
||||
Votre profil est visible par tous les membres de l'association
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-radiobutton mb-4">
|
||||
<p:radioButton id="visiLimite" name="visibilite" value="limite" />
|
||||
<label for="visiLimite" class="ml-2">
|
||||
<div class="surface-white border-round p-3 cursor-pointer border-1 border-200">
|
||||
<h6 class="text-900 font-semibold mb-1">Limité</h6>
|
||||
<p class="text-600 text-sm mb-0">
|
||||
Visible uniquement par les administrateurs et organisateurs
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-radiobutton">
|
||||
<p:radioButton id="visiPrive" name="visibilite" value="prive" />
|
||||
<label for="visiPrive" class="ml-2">
|
||||
<div class="surface-white border-round p-3 cursor-pointer border-1 border-200">
|
||||
<h6 class="text-900 font-semibold mb-1">Privé</h6>
|
||||
<p class="text-600 text-sm mb-0">
|
||||
Votre profil n'est visible que par vous-même
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Partage des données -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-share-alt text-green-500 mr-2"></i>
|
||||
Partage des Données
|
||||
</h6>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="shareEmail" value="true" />
|
||||
<label for="shareEmail" class="ml-2">
|
||||
<div class="text-900 font-semibold">Adresse email</div>
|
||||
<div class="text-600 text-sm">Permettre aux autres membres de voir votre email</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="sharePhone" />
|
||||
<label for="sharePhone" class="ml-2">
|
||||
<div class="text-900 font-semibold">Numéro de téléphone</div>
|
||||
<div class="text-600 text-sm">Afficher votre numéro dans l'annuaire</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="shareActivities" value="true" />
|
||||
<label for="shareActivities" class="ml-2">
|
||||
<div class="text-900 font-semibold">Activités publiques</div>
|
||||
<div class="text-600 text-sm">Participation aux événements et formations</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="shareStats" />
|
||||
<label for="shareStats" class="ml-2">
|
||||
<div class="text-900 font-semibold">Statistiques anonymes</div>
|
||||
<div class="text-600 text-sm">Contribuer aux statistiques générales</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="surface-orange-50 border-left-3 border-orange-500 p-3">
|
||||
<h6 class="text-orange-800 font-semibold mb-1">
|
||||
<i class="pi pi-info-circle mr-2"></i>Information
|
||||
</h6>
|
||||
<p class="text-orange-700 text-sm mb-0">
|
||||
Ces paramètres n'affectent pas les données nécessaires au fonctionnement de l'association.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Données personnelles -->
|
||||
<div class="col-12">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-database text-purple-500 mr-2"></i>
|
||||
Gestion des Données Personnelles
|
||||
</h6>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4 text-center">
|
||||
<i class="pi pi-download text-blue-500 text-3xl mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Exporter mes données</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Téléchargez toutes vos données personnelles au format JSON
|
||||
</p>
|
||||
<p:commandButton value="Télécharger"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-download" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4 text-center">
|
||||
<i class="pi pi-refresh text-green-500 text-3xl mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Actualiser le consentement</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Revoir et mettre à jour vos consentements RGPD
|
||||
</p>
|
||||
<p:commandButton value="Actualiser"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-refresh" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4 text-center">
|
||||
<i class="pi pi-trash text-red-500 text-3xl mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Supprimer mon compte</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Suppression définitive de toutes vos données
|
||||
</p>
|
||||
<p:commandButton value="Supprimer"
|
||||
styleClass="p-button-danger w-full"
|
||||
icon="pi pi-trash" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Préférences -->
|
||||
<p:tab title="Préférences">
|
||||
<div class="grid">
|
||||
<!-- Préférences de communication -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-envelope text-blue-500 mr-2"></i>
|
||||
Communications
|
||||
</h6>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="emailNewsletter" value="true" />
|
||||
<label for="emailNewsletter" class="ml-2 text-900">Newsletter hebdomadaire</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="emailEvents" value="true" />
|
||||
<label for="emailEvents" class="ml-2 text-900">Notifications d'événements</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="emailReminders" value="true" />
|
||||
<label for="emailReminders" class="ml-2 text-900">Rappels de cotisations</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="emailPromo" />
|
||||
<label for="emailPromo" class="ml-2 text-900">Offres promotionnelles</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="smsUrgent" />
|
||||
<label for="smsUrgent" class="ml-2 text-900">SMS pour urgences uniquement</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Paramètres d'affichage -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-desktop text-green-500 mr-2"></i>
|
||||
Affichage
|
||||
</h6>
|
||||
|
||||
<div class="field">
|
||||
<label for="themeChoice" class="block text-900 font-semibold mb-2">Thème</label>
|
||||
<p:selectOneMenu id="themeChoice" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Clair (par défaut)" itemValue="light" />
|
||||
<f:selectItem itemLabel="Sombre" itemValue="dark" />
|
||||
<f:selectItem itemLabel="Automatique" itemValue="auto" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="languageChoice" class="block text-900 font-semibold mb-2">Langue</label>
|
||||
<p:selectOneMenu id="languageChoice" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Français" itemValue="fr" />
|
||||
<f:selectItem itemLabel="English" itemValue="en" />
|
||||
<f:selectItem itemLabel="العربية" itemValue="ar" />
|
||||
<f:selectItem itemLabel="Wolof" itemValue="wo" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="timezoneChoice" class="block text-900 font-semibold mb-2">Fuseau horaire</label>
|
||||
<p:selectOneMenu id="timezoneChoice" styleClass="w-full">
|
||||
<f:selectItem itemLabel="GMT (Dakar, Casablanca)" itemValue="GMT" />
|
||||
<f:selectItem itemLabel="GMT+1 (Paris, Madrid)" itemValue="CET" />
|
||||
<f:selectItem itemLabel="GMT-5 (New York)" itemValue="EST" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="animationsEnabled" value="true" />
|
||||
<label for="animationsEnabled" class="ml-2 text-900">Activer les animations</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sauvegarde et synchronisation -->
|
||||
<div class="col-12">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-cloud text-blue-500 mr-2"></i>
|
||||
Sauvegarde et Synchronisation
|
||||
</h6>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h6 class="text-900 font-semibold mb-0">Sauvegarde automatique</h6>
|
||||
<p:inputSwitch value="true" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">
|
||||
Sauvegarde quotidienne de vos préférences et données
|
||||
</p>
|
||||
<div class="text-500 text-xs">Dernière sauvegarde: il y a 2h</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h6 class="text-900 font-semibold mb-0">Sync calendriers</h6>
|
||||
<p:inputSwitch value="true" />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">
|
||||
Synchronisation avec Google Calendar et Outlook
|
||||
</p>
|
||||
<div class="text-500 text-xs">2 calendriers connectés</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h6 class="text-900 font-semibold mb-0">Mode hors ligne</h6>
|
||||
<p:inputSwitch />
|
||||
</div>
|
||||
<p class="text-600 text-sm mb-2">
|
||||
Accès limité aux fonctionnalités sans connexion
|
||||
</p>
|
||||
<div class="text-500 text-xs">Cache: 25 MB</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
<!-- Onglet Avancé -->
|
||||
<p:tab title="Avancé">
|
||||
<div class="grid">
|
||||
<!-- API et intégrations -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-cog text-purple-500 mr-2"></i>
|
||||
API et Intégrations
|
||||
</h6>
|
||||
|
||||
<div class="surface-white border-round p-3 mb-3">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<h6 class="text-900 font-semibold mb-0">Clé API personnelle</h6>
|
||||
<p:tag value="ACTIVE" severity="success" styleClass="text-xs" />
|
||||
</div>
|
||||
<div class="text-600 text-sm mb-2">Utilisée pour les intégrations tierces</div>
|
||||
<div class="surface-100 border-round p-2 font-mono text-sm">
|
||||
uk_1a2b3c4d5e6f7g8h9i0j...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<div class="col-6">
|
||||
<p:commandButton value="Regénérer"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-refresh" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p:commandButton value="Révoquer"
|
||||
styleClass="p-button-danger w-full"
|
||||
icon="pi pi-times" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-orange-50 border-left-3 border-orange-500 p-3 mt-3">
|
||||
<h6 class="text-orange-800 font-semibold mb-1">
|
||||
<i class="pi pi-exclamation-triangle mr-2"></i>Sécurité
|
||||
</h6>
|
||||
<p class="text-orange-700 text-sm mb-0">
|
||||
Ne partagez jamais votre clé API. Changez-la si elle est compromise.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logs d'activité -->
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4 h-full">
|
||||
<h6 class="text-900 font-semibold mb-4">
|
||||
<i class="pi pi-file-o text-orange-500 mr-2"></i>
|
||||
Logs d'Activité
|
||||
</h6>
|
||||
|
||||
<div class="field">
|
||||
<label for="logLevel" class="block text-900 font-semibold mb-2">Niveau de logging</label>
|
||||
<p:selectOneMenu id="logLevel" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Minimal (erreurs uniquement)" itemValue="error" />
|
||||
<f:selectItem itemLabel="Standard (recommandé)" itemValue="info" />
|
||||
<f:selectItem itemLabel="Détaillé (debug)" itemValue="debug" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="logRetention" class="block text-900 font-semibold mb-2">Durée de conservation</label>
|
||||
<p:selectOneMenu id="logRetention" styleClass="w-full">
|
||||
<f:selectItem itemLabel="30 jours" itemValue="30" />
|
||||
<f:selectItem itemLabel="90 jours" itemValue="90" />
|
||||
<f:selectItem itemLabel="1 an" itemValue="365" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="downloadLogs" />
|
||||
<label for="downloadLogs" class="ml-2 text-900">Permettre le téléchargement des logs</label>
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Télécharger mes logs"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-download" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zone dangereuse -->
|
||||
<div class="col-12">
|
||||
<div class="surface-red-50 border-round p-4 border-2 border-red-500">
|
||||
<h6 class="text-red-800 font-semibold mb-4">
|
||||
<i class="pi pi-exclamation-triangle text-red-600 mr-2"></i>
|
||||
Zone Dangereuse
|
||||
</h6>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-2">Réinitialiser les préférences</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Remet tous vos paramètres aux valeurs par défaut
|
||||
</p>
|
||||
<p:commandButton value="Réinitialiser"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-refresh" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-2">Désactiver le compte</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Suspend temporairement votre accès
|
||||
</p>
|
||||
<p:commandButton value="Désactiver"
|
||||
styleClass="p-button-warning w-full"
|
||||
icon="pi pi-pause" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-white border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-2">Supprimer le compte</h6>
|
||||
<p class="text-600 text-sm mb-3">
|
||||
Action irréversible. Toutes vos données seront perdues
|
||||
</p>
|
||||
<p:commandButton value="Supprimer"
|
||||
styleClass="p-button-danger w-full"
|
||||
icon="pi pi-trash" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions globales -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Sauvegarder toutes les modifications</h6>
|
||||
<p class="text-600 text-sm mb-0">
|
||||
Les changements seront appliqués immédiatement à votre compte
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-times" />
|
||||
<p:commandButton value="Enregistrer tous les paramètres"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-save" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,510 @@
|
||||
<!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:param name="page" value="#{personnelBean}"/>
|
||||
<ui:define name="title">Mes Préférences - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="ui-fluid">
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-4xl mb-2">
|
||||
<i class="pi pi-cog text-blue-500 mr-3"></i>
|
||||
Mes Préférences
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-0">
|
||||
Personnalisez votre expérience UnionFlow selon vos besoins
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Réinitialiser"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-refresh"
|
||||
action="#{preferencesBean.reinitialiserPreferences}"
|
||||
update="@form" />
|
||||
<p:commandButton value="Enregistrer"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-save"
|
||||
action="#{preferencesBean.sauvegarderPreferences}"
|
||||
update="@form" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Raccourcis préférences -->
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-palette text-3xl text-purple-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Apparence</h6>
|
||||
<p class="text-600 text-sm mb-0">Thème, couleurs, mise en page</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-bell text-3xl text-orange-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Notifications</h6>
|
||||
<p class="text-600 text-sm mb-0">Alertes, emails, SMS</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 hover:surface-200 border-round p-4 text-center cursor-pointer transition-duration-200">
|
||||
<i class="pi pi-shield text-3xl text-green-500 mb-3"></i>
|
||||
<h6 class="text-900 font-semibold mb-2">Confidentialité</h6>
|
||||
<p class="text-600 text-sm mb-0">Sécurité, permissions</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Préférences d'apparence -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-palette text-purple-500 mr-2"></i>
|
||||
Apparence et Interface
|
||||
</h4>
|
||||
|
||||
<h:form id="apparenceForm">
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">Thème</h6>
|
||||
<p:selectOneRadio id="theme" value="#{preferencesBean.theme}" layout="custom">
|
||||
<f:selectItem itemLabel="Clair" itemValue="light" />
|
||||
<f:selectItem itemLabel="Sombre" itemValue="dark" />
|
||||
</p:selectOneRadio>
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<div class="field-radiobutton">
|
||||
<p:radioButton id="themeLight" for="theme" itemIndex="0" />
|
||||
<label for="themeLight" class="ml-2">
|
||||
<div class="surface-100 border-round p-3 cursor-pointer">
|
||||
<i class="pi pi-sun text-yellow-500 text-xl mb-2"></i>
|
||||
<div class="text-900 font-semibold text-sm">Clair</div>
|
||||
<div class="text-600 text-xs">Mode jour</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="field-radiobutton">
|
||||
<p:radioButton id="themeDark" for="theme" itemIndex="1" />
|
||||
<label for="themeDark" class="ml-2">
|
||||
<div class="surface-800 border-round p-3 cursor-pointer">
|
||||
<i class="pi pi-moon text-blue-400 text-xl mb-2"></i>
|
||||
<div class="text-white font-semibold text-sm">Sombre</div>
|
||||
<div class="text-300 text-xs">Mode nuit</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">Couleur d'accent</h6>
|
||||
<p:selectOneRadio id="accentColor" value="#{preferencesBean.couleurAccent}" layout="custom">
|
||||
<f:selectItem itemLabel="Bleu" itemValue="blue" />
|
||||
<f:selectItem itemLabel="Vert" itemValue="green" />
|
||||
<f:selectItem itemLabel="Violet" itemValue="purple" />
|
||||
<f:selectItem itemLabel="Orange" itemValue="orange" />
|
||||
</p:selectOneRadio>
|
||||
<div class="grid">
|
||||
<div class="col-3">
|
||||
<div class="field-radiobutton">
|
||||
<p:radioButton id="colorBlue" for="accentColor" itemIndex="0" />
|
||||
<label for="colorBlue" class="w-2rem h-2rem border-circle bg-blue-500 cursor-pointer block ml-2"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="field-radiobutton">
|
||||
<p:radioButton id="colorGreen" for="accentColor" itemIndex="1" />
|
||||
<label for="colorGreen" class="w-2rem h-2rem border-circle bg-green-500 cursor-pointer block ml-2"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="field-radiobutton">
|
||||
<p:radioButton id="colorPurple" for="accentColor" itemIndex="2" />
|
||||
<label for="colorPurple" class="w-2rem h-2rem border-circle bg-purple-500 cursor-pointer block ml-2"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="field-radiobutton">
|
||||
<p:radioButton id="colorOrange" for="accentColor" itemIndex="3" />
|
||||
<label for="colorOrange" class="w-2rem h-2rem border-circle bg-orange-500 cursor-pointer block ml-2"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="field">
|
||||
<label for="langue" class="block text-900 font-semibold mb-2">Langue</label>
|
||||
<p:selectOneMenu id="langue" value="#{preferencesBean.langue}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Français" itemValue="fr" />
|
||||
<f:selectItem itemLabel="English" itemValue="en" />
|
||||
<f:selectItem itemLabel="العربية" itemValue="ar" />
|
||||
<f:selectItem itemLabel="Wolof" itemValue="wo" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="field">
|
||||
<label for="fuseau" class="block text-900 font-semibold mb-2">Fuseau horaire</label>
|
||||
<p:selectOneMenu id="fuseau" value="#{preferencesBean.fuseauHoraire}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="GMT (Casablanca)" itemValue="GMT" />
|
||||
<f:selectItem itemLabel="GMT+1 (Paris)" itemValue="CET" />
|
||||
<f:selectItem itemLabel="GMT-5 (New York)" itemValue="EST" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="field">
|
||||
<label for="format" class="block text-900 font-semibold mb-2">Format de date</label>
|
||||
<p:selectOneMenu id="format" value="#{preferencesBean.formatDate}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="DD/MM/YYYY" itemValue="dd/mm/yyyy" />
|
||||
<f:selectItem itemLabel="MM/DD/YYYY" itemValue="mm/dd/yyyy" />
|
||||
<f:selectItem itemLabel="YYYY-MM-DD" itemValue="yyyy-mm-dd" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Préférences de notifications -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-bell text-orange-500 mr-2"></i>
|
||||
Notifications et Alertes
|
||||
</h4>
|
||||
|
||||
<h:form id="notificationsForm">
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">
|
||||
<i class="pi pi-desktop mr-2"></i>Notifications navigateur
|
||||
</h6>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="notifEvenements" value="#{preferencesBean.notifEvenements}" />
|
||||
<label for="notifEvenements" class="ml-2 text-900">Nouveaux événements</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="notifMessages" value="#{preferencesBean.notifMessages}" />
|
||||
<label for="notifMessages" class="ml-2 text-900">Messages privés</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="notifCotisations" value="#{preferencesBean.notifCotisations}" />
|
||||
<label for="notifCotisations" class="ml-2 text-900">Rappels cotisations</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="notifSysteme" value="#{preferencesBean.notifSysteme}" />
|
||||
<label for="notifSysteme" class="ml-2 text-900">Mises à jour système</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">
|
||||
<i class="pi pi-envelope mr-2"></i>Notifications email
|
||||
</h6>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="emailQuotidien" value="#{preferencesBean.emailQuotidien}" />
|
||||
<label for="emailQuotidien" class="ml-2 text-900">Résumé quotidien</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="emailHebdo" value="#{preferencesBean.emailHebdo}" />
|
||||
<label for="emailHebdo" class="ml-2 text-900">Newsletter hebdomadaire</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="emailUrgent" value="#{preferencesBean.emailUrgent}" />
|
||||
<label for="emailUrgent" class="ml-2 text-900">Alertes urgentes</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="emailPromo" value="#{preferencesBean.emailPromo}" />
|
||||
<label for="emailPromo" class="ml-2 text-900">Offres promotionnelles</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">
|
||||
<i class="pi pi-mobile mr-2"></i>Notifications SMS
|
||||
</h6>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="smsUrgent" value="#{preferencesBean.smsUrgent}" />
|
||||
<label for="smsUrgent" class="ml-2 text-900">Urgences uniquement</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="smsRappels" value="#{preferencesBean.smsRappels}" />
|
||||
<label for="smsRappels" class="ml-2 text-900">Rappels importants</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="smsEvenements" value="#{preferencesBean.smsEvenements}" />
|
||||
<label for="smsEvenements" class="ml-2 text-900">Événements du jour</label>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="heuresSMS" class="block text-900 font-semibold mb-2">Heures autorisées</label>
|
||||
<p:selectOneMenu id="heuresSMS" value="#{preferencesBean.heuresSMS}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="08h - 20h" itemValue="08-20" />
|
||||
<f:selectItem itemLabel="09h - 18h" itemValue="09-18" />
|
||||
<f:selectItem itemLabel="24h/24" itemValue="00-24" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Préférences de confidentialité -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-shield text-green-500 mr-2"></i>
|
||||
Confidentialité et Sécurité
|
||||
</h4>
|
||||
|
||||
<h:form id="confidentialiteForm">
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">Visibilité du profil</h6>
|
||||
<p:selectOneRadio id="visibilite" value="#{preferencesBean.visibiliteProfil}" layout="custom">
|
||||
<f:selectItem itemLabel="Public" itemValue="publique" />
|
||||
<f:selectItem itemLabel="Limité" itemValue="limitee" />
|
||||
<f:selectItem itemLabel="Privé" itemValue="prive" />
|
||||
</p:selectOneRadio>
|
||||
|
||||
<div class="field-radiobutton mb-3">
|
||||
<p:radioButton id="visibilitePublique" for="visibilite" itemIndex="0" />
|
||||
<label for="visibilitePublique" class="ml-2">
|
||||
<div class="text-900 font-semibold">Public</div>
|
||||
<div class="text-600 text-sm">Visible par tous les membres</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-radiobutton mb-3">
|
||||
<p:radioButton id="visibiliteLimitee" for="visibilite" itemIndex="1" />
|
||||
<label for="visibiliteLimitee" class="ml-2">
|
||||
<div class="text-900 font-semibold">Limité</div>
|
||||
<div class="text-600 text-sm">Visible par les administrateurs</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-radiobutton">
|
||||
<p:radioButton id="visibilitePrive" for="visibilite" itemIndex="2" />
|
||||
<label for="visibilitePrive" class="ml-2">
|
||||
<div class="text-900 font-semibold">Privé</div>
|
||||
<div class="text-600 text-sm">Visible par vous uniquement</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">Paramètres de sécurité</h6>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="doubleAuth" value="#{preferencesBean.doubleAuth}" />
|
||||
<label for="doubleAuth" class="ml-2 text-900">Authentification à deux facteurs</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="connexionSecure" value="#{preferencesBean.connexionSecure}" />
|
||||
<label for="connexionSecure" class="ml-2 text-900">Connexion HTTPS obligatoire</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-3">
|
||||
<p:selectBooleanCheckbox id="deconnexionAuto" value="#{preferencesBean.deconnexionAuto}" />
|
||||
<label for="deconnexionAuto" class="ml-2 text-900">Déconnexion automatique</label>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="dureeSession" class="block text-900 font-semibold mb-2">Durée max session</label>
|
||||
<p:selectOneMenu id="dureeSession" styleClass="w-full">
|
||||
<f:selectItem itemLabel="30 minutes" itemValue="30" />
|
||||
<f:selectItem itemLabel="1 heure" itemValue="60" />
|
||||
<f:selectItem itemLabel="2 heures" itemValue="120" />
|
||||
<f:selectItem itemLabel="4 heures" itemValue="240" />
|
||||
<f:selectItem itemLabel="8 heures" itemValue="480" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Préférences tableau de bord -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-chart-bar text-blue-500 mr-2"></i>
|
||||
Tableau de Bord Personnel
|
||||
</h4>
|
||||
|
||||
<h:form id="dashboardForm">
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">Widgets à afficher</h6>
|
||||
|
||||
<div class="field-checkbox mb-2">
|
||||
<p:selectBooleanCheckbox id="widgetActivites" value="#{preferencesBean.widgetActivites}" />
|
||||
<label for="widgetActivites" class="ml-2 text-900">Activités récentes</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-2">
|
||||
<p:selectBooleanCheckbox id="widgetEvenements" value="#{preferencesBean.widgetEvenements}" />
|
||||
<label for="widgetEvenements" class="ml-2 text-900">Événements à venir</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-2">
|
||||
<p:selectBooleanCheckbox id="widgetCotisations" value="#{preferencesBean.widgetCotisations}" />
|
||||
<label for="widgetCotisations" class="ml-2 text-900">État des cotisations</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-2">
|
||||
<p:selectBooleanCheckbox id="widgetNotifications" value="#{preferencesBean.widgetNotifications}" />
|
||||
<label for="widgetNotifications" class="ml-2 text-900">Notifications récentes</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox mb-2">
|
||||
<p:selectBooleanCheckbox id="widgetStatistiques" value="#{preferencesBean.widgetStatistiques}" />
|
||||
<label for="widgetStatistiques" class="ml-2 text-900">Mes statistiques</label>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="widgetMeteo" value="#{preferencesBean.widgetMeteo}" />
|
||||
<label for="widgetMeteo" class="ml-2 text-900">Météo locale</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-4">
|
||||
<h6 class="text-900 font-semibold mb-3">Configuration d'affichage</h6>
|
||||
|
||||
<div class="field">
|
||||
<label for="layoutDashboard" class="block text-900 font-semibold mb-2">Disposition</label>
|
||||
<p:selectOneMenu id="layoutDashboard" value="#{preferencesBean.layoutDashboard}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Grille 2 colonnes" itemValue="grid-2" />
|
||||
<f:selectItem itemLabel="Grille 3 colonnes" itemValue="grid-3" />
|
||||
<f:selectItem itemLabel="Liste verticale" itemValue="list" />
|
||||
<f:selectItem itemLabel="Compact" itemValue="compact" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="pageAccueil" class="block text-900 font-semibold mb-2">Page d'accueil</label>
|
||||
<p:selectOneMenu id="pageAccueil" value="#{preferencesBean.pageAccueil}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Tableau de bord" itemValue="dashboard" />
|
||||
<f:selectItem itemLabel="Mes activités" itemValue="activites" />
|
||||
<f:selectItem itemLabel="Mon agenda" itemValue="agenda" />
|
||||
<f:selectItem itemLabel="Dernière page visitée" itemValue="last" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="elementsPage" class="block text-900 font-semibold mb-2">Éléments par page</label>
|
||||
<p:selectOneMenu id="elementsPage" value="#{preferencesBean.elementsPage}" styleClass="w-full">
|
||||
<f:selectItem itemLabel="10" itemValue="10" />
|
||||
<f:selectItem itemLabel="25" itemValue="25" />
|
||||
<f:selectItem itemLabel="50" itemValue="50" />
|
||||
<f:selectItem itemLabel="100" itemValue="100" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field-checkbox">
|
||||
<p:selectBooleanCheckbox id="animations" value="#{preferencesBean.animations}" />
|
||||
<label for="animations" class="ml-2 text-900">Activer les animations</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-900 font-semibold mb-1">Enregistrer les modifications</h6>
|
||||
<p class="text-600 text-sm mb-0">Vos préférences seront appliquées immédiatement</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-times" />
|
||||
<p:commandButton value="Réinitialiser par défaut"
|
||||
styleClass="p-button-secondary"
|
||||
icon="pi pi-refresh" />
|
||||
<p:commandButton value="Enregistrer les préférences"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-save" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-blue-50 border-left-3 border-blue-500 p-3 mt-3">
|
||||
<p class="text-blue-700 text-sm mb-0">
|
||||
<i class="pi pi-info-circle mr-2"></i>
|
||||
Certaines modifications nécessiteront une reconnexion pour être appliquées.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,301 @@
|
||||
<!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:param name="page" value="#{personnelBean}"/>
|
||||
<ui:define name="title">Mon Profil - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formProfil">
|
||||
<!-- En-tête profil -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12">
|
||||
<div class="surface-card border-round p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<div class="flex align-items-center gap-4">
|
||||
<div class="w-6rem h-6rem border-circle bg-primary-100 flex align-items-center justify-content-center">
|
||||
<h:graphicImage value="#{personnelBean.membre.photoUrl}"
|
||||
style="width: 100%; height: 100%; object-fit: cover; border-radius: 50%;"
|
||||
rendered="#{personnelBean.membre != null and personnelBean.membre.photoUrl != null}" />
|
||||
<i class="pi pi-user text-primary text-4xl"
|
||||
rendered="#{personnelBean.membre == null or personnelBean.membre.photoUrl == null}"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-900 font-bold text-3xl mb-2">
|
||||
#{personnelBean.membre != null ? personnelBean.membre.nomComplet : 'Chargement...'}
|
||||
</h2>
|
||||
<p class="text-600 text-lg mb-1" rendered="#{personnelBean.membre != null and personnelBean.membre.dateAdhesion != null}">
|
||||
Membre depuis le #{personnelBean.membre.dateAdhesionFormatee}
|
||||
</p>
|
||||
<div class="flex align-items-center gap-2" rendered="#{personnelBean.membre != null}">
|
||||
<p:tag value="#{personnelBean.membre.statut}"
|
||||
severity="#{personnelBean.membre.statutSeverity}"
|
||||
styleClass="text-sm" />
|
||||
<p:tag value="#{personnelBean.membre.typeMembre}"
|
||||
severity="#{personnelBean.membre.typeSeverity}"
|
||||
styleClass="text-sm" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Modifier" />
|
||||
<ui:param name="icon" value="pi pi-pencil" />
|
||||
<ui:param name="onclick" value="PF('modifierProfilDialog').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{personnelBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiques profil -->
|
||||
<div class="grid" rendered="#{personnelBean.statistiques != null}">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.actionsRealisees}" />
|
||||
<ui:param name="label" value="Actions Réalisées" />
|
||||
<ui:param name="subLabel" value="Ce mois-ci" />
|
||||
<ui:param name="icon" value="pi pi-check-circle" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.evenementsParticipes}" />
|
||||
<ui:param name="label" value="Événements" />
|
||||
<ui:param name="subLabel" value="Participés" />
|
||||
<ui:param name="icon" value="pi pi-calendar" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.tauxParticipation}%" />
|
||||
<ui:param name="label" value="Taux Participation" />
|
||||
<ui:param name="subLabel" value="Global" />
|
||||
<ui:param name="icon" value="pi pi-chart-line" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{personnelBean.statistiques.evaluationMoyenne}★" />
|
||||
<ui:param name="label" value="Évaluation" />
|
||||
<ui:param name="subLabel" value="Moyenne" />
|
||||
<ui:param name="icon" value="pi pi-star" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations personnelles -->
|
||||
<div class="grid mb-4" rendered="#{personnelBean.membre != null}">
|
||||
<div class="col-12 lg:col-8">
|
||||
<div class="surface-card border-round p-4 h-full">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-id-card text-primary mr-2"></i>
|
||||
Informations Personnelles
|
||||
</h4>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Nom complet</div>
|
||||
<div class="text-900 font-semibold">#{personnelBean.membre.nomComplet}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Email</div>
|
||||
<div class="text-900 font-semibold">#{personnelBean.membre.email}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Téléphone</div>
|
||||
<div class="text-900 font-semibold">#{personnelBean.membre.telephone}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-6" rendered="#{personnelBean.membre.dateNaissance != null}">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Date de naissance</div>
|
||||
<div class="text-900 font-semibold">#{personnelBean.membre.dateNaissanceFormatee}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" rendered="#{personnelBean.membre.adresse != null}">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Adresse</div>
|
||||
<div class="text-900 font-semibold">#{personnelBean.membre.adresse}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-6" rendered="#{personnelBean.membre.profession != null}">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Profession</div>
|
||||
<div class="text-900 font-semibold">#{personnelBean.membre.profession}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="surface-card border-round p-4 h-full">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-bookmark text-blue-500 mr-2"></i>
|
||||
Adhésion et Statut
|
||||
</h4>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="text-600 text-sm mb-1">Numéro de membre</div>
|
||||
<div class="text-900 font-bold text-lg">#{personnelBean.membre.numeroMembre}</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3" rendered="#{personnelBean.membre.typeMembre != null}">
|
||||
<div class="text-600 text-sm mb-1">Type d'adhésion</div>
|
||||
<div class="text-900 font-semibold">#{personnelBean.membre.typeMembre}</div>
|
||||
</div>
|
||||
|
||||
<div class="surface-100 border-round p-3 mb-3" rendered="#{personnelBean.membre.dateAdhesion != null}">
|
||||
<div class="text-600 text-sm mb-1">Date d'inscription</div>
|
||||
<div class="text-900 font-semibold">#{personnelBean.membre.dateAdhesionFormatee}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Activités récentes -->
|
||||
<div class="grid mb-4">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-card border-round p-4 h-full">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-history text-purple-500 mr-2"></i>
|
||||
Activités Récentes
|
||||
</h4>
|
||||
|
||||
<ui:repeat value="#{personnelBean.activitesRecentes}" var="activite">
|
||||
<div class="surface-100 border-round p-3 mb-3">
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-900 font-semibold text-sm">#{activite.titre}</span>
|
||||
<span class="text-600 text-xs">#{activite.dateHeure}</span>
|
||||
</div>
|
||||
<div class="text-600 text-sm">#{activite.description}</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
|
||||
<div class="text-center text-600 text-sm" rendered="#{empty personnelBean.activitesRecentes}">
|
||||
Aucune activité récente
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="surface-card border-round p-4 h-full">
|
||||
<h4 class="text-900 font-bold mb-4">
|
||||
<i class="pi pi-shield text-orange-500 mr-2"></i>
|
||||
Rôles et Permissions
|
||||
</h4>
|
||||
|
||||
<div class="text-600 text-sm" rendered="#{userSession != null and userSession.roles != null}">
|
||||
<ui:repeat value="#{userSession.roles}" var="role">
|
||||
<div class="mb-2">
|
||||
<p:tag value="#{role}" severity="info" styleClass="text-xs" />
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
<!-- Dialog Modifier Profil -->
|
||||
<p:dialog id="modifierProfilDialog"
|
||||
widgetVar="modifierProfilDialog"
|
||||
header="Modifier Mon Profil"
|
||||
modal="true"
|
||||
width="900"
|
||||
styleClass="surface-0">
|
||||
<h:form id="modifierProfilForm">
|
||||
<div class="ui-fluid">
|
||||
<div class="formgrid grid" rendered="#{personnelBean.membre != null}">
|
||||
<div class="field col-12 lg:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="nom" />
|
||||
<ui:param name="label" value="Nom *" />
|
||||
<ui:param name="value" value="#{personnelBean.membre.nom}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="prenom" />
|
||||
<ui:param name="label" value="Prénom *" />
|
||||
<ui:param name="value" value="#{personnelBean.membre.prenom}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="email" />
|
||||
<ui:param name="label" value="Email *" />
|
||||
<ui:param name="value" value="#{personnelBean.membre.email}" />
|
||||
<ui:param name="required" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="telephone" />
|
||||
<ui:param name="label" value="Téléphone" />
|
||||
<ui:param name="value" value="#{personnelBean.membre.telephone}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-calendar.xhtml">
|
||||
<ui:param name="id" value="dateNaissance" />
|
||||
<ui:param name="label" value="Date de naissance" />
|
||||
<ui:param name="value" value="#{personnelBean.membre.dateNaissance}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<ui:include src="/templates/components/forms/form-field-textarea.xhtml">
|
||||
<ui:param name="id" value="adresse" />
|
||||
<ui:param name="label" value="Adresse" />
|
||||
<ui:param name="value" value="#{personnelBean.membre.adresse}" />
|
||||
<ui:param name="rows" value="3" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="field col-12 lg:col-6">
|
||||
<ui:include src="/templates/components/forms/form-field-text.xhtml">
|
||||
<ui:param name="id" value="profession" />
|
||||
<ui:param name="label" value="Profession" />
|
||||
<ui:param name="value" value="#{personnelBean.membre.profession}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end gap-2 mt-4">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('modifierProfilDialog').hide();"
|
||||
type="button" />
|
||||
<p:commandButton value="Enregistrer"
|
||||
styleClass="p-button-primary"
|
||||
icon="pi pi-save"
|
||||
action="#{personnelBean.mettreAJourProfil}"
|
||||
update="@form :formProfil"
|
||||
onclick="if(!args.validationFailed) PF('modifierProfilDialog').hide();" />
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
241
target/classes/META-INF/resources/pages/secure/profile.xhtml
Normal file
241
target/classes/META-INF/resources/pages/secure/profile.xhtml
Normal file
@@ -0,0 +1,241 @@
|
||||
<!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">Mon Profil - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête du profil -->
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center">
|
||||
<div class="bg-primary text-white border-round flex align-items-center justify-content-center mr-4"
|
||||
style="width: 5rem; height: 5rem; font-size: 2rem; font-weight: bold;">
|
||||
#{userSession.currentUser.initiales}
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="mb-2">#{userSession.currentUser.nomComplet}</h2>
|
||||
<div class="flex align-items-center gap-2 mb-2">
|
||||
<p:tag value="#{userSession.typeCompte}"
|
||||
severity="#{userSession.isSuperAdmin() ? 'danger' : (userSession.isAdmin() ? 'warning' : 'info')}" />
|
||||
<span class="text-600">•</span>
|
||||
<span class="text-600">#{userSession.currentUser.email}</span>
|
||||
</div>
|
||||
<div class="text-600">
|
||||
<i class="pi pi-building mr-1"></i>
|
||||
#{userSession.entite.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p:commandButton value="Modifier le profil"
|
||||
icon="pi pi-pencil"
|
||||
styleClass="ui-button-outlined"
|
||||
onclick="PF('dlgEditProfile').show();" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations détaillées -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>📋 Informations Personnelles</h5>
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Nom complet</label>
|
||||
<div class="text-600">#{userSession.currentUser.nomComplet}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Nom d'utilisateur</label>
|
||||
<div class="text-600">#{userSession.currentUser.username}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Adresse email</label>
|
||||
<div class="text-600">#{userSession.currentUser.email}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Type de compte</label>
|
||||
<div>
|
||||
<p:tag value="#{userSession.typeCompte}"
|
||||
severity="#{userSession.isSuperAdmin() ? 'danger' : (userSession.isAdmin() ? 'warning' : 'info')}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>🏢 Informations de l'Entité</h5>
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Nom de l'entité</label>
|
||||
<div class="text-600">#{userSession.entite.nom}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Type d'entité</label>
|
||||
<div class="text-600">#{userSession.entite.type}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Localisation</label>
|
||||
<div class="text-600">
|
||||
<i class="pi pi-map-marker mr-1"></i>
|
||||
#{userSession.entite.ville}, #{userSession.entite.pays}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rôles et permissions -->
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>🔐 Rôles et Permissions</h5>
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Rôles assignés</label>
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
<ui:repeat value="#{userSession.roles}" var="role">
|
||||
<p:tag value="#{role}"
|
||||
severity="#{role == 'SUPER_ADMIN' ? 'danger' : (role == 'ADMIN_ENTITE' ? 'warning' : 'info')}" />
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" rendered="#{userSession.permissions != null}">
|
||||
<label class="font-medium text-900">Permissions spéciales</label>
|
||||
<div class="flex gap-1 flex-wrap">
|
||||
<ui:repeat value="#{userSession.permissions}" var="permission">
|
||||
<p:tag value="#{permission}" severity="secondary" />
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>🔒 Sécurité de la Session</h5>
|
||||
<div class="field-group">
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Statut de connexion</label>
|
||||
<div>
|
||||
<p:tag value="Connecté" severity="success" />
|
||||
<span class="text-600 ml-2">Session active</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Temps restant</label>
|
||||
<div class="text-600">
|
||||
<i class="pi pi-clock mr-1"></i>
|
||||
#{jwtTokenManager.timeUntilExpiration / 60} minutes
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="font-medium text-900">Actions sécurisées</label>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Changer mot de passe"
|
||||
icon="pi pi-key"
|
||||
styleClass="ui-button-outlined ui-button-warning ui-button-sm"
|
||||
onclick="PF('dlgChangePassword').show();" />
|
||||
<p:commandButton value="Déconnecter autres sessions"
|
||||
icon="pi pi-sign-out"
|
||||
styleClass="ui-button-outlined ui-button-danger ui-button-sm" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog pour modifier le profil -->
|
||||
<p:dialog header="Modifier le Profil" widgetVar="dlgEditProfile" modal="true" width="500">
|
||||
<h:form id="formEditProfile">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="editNom" value="Nom" />
|
||||
<p:inputText id="editNom" value="#{userSession.currentUser.nom}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="editPrenom" value="Prénom" />
|
||||
<p:inputText id="editPrenom" value="#{userSession.currentUser.prenom}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="editEmail" value="Email" />
|
||||
<p:inputText id="editEmail" value="#{userSession.currentUser.email}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Enregistrer"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-success"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgEditProfile').hide();" />
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgEditProfile').hide();"
|
||||
type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
<!-- Dialog pour changer le mot de passe -->
|
||||
<p:dialog header="Changer le Mot de Passe" widgetVar="dlgChangePassword" modal="true" width="400">
|
||||
<h:form id="formChangePassword">
|
||||
<div class="ui-fluid">
|
||||
<div class="field">
|
||||
<p:outputLabel for="currentPassword" value="Mot de passe actuel" />
|
||||
<p:password id="currentPassword" required="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="newPassword" value="Nouveau mot de passe" />
|
||||
<p:password id="newPassword" required="true" toggleMask="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="confirmPassword" value="Confirmer le mot de passe" />
|
||||
<p:password id="confirmPassword" required="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Changer"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-warning"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgChangePassword').hide();" />
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgChangePassword').hide();"
|
||||
type="button" />
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,116 @@
|
||||
<!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:param name="page" value="#{rapportsBean}"/>
|
||||
<ui:define name="title">Rapports Activités - 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-calendar text-orange-500" />
|
||||
<ui:param name="title" value="Rapports Activités" />
|
||||
<ui:param name="description" value="Analyse des activités et événements" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActions">
|
||||
<div class="flex gap-2">
|
||||
<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="onclick" value="PF('dlgExport').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{rapportsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques activités -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{rapportsBean.indicateurs.totalEvenements}" />
|
||||
<ui:param name="label" value="Total Événements" />
|
||||
<ui:param name="icon" value="pi pi-calendar" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{rapportsBean.indicateurs.croissanceEvenements}%" />
|
||||
<ui:param name="label" value="Croissance Événements" />
|
||||
<ui:param name="icon" value="pi pi-arrow-up" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- KPIs Activités -->
|
||||
<div class="card">
|
||||
<h5>Indicateurs d'Activité</h5>
|
||||
<div class="formgrid grid">
|
||||
<ui:repeat value="#{rapportsBean.kpis}" var="kpi">
|
||||
<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="colSize" value="col-12 md:col-4" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Export -->
|
||||
<h:form id="formExport">
|
||||
<p:dialog id="dlgExport"
|
||||
widgetVar="dlgExport"
|
||||
header="Exporter le Rapport Activités"
|
||||
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="#{rapportsBean.nouveauRapport.format}"
|
||||
layout="grid"
|
||||
columns="1">
|
||||
<f:selectItem itemLabel="PDF" itemValue="PDF" />
|
||||
<f:selectItem itemLabel="Excel (.xlsx)" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="CSV" itemValue="CSV" />
|
||||
</p:selectOneRadio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex justify-content-end gap-2">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('dlgExport').hide();"
|
||||
type="button" />
|
||||
<p:commandButton value="Exporter"
|
||||
icon="pi pi-download"
|
||||
styleClass="p-button-success"
|
||||
action="#{rapportsBean.exporterDonnees}" />
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,145 @@
|
||||
<!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:param name="page" value="#{rapportDetailsBean}"/>
|
||||
<ui:define name="title">Détails du Rapport - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<h:form id="formDetails">
|
||||
<p:messages id="messages" showDetail="true" closable="true"/>
|
||||
|
||||
<!-- En-tête -->
|
||||
<div class="card mb-3">
|
||||
<div class="flex justify-content-between align-items-center flex-column md:flex-row">
|
||||
<div class="flex align-items-center gap-3 mb-2 md:mb-0">
|
||||
<div class="bg-primary text-white border-round text-center"
|
||||
style="width: 64px; height: 64px; line-height: 64px;">
|
||||
<i class="pi #{rapportDetailsBean.rapport.typeIcon} text-3xl"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="m-0">#{rapportDetailsBean.rapport.typeLibelle}</h3>
|
||||
<div class="mt-2 flex align-items-center gap-2">
|
||||
<p:tag value="#{rapportDetailsBean.rapport.statut}"
|
||||
severity="#{rapportDetailsBean.rapport.statutSeverity}" />
|
||||
<span class="text-600">Généré le #{rapportDetailsBean.dateGenerationFormatee}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Retour"/>
|
||||
<ui:param name="icon" value="pi pi-arrow-left"/>
|
||||
<ui:param name="action" value="#{rapportDetailsBean.retourner}"/>
|
||||
</ui:include>
|
||||
<p:commandButton value="Télécharger"
|
||||
icon="pi pi-download"
|
||||
styleClass="ui-button-success"
|
||||
action="#{rapportDetailsBean.telechargerRapport}"
|
||||
update="messages"
|
||||
rendered="#{rapportDetailsBean.isRapportDisponible()}"/>
|
||||
<p:commandButton value="Régénérer"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
action="#{rapportDetailsBean.regenererRapport}"
|
||||
update="messages"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h:panelGroup rendered="#{not empty rapportDetailsBean.rapport}">
|
||||
<div class="grid">
|
||||
<!-- Informations générales -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Informations Générales</h5>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Type de rapport"/>
|
||||
<ui:param name="value" value="#{rapportDetailsBean.rapport.typeLibelle}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Date de génération"/>
|
||||
<ui:param name="value" value="#{rapportDetailsBean.dateGenerationFormatee}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Période couverte"/>
|
||||
<ui:param name="value" value="#{rapportDetailsBean.rapport.periodeCouverte}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Généré par"/>
|
||||
<ui:param name="value" value="#{rapportDetailsBean.rapport.generePar}"/>
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/forms/detail-field.xhtml">
|
||||
<ui:param name="label" value="Statut"/>
|
||||
<ui:param name="value" value="#{rapportDetailsBean.rapport.statut}"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Résumé du rapport -->
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5 class="mb-3">Résumé</h5>
|
||||
<div class="surface-50 p-3 border-round">
|
||||
<p class="text-600 m-0">
|
||||
Ce rapport contient les données analytiques et statistiques
|
||||
pour la période sélectionnée. Les informations détaillées
|
||||
sont disponibles dans le fichier téléchargeable.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions rapides -->
|
||||
<div class="card mt-3">
|
||||
<h5 class="mb-3">Actions</h5>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<p:commandButton value="Télécharger PDF"
|
||||
icon="pi pi-file-pdf"
|
||||
styleClass="ui-button-success"
|
||||
action="#{rapportDetailsBean.telechargerRapport}"
|
||||
update="messages"
|
||||
rendered="#{rapportDetailsBean.isRapportDisponible()}"/>
|
||||
<p:commandButton value="Télécharger Excel"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-outlined ui-button-success"
|
||||
action="#{rapportDetailsBean.telechargerRapport}"
|
||||
update="messages"
|
||||
rendered="#{rapportDetailsBean.isRapportDisponible()}"/>
|
||||
<p:commandButton value="Régénérer le rapport"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
action="#{rapportDetailsBean.regenererRapport}"
|
||||
update="messages"/>
|
||||
<p:commandButton value="Partager"
|
||||
icon="pi pi-share-alt"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
onclick="PF('dlgPartage').show();"/>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
<!-- Message si rapport non trouvé -->
|
||||
<h:panelGroup rendered="#{empty rapportDetailsBean.rapport}">
|
||||
<div class="card">
|
||||
<div class="text-center p-5">
|
||||
<i class="pi pi-exclamation-triangle text-6xl text-orange-500 mb-3"></i>
|
||||
<h3 class="mb-2">Rapport introuvable</h3>
|
||||
<p class="text-600 mb-4">Le rapport demandé n'a pas été trouvé.</p>
|
||||
<ui:include src="/templates/components/buttons/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Retour aux rapports"/>
|
||||
<ui:param name="icon" value="pi pi-arrow-left"/>
|
||||
<ui:param name="action" value="#{rapportDetailsBean.retourner}"/>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
<!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:param name="page" value="#{rapportsBean}"/>
|
||||
<ui:define name="title">Export de Rapports - 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-download text-indigo-500" />
|
||||
<ui:param name="title" value="Export de Rapports" />
|
||||
<ui:param name="description" value="Générer et exporter des rapports personnalisés" />
|
||||
</ui:include>
|
||||
|
||||
<!-- Formulaire de génération de rapport -->
|
||||
<div class="card">
|
||||
<h:form id="formRapport">
|
||||
<h5>Nouveau Rapport</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="typeRapport" value="Type de Rapport *" />
|
||||
<p:selectOneMenu id="typeRapport"
|
||||
value="#{rapportsBean.nouveauRapport.type}"
|
||||
styleClass="w-full"
|
||||
required="true">
|
||||
<f:selectItem itemLabel="Sélectionner un type" 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>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="formatRapport" value="Format *" />
|
||||
<p:selectOneMenu id="formatRapport"
|
||||
value="#{rapportsBean.nouveauRapport.format}"
|
||||
styleClass="w-full"
|
||||
required="true">
|
||||
<f:selectItem itemLabel="PDF" itemValue="PDF" />
|
||||
<f:selectItem itemLabel="Excel (.xlsx)" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="CSV" itemValue="CSV" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="periodeRapport" value="Période *" />
|
||||
<p:selectOneMenu id="periodeRapport"
|
||||
value="#{rapportsBean.nouveauRapport.periode}"
|
||||
styleClass="w-full"
|
||||
required="true">
|
||||
<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="Année en cours" itemValue="ANNEE_COURANTE" />
|
||||
<f:selectItem itemLabel="Période personnalisée" itemValue="PERSONNALISEE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="detailRapport" value="Niveau de Détail" />
|
||||
<p:selectOneMenu id="detailRapport"
|
||||
value="#{rapportsBean.nouveauRapport.detail}"
|
||||
styleClass="w-full">
|
||||
<f:selectItem itemLabel="Résumé" itemValue="RESUME" />
|
||||
<f:selectItem itemLabel="Standard" itemValue="STANDARD" />
|
||||
<f:selectItem itemLabel="Détaillé" itemValue="DETAILLE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<p:outputLabel for="commentairesRapport" value="Commentaires (optionnel)" />
|
||||
<p:inputTextarea id="commentairesRapport"
|
||||
value="#{rapportsBean.nouveauRapport.commentaires}"
|
||||
rows="3"
|
||||
styleClass="w-full"
|
||||
placeholder="Ajoutez des commentaires ou notes pour ce rapport..." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="flex justify-content-end gap-2">
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="p-button-outlined p-button-secondary"
|
||||
action="#{rapportsBean.nouveauRapport = null}"
|
||||
update="@form" />
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Générer le Rapport" />
|
||||
<ui:param name="icon" value="pi pi-file" />
|
||||
<ui:param name="action" value="#{rapportsBean.genererRapport}" />
|
||||
<ui:param name="update" value="@form :formHistorique" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Historique des rapports -->
|
||||
<div class="card">
|
||||
<h:form id="formHistorique">
|
||||
<h5>Historique des Rapports</h5>
|
||||
|
||||
<p:dataTable value="#{rapportsBean.historiqueRapports}" var="rapport"
|
||||
emptyMessage="Aucun rapport généré"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
styleClass="p-datatable-sm">
|
||||
|
||||
<p:column headerText="Type">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="#{rapport.typeIcon} text-#{rapport.typeCouleur}"></i>
|
||||
<span class="font-semibold">#{rapport.typeLibelle}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Période">
|
||||
<span>#{rapport.periodeCouverte}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Date Génération">
|
||||
<span>#{rapport.dateGenerationFormatee}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Généré par">
|
||||
<span>#{rapport.generePar}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut">
|
||||
<p:tag value="#{rapport.statut}"
|
||||
severity="#{rapport.statutSeverity}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions" styleClass="text-center">
|
||||
<div class="flex justify-content-center gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
title="Voir"
|
||||
styleClass="p-button-sm p-button-rounded p-button-info"
|
||||
action="#{rapportsBean.voirRapport(rapport)}" />
|
||||
<p:commandButton icon="pi pi-download"
|
||||
title="Télécharger"
|
||||
styleClass="p-button-sm p-button-rounded p-button-success"
|
||||
action="#{rapportsBean.telechargerRapport(rapport)}"
|
||||
rendered="#{rapport.statut == 'GENERE'}" />
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,209 @@
|
||||
<!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:param name="page" value="#{rapportsBean}"/>
|
||||
<ui:define name="title">Rapports Financiers - 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-dollar text-green-500" />
|
||||
<ui:param name="title" value="Rapports Financiers" />
|
||||
<ui:param name="description" value="Analyse financière et suivi des revenus" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActions">
|
||||
<div class="flex gap-2">
|
||||
<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="onclick" value="PF('dlgExport').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{rapportsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Filtres de période -->
|
||||
<div class="card">
|
||||
<h:form id="formFiltres">
|
||||
<h5>Période d'Analyse</h5>
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<ui:include src="/templates/components/forms/form-field-select.xhtml">
|
||||
<ui:param name="id" value="periodeRapide" />
|
||||
<ui:param name="label" value="Période Rapide" />
|
||||
<ui:param name="value" value="#{rapportsBean.periodeRapide}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:define name="items">
|
||||
<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="Année en cours" itemValue="ANNEE_COURANTE" />
|
||||
</ui:define>
|
||||
</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="dateDebut" />
|
||||
<ui:param name="label" value="Date Début" />
|
||||
<ui:param name="value" value="#{rapportsBean.dateDebut}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
</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="#{rapportsBean.dateFin}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="field">
|
||||
<p:outputLabel />
|
||||
<ui:include src="/templates/components/buttons/button-primary.xhtml">
|
||||
<ui:param name="value" value="Appliquer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{rapportsBean.chargerDonnees}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Indicateurs financiers -->
|
||||
<div class="grid">
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{rapportsBean.indicateurs.revenus}" />
|
||||
<ui:param name="label" value="Revenus Totaux" />
|
||||
<ui:param name="icon" value="pi pi-dollar" />
|
||||
<ui:param name="bgColor" value="green" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{rapportsBean.indicateurs.croissanceRevenus}%" />
|
||||
<ui:param name="label" value="Croissance Revenus" />
|
||||
<ui:param name="icon" value="pi pi-arrow-up" />
|
||||
<ui:param name="bgColor" value="blue" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{rapportsBean.indicateurs.totalMembres}" />
|
||||
<ui:param name="label" value="Membres Actifs" />
|
||||
<ui:param name="icon" value="pi pi-users" />
|
||||
<ui:param name="bgColor" value="purple" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/cards/stat-card.xhtml">
|
||||
<ui:param name="value" value="#{rapportsBean.indicateurs.croissanceMembres}%" />
|
||||
<ui:param name="label" value="Croissance Membres" />
|
||||
<ui:param name="icon" value="pi pi-chart-line" />
|
||||
<ui:param name="bgColor" value="orange" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Sources de revenus -->
|
||||
<div class="card">
|
||||
<h5>Sources de Revenus</h5>
|
||||
<p:dataTable value="#{rapportsBean.sourceRevenus}" var="source"
|
||||
emptyMessage="Aucune donnée disponible"
|
||||
styleClass="p-datatable-sm">
|
||||
<p:column headerText="Source">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<i class="#{source.icon} text-lg"></i>
|
||||
<span class="font-semibold">#{source.libelle}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Montant">
|
||||
<span class="font-bold">#{source.montant} FCFA</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Pourcentage">
|
||||
<p:progressBar value="#{source.pourcentage}"
|
||||
showValue="true"
|
||||
styleClass="p-progressbar-sm" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
<!-- KPIs Financiers -->
|
||||
<div class="card">
|
||||
<h5>Indicateurs Clés de Performance</h5>
|
||||
<div class="formgrid grid">
|
||||
<ui:repeat value="#{rapportsBean.kpis}" var="kpi">
|
||||
<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="colSize" value="col-12 md:col-4" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Export -->
|
||||
<h:form id="formExport">
|
||||
<p:dialog id="dlgExport"
|
||||
widgetVar="dlgExport"
|
||||
header="Exporter le Rapport Financier"
|
||||
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="#{rapportsBean.nouveauRapport.format}"
|
||||
layout="grid"
|
||||
columns="1">
|
||||
<f:selectItem itemLabel="PDF" itemValue="PDF" />
|
||||
<f:selectItem itemLabel="Excel (.xlsx)" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="CSV" itemValue="CSV" />
|
||||
</p:selectOneRadio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex justify-content-end gap-2">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('dlgExport').hide();"
|
||||
type="button" />
|
||||
<p:commandButton value="Exporter"
|
||||
icon="pi pi-download"
|
||||
styleClass="p-button-success"
|
||||
action="#{rapportsBean.exporterDonnees}" />
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,150 @@
|
||||
<!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:param name="page" value="#{rapportsBean}"/>
|
||||
<ui:define name="title">Rapports Membres - 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-users text-blue-500" />
|
||||
<ui:param name="title" value="Rapports Membres" />
|
||||
<ui:param name="description" value="Analyse et statistiques sur les membres" />
|
||||
<ui:define name="actions">
|
||||
<h:form id="formActions">
|
||||
<div class="flex gap-2">
|
||||
<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="onclick" value="PF('dlgExport').show();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/buttons/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{rapportsBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
|
||||
<!-- Statistiques membres -->
|
||||
<div class="formgrid grid">
|
||||
<ui:include src="/templates/components/cards/kpi-card.xhtml">
|
||||
<ui:param name="title" value="Total Membres" />
|
||||
<ui:param name="value" value="#{rapportsBean.indicateurs.totalMembres}" />
|
||||
<ui:param name="icon" value="pi-users" />
|
||||
<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="Croissance" />
|
||||
<ui:param name="value" value="#{rapportsBean.indicateurs.croissanceMembres}%" />
|
||||
<ui:param name="icon" value="pi-arrow-up" />
|
||||
<ui:param name="iconColor" value="green-600" />
|
||||
<ui:param name="showGrowth" value="false" />
|
||||
<ui:param name="showProgress" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<!-- Répartition des membres -->
|
||||
<div class="card">
|
||||
<h5>Répartition des Membres</h5>
|
||||
<p:dataTable value="#{rapportsBean.repartitionMembres}" var="repartition"
|
||||
emptyMessage="Aucune donnée disponible"
|
||||
styleClass="p-datatable-sm">
|
||||
<p:column headerText="Statut">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<div class="w-1rem h-1rem border-circle bg-#{repartition.couleur}"></div>
|
||||
<span class="font-semibold">#{repartition.libelle}</span>
|
||||
</div>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Nombre">
|
||||
<span class="font-bold">#{repartition.nombre}</span>
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Pourcentage">
|
||||
<p:progressBar value="#{repartition.pourcentage}"
|
||||
showValue="true"
|
||||
styleClass="p-progressbar-sm" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
<!-- Objectifs -->
|
||||
<div class="card">
|
||||
<h5>Objectifs</h5>
|
||||
<div class="grid">
|
||||
<ui:repeat value="#{rapportsBean.objectifs}" var="objectif">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="surface-100 border-round-lg p-4">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<span class="font-semibold">#{objectif.libelle}</span>
|
||||
<span class="text-sm text-600">#{objectif.pourcentage}%</span>
|
||||
</div>
|
||||
<p:progressBar value="#{objectif.pourcentage}"
|
||||
showValue="false"
|
||||
styleClass="p-progressbar-sm mb-2" />
|
||||
<div class="flex justify-content-between text-sm">
|
||||
<span class="text-600">Réalisé: #{objectif.realise}</span>
|
||||
<span class="text-600">Cible: #{objectif.cible}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dialog Export -->
|
||||
<h:form id="formExport">
|
||||
<p:dialog id="dlgExport"
|
||||
widgetVar="dlgExport"
|
||||
header="Exporter le Rapport Membres"
|
||||
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="#{rapportsBean.nouveauRapport.format}"
|
||||
layout="grid"
|
||||
columns="1">
|
||||
<f:selectItem itemLabel="PDF" itemValue="PDF" />
|
||||
<f:selectItem itemLabel="Excel (.xlsx)" itemValue="EXCEL" />
|
||||
<f:selectItem itemLabel="CSV" itemValue="CSV" />
|
||||
</p:selectOneRadio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<div class="flex justify-content-end gap-2">
|
||||
<p:commandButton value="Annuler"
|
||||
styleClass="p-button-outlined"
|
||||
onclick="PF('dlgExport').hide();"
|
||||
type="button" />
|
||||
<p:commandButton value="Exporter"
|
||||
icon="pi pi-download"
|
||||
styleClass="p-button-success"
|
||||
action="#{rapportsBean.exporterDonnees}" />
|
||||
</div>
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
26
target/classes/META-INF/resources/pages/secure/reports.xhtml
Normal file
26
target/classes/META-INF/resources/pages/secure/reports.xhtml
Normal file
@@ -0,0 +1,26 @@
|
||||
<!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 - Rapports</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h2>Rapports</h2>
|
||||
<p>Génération et consultation de rapports</p>
|
||||
|
||||
<p:button value="Retour au tableau de bord"
|
||||
icon="pi pi-arrow-left"
|
||||
outcome="/pages/secure/dashboard"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,355 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||
xmlns:f="http://java.sun.com/jsf/core"
|
||||
xmlns:h="http://java.sun.com/jsf/html"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/main-template.xhtml">
|
||||
|
||||
<ui:define name="title">Gestion de la Souscription - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="head">
|
||||
<style>
|
||||
.subscription-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 2rem;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.quota-gauge {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.quota-progress {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.quota-text {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feature-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 8px;
|
||||
border-radius: 16px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.feature-active {
|
||||
background: #dcfce7;
|
||||
color: #166534;
|
||||
}
|
||||
|
||||
.feature-inactive {
|
||||
background: #f3f4f6;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.upgrade-card {
|
||||
border: 2px solid #10b981;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.upgrade-card::before {
|
||||
content: 'RECOMMANDÉ';
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: -30px;
|
||||
background: #10b981;
|
||||
color: white;
|
||||
padding: 4px 40px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
</style>
|
||||
</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<!-- En-tête de souscription -->
|
||||
<div class="subscription-header">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h1 class="text-4xl font-bold mb-2">
|
||||
<i class="#{souscriptionBean.iconeStatut} mr-2"></i>
|
||||
#{souscriptionBean.souscriptionActive.formulaireNom}
|
||||
</h1>
|
||||
<div class="text-xl opacity-90 mb-1">
|
||||
#{souscriptionBean.souscriptionActive.organisationNom}
|
||||
</div>
|
||||
<div class="text-lg opacity-80">
|
||||
Souscription #{souscriptionBean.souscriptionActive.statut.libelle}
|
||||
- #{souscriptionBean.souscriptionActive.typeFacturation.libelle}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-2xl font-bold mb-1">
|
||||
#{souscriptionBean.souscriptionActive.montantFormat}
|
||||
</div>
|
||||
<div class="opacity-90">
|
||||
Expire le #{souscriptionBean.souscriptionActive.dateFin}
|
||||
</div>
|
||||
<h:panelGroup rendered="#{souscriptionBean.joursAvantExpiration le 30}">
|
||||
<div class="text-yellow-300 font-semibold mt-1">
|
||||
<i class="pi pi-clock mr-1"></i>
|
||||
#{souscriptionBean.joursAvantExpiration} jour(s) restant(s)
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alertes quota et expiration -->
|
||||
<h:panelGroup rendered="#{not empty souscriptionBean.alertesQuota}">
|
||||
<div class="grid mb-4">
|
||||
<ui:repeat value="#{souscriptionBean.alertesQuota}" var="alerte">
|
||||
<div class="col-12">
|
||||
<p:message severity="#{alerte.severite}"
|
||||
summary="#{alerte.titre}"
|
||||
detail="#{alerte.message}"
|
||||
closable="false">
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<div class="flex align-items-center">
|
||||
<i class="#{alerte.icone} mr-2"></i>
|
||||
<div>
|
||||
<div class="font-semibold">#{alerte.titre}</div>
|
||||
<div>#{alerte.message}</div>
|
||||
</div>
|
||||
</div>
|
||||
<p:commandButton value="#{alerte.action}"
|
||||
action="#{alerte.actionUrl}"
|
||||
styleClass="p-button-sm p-button-outlined"
|
||||
rendered="#{not empty alerte.action}"/>
|
||||
</div>
|
||||
</p:message>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
|
||||
<div class="grid">
|
||||
<!-- Utilisation du quota -->
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="surface-card p-4 border-round shadow-2">
|
||||
<div class="text-center mb-4">
|
||||
<div class="text-900 font-bold text-xl mb-2">Quota de Membres</div>
|
||||
|
||||
<!-- Jauge circulaire du quota -->
|
||||
<div class="quota-gauge mb-3">
|
||||
<svg width="120" height="120" class="quota-progress">
|
||||
<circle cx="60" cy="60" r="50"
|
||||
stroke="#e5e7eb" stroke-width="8"
|
||||
fill="transparent"/>
|
||||
<circle cx="60" cy="60" r="50"
|
||||
stroke="#{souscriptionBean.couleurJaugeQuota == 'success' ? '#10b981' : souscriptionBean.couleurJaugeQuota == 'warning' ? '#f59e0b' : '#ef4444'}"
|
||||
stroke-width="8"
|
||||
fill="transparent"
|
||||
stroke-dasharray="314"
|
||||
stroke-dashoffset="#{314 - (314 * souscriptionBean.souscriptionActive.pourcentageUtilisation / 100)}"
|
||||
stroke-linecap="round"/>
|
||||
</svg>
|
||||
<div class="quota-text">
|
||||
<div class="text-2xl font-bold text-900">#{souscriptionBean.souscriptionActive.pourcentageUtilisation}%</div>
|
||||
<div class="text-sm text-600">utilisé</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-600 mb-2">
|
||||
#{souscriptionBean.membresActuels} / #{souscriptionBean.quotaMaximum} membres
|
||||
</div>
|
||||
<div class="text-900 font-semibold">
|
||||
#{souscriptionBean.membresRestants} membre(s) restant(s)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Upgrader"
|
||||
action="#{souscriptionBean.upgraderFormulaire()}"
|
||||
styleClass="p-button-success flex-1"
|
||||
rendered="#{souscriptionBean.alerteQuotaProche or souscriptionBean.quotaAtteint}"/>
|
||||
|
||||
<p:commandButton value="Gérer les membres"
|
||||
action="/pages/secure/membre/liste"
|
||||
styleClass="p-button-outlined flex-1"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Détails de la souscription -->
|
||||
<div class="col-12 md:col-5">
|
||||
<div class="surface-card p-4 border-round shadow-2">
|
||||
<div class="text-900 font-bold text-xl mb-3">Détails de la Souscription</div>
|
||||
|
||||
<div class="formgrid grid">
|
||||
<div class="field col-6">
|
||||
<label class="block text-600 font-medium mb-2">Date de début</label>
|
||||
<div class="text-900">#{souscriptionBean.souscriptionActive.dateDebut}</div>
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<label class="block text-600 font-medium mb-2">Date de fin</label>
|
||||
<div class="text-900">#{souscriptionBean.souscriptionActive.dateFin}</div>
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<label class="block text-600 font-medium mb-2">Dernier paiement</label>
|
||||
<div class="text-900">#{souscriptionBean.souscriptionActive.dateDernierPaiement}</div>
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<label class="block text-600 font-medium mb-2">Prochain paiement</label>
|
||||
<div class="text-900">#{souscriptionBean.souscriptionActive.dateProchainPaiement}</div>
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<label class="block text-600 font-medium mb-2">Référence de paiement</label>
|
||||
<div class="text-900 font-mono">#{souscriptionBean.souscriptionActive.referencePaiement}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notifications -->
|
||||
<div class="mt-4 pt-3 border-top-1 surface-border">
|
||||
<div class="text-900 font-semibold mb-3">Notifications</div>
|
||||
<div class="flex align-items-center justify-content-between mb-2">
|
||||
<label for="notif-expiration" class="text-900">Expiration de souscription</label>
|
||||
<p:inputSwitch id="notif-expiration"
|
||||
value="#{souscriptionBean.souscriptionActive.notificationExpiration}"
|
||||
onLabel="ON" offLabel="OFF">
|
||||
<p:ajax listener="#{souscriptionBean.activerNotificationExpiration(souscriptionBean.souscriptionActive.notificationExpiration)}" />
|
||||
</p:inputSwitch>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between">
|
||||
<label for="notif-quota" class="text-900">Quota de membres atteint</label>
|
||||
<p:inputSwitch id="notif-quota"
|
||||
value="#{souscriptionBean.souscriptionActive.notificationQuotaAtteint}"
|
||||
onLabel="ON" offLabel="OFF">
|
||||
<p:ajax listener="#{souscriptionBean.activerNotificationQuota(souscriptionBean.souscriptionActive.notificationQuotaAtteint)}" />
|
||||
</p:inputSwitch>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions rapides -->
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="surface-card p-4 border-round shadow-2">
|
||||
<div class="text-900 font-bold text-xl mb-3">Actions</div>
|
||||
|
||||
<div class="flex flex-column gap-3">
|
||||
<p:commandButton value="Renouveler"
|
||||
action="#{souscriptionBean.renouvelerSouscription()}"
|
||||
styleClass="p-button w-full"
|
||||
icon="pi pi-refresh"/>
|
||||
|
||||
<p:commandButton value="Changer de plan"
|
||||
action="#{souscriptionBean.changerFormulaire()}"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-sync"/>
|
||||
|
||||
<p:commandButton value="Historique des paiements"
|
||||
action="/pages/secure/souscription/historique"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-history"/>
|
||||
|
||||
<p:commandButton value="Télécharger facture"
|
||||
styleClass="p-button-outlined w-full"
|
||||
icon="pi pi-download"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Formulaires disponibles pour upgrade -->
|
||||
<h:panelGroup rendered="#{souscriptionBean.alerteQuotaProche or souscriptionBean.quotaAtteint}">
|
||||
<div class="surface-card p-6 border-round shadow-2 mt-4">
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="text-900 text-3xl font-bold mb-2">Besoin de plus d'espace ?</h2>
|
||||
<p class="text-600 text-lg">Découvrez nos formules supérieures pour accueillir plus de membres</p>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="surface-border border-round p-4">
|
||||
<div class="text-center mb-3">
|
||||
<div class="bg-green-500 text-white inline-flex align-items-center justify-content-center border-circle mb-3" style="width: 60px; height: 60px;">
|
||||
<i class="pi pi-users text-2xl"></i>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl">Premium</div>
|
||||
<div class="text-600">Jusqu'à 500 membres</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-4">
|
||||
<div class="text-900 text-3xl font-bold">4 000 FCFA/mois</div>
|
||||
<div class="text-600">40 000 FCFA/an (économisez 16%)</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-1 mb-4">
|
||||
<span class="feature-badge feature-active">
|
||||
<i class="pi pi-check mr-1"></i>Gestion complète
|
||||
</span>
|
||||
<span class="feature-badge feature-active">
|
||||
<i class="pi pi-check mr-1"></i>Rapports avancés
|
||||
</span>
|
||||
<span class="feature-badge feature-active">
|
||||
<i class="pi pi-check mr-1"></i>Support prioritaire
|
||||
</span>
|
||||
<span class="feature-badge feature-active">
|
||||
<i class="pi pi-check mr-1"></i>Intégrations
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Upgrader vers Premium"
|
||||
styleClass="p-button-success w-full"
|
||||
action="/pages/secure/souscription/upgrade?plan=premium"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="upgrade-card surface-border border-round p-4">
|
||||
<div class="text-center mb-3">
|
||||
<div class="bg-indigo-500 text-white inline-flex align-items-center justify-content-center border-circle mb-3" style="width: 60px; height: 60px;">
|
||||
<i class="pi pi-diamond text-2xl"></i>
|
||||
</div>
|
||||
<div class="text-900 font-bold text-2xl">Cristal</div>
|
||||
<div class="text-600">Jusqu'à 2000 membres</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-4">
|
||||
<div class="text-900 text-3xl font-bold">5 000 FCFA/mois</div>
|
||||
<div class="text-600">50 000 FCFA/an (économisez 16%)</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-1 mb-4">
|
||||
<span class="feature-badge feature-active">
|
||||
<i class="pi pi-check mr-1"></i>Tout Premium +
|
||||
</span>
|
||||
<span class="feature-badge feature-active">
|
||||
<i class="pi pi-check mr-1"></i>Personnalisation
|
||||
</span>
|
||||
<span class="feature-badge feature-active">
|
||||
<i class="pi pi-check mr-1"></i>API complète
|
||||
</span>
|
||||
<span class="feature-badge feature-active">
|
||||
<i class="pi pi-check mr-1"></i>Support dédié
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Upgrader vers Cristal"
|
||||
styleClass="p-button-help w-full"
|
||||
action="/pages/secure/souscription/upgrade?plan=cristal"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
18
target/classes/META-INF/resources/pages/secure/stats.xhtml
Normal file
18
target/classes/META-INF/resources/pages/secure/stats.xhtml
Normal file
@@ -0,0 +1,18 @@
|
||||
<!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:param name="page" value="#{dashboardBean}"/>
|
||||
<ui:define name="title">Statistiques - UnionFlow</ui:define>
|
||||
<ui:define name="content">
|
||||
<!-- Redirection vers dashboard (WOU/DRY - réutiliser la même page) -->
|
||||
<h:form>
|
||||
<p:commandButton value="Voir le tableau de bord"
|
||||
action="dashboardPage?faces-redirect=true"
|
||||
styleClass="ui-button-primary"/>
|
||||
</h:form>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
@@ -0,0 +1,775 @@
|
||||
<!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">Configuration Système - 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-cog text-purple-500 mr-2"></i>
|
||||
Configuration Système
|
||||
</h3>
|
||||
<p class="text-600 m-0">Paramètres globaux • Sécurité • Intégrations • Performance • #{configBean.derniereModification}</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Sauvegarder configuration"
|
||||
icon="pi pi-save"
|
||||
styleClass="ui-button-success"
|
||||
action="#{configBean.sauvegarderTout}" />
|
||||
<p:commandButton value="Réinitialiser"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
onclick="return confirm('Réinitialiser toute la configuration ?');"
|
||||
action="#{configBean.reinitialiser}" />
|
||||
<p:commandButton value="Exporter config"
|
||||
icon="pi pi-download"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{configBean.exporterConfiguration}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statut système -->
|
||||
<div class="grid">
|
||||
<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">#{configBean.statutSysteme}</div>
|
||||
<div class="text-green-700">Statut Système</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-circle 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">#{configBean.versionApplication}</div>
|
||||
<div class="text-blue-700">Version Application</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-code 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">#{configBean.utilisateursConnectes}</div>
|
||||
<div class="text-orange-700">Utilisateurs En Ligne</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-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">#{configBean.espaceDisque}</div>
|
||||
<div class="text-purple-700">Espace Utilisé</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-database text-xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration par onglets -->
|
||||
<div class="card">
|
||||
<p:tabView>
|
||||
<!-- Paramètres Généraux -->
|
||||
<p:tab title="🏢 Général">
|
||||
<h:form id="formGeneral">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Informations Application</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="nomApplication" value="Nom de l'application" />
|
||||
<p:inputText id="nomApplication" value="#{configBean.config.nomApplication}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="description" value="Description" />
|
||||
<p:inputTextarea id="description" value="#{configBean.config.description}" rows="3" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="organisation" value="Organisation" />
|
||||
<p:inputText id="organisation" value="#{configBean.config.organisation}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="siteWeb" value="Site web" />
|
||||
<p:inputText id="siteWeb" value="#{configBean.config.siteWeb}" placeholder="https://..." />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Paramètres Régionaux</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="langue" value="Langue par défaut" />
|
||||
<p:selectOneMenu id="langue" value="#{configBean.config.langue}">
|
||||
<f:selectItem itemLabel="Français" itemValue="fr" />
|
||||
<f:selectItem itemLabel="English" itemValue="en" />
|
||||
<f:selectItem itemLabel="العربية" itemValue="ar" />
|
||||
<f:selectItem itemLabel="Wolof" itemValue="wo" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="fuseau" value="Fuseau horaire" />
|
||||
<p:selectOneMenu id="fuseau" value="#{configBean.config.fuseauHoraire}">
|
||||
<f:selectItem itemLabel="GMT (UTC+0)" itemValue="GMT" />
|
||||
<f:selectItem itemLabel="WAT (UTC+1)" itemValue="WAT" />
|
||||
<f:selectItem itemLabel="CET (UTC+1)" itemValue="CET" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="devise" value="Devise" />
|
||||
<p:selectOneMenu id="devise" value="#{configBean.config.devise}">
|
||||
<f:selectItem itemLabel="FCFA (XOF)" itemValue="XOF" />
|
||||
<f:selectItem itemLabel="Euro (EUR)" itemValue="EUR" />
|
||||
<f:selectItem itemLabel="Dollar (USD)" itemValue="USD" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="formatDate" value="Format de date" />
|
||||
<p:selectOneMenu id="formatDate" value="#{configBean.config.formatDate}">
|
||||
<f:selectItem itemLabel="dd/MM/yyyy" itemValue="dd/MM/yyyy" />
|
||||
<f:selectItem itemLabel="MM/dd/yyyy" itemValue="MM/dd/yyyy" />
|
||||
<f:selectItem itemLabel="yyyy-MM-dd" itemValue="yyyy-MM-dd" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h5>Options d'Interface</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="modeNuit" value="#{configBean.config.modeNuit}" />
|
||||
<p:outputLabel for="modeNuit" value=" Mode sombre par défaut" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="notificationsDesktop" value="#{configBean.config.notificationsDesktop}" />
|
||||
<p:outputLabel for="notificationsDesktop" value=" Notifications desktop" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="animationsUI" value="#{configBean.config.animationsUI}" />
|
||||
<p:outputLabel for="animationsUI" value=" Animations d'interface" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:tab>
|
||||
|
||||
<!-- Configuration Email -->
|
||||
<p:tab title="📧 Email">
|
||||
<h:form id="formEmail">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Serveur SMTP</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="smtpHost" value="Serveur SMTP" />
|
||||
<p:inputText id="smtpHost" value="#{configBean.emailConfig.smtpHost}"
|
||||
placeholder="smtp.gmail.com" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="smtpPort" value="Port" />
|
||||
<p:inputNumber id="smtpPort" value="#{configBean.emailConfig.smtpPort}"
|
||||
symbol="" placeholder="587" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="smtpUsername" value="Nom d'utilisateur" />
|
||||
<p:inputText id="smtpUsername" value="#{configBean.emailConfig.smtpUsername}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="smtpPassword" value="Mot de passe" />
|
||||
<p:password id="smtpPassword" value="#{configBean.emailConfig.smtpPassword}"
|
||||
feedback="false" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="smtpSSL" value="#{configBean.emailConfig.smtpSSL}" />
|
||||
<p:outputLabel for="smtpSSL" value=" Utiliser SSL/TLS" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Configuration Email</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="emailExpediteur" value="Email expéditeur" />
|
||||
<p:inputText id="emailExpediteur" value="#{configBean.emailConfig.emailExpediteur}"
|
||||
placeholder="noreply@unionflow.com" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="nomExpediteur" value="Nom expéditeur" />
|
||||
<p:inputText id="nomExpediteur" value="#{configBean.emailConfig.nomExpediteur}"
|
||||
placeholder="UnionFlow System" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="emailAdmin" value="Email administrateur" />
|
||||
<p:inputText id="emailAdmin" value="#{configBean.emailConfig.emailAdmin}" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="signatureEmail" value="Signature email" />
|
||||
<p:inputTextarea id="signatureEmail" value="#{configBean.emailConfig.signature}"
|
||||
rows="4" placeholder="Signature automatique..." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h5>Test de Configuration</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="emailTest" value="Email de test" />
|
||||
<p:inputText id="emailTest" value="#{configBean.emailTest}"
|
||||
placeholder="test@example.com" />
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Envoyer email de test"
|
||||
icon="pi pi-send"
|
||||
styleClass="ui-button-outlined ui-button-info w-full"
|
||||
action="#{configBean.envoyerEmailTest}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:tab>
|
||||
|
||||
<!-- Sécurité -->
|
||||
<p:tab title="🔒 Sécurité">
|
||||
<h:form id="formSecurite">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Politique de Mots de Passe</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="longueurMinMdp" value="Longueur minimale" />
|
||||
<p:inputNumber id="longueurMinMdp" value="#{configBean.securityConfig.longueurMinMdp}"
|
||||
symbol="" min="6" max="20" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="majusculesRequises" value="#{configBean.securityConfig.majusculesRequises}" />
|
||||
<p:outputLabel for="majusculesRequises" value=" Majuscules obligatoires" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="chiffresRequis" value="#{configBean.securityConfig.chiffresRequis}" />
|
||||
<p:outputLabel for="chiffresRequis" value=" Chiffres obligatoires" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="caracteresSpeciaux" value="#{configBean.securityConfig.caracteresSpeciaux}" />
|
||||
<p:outputLabel for="caracteresSpeciaux" value=" Caractères spéciaux obligatoires" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="expirationMdp" value="Expiration (jours)" />
|
||||
<p:inputNumber id="expirationMdp" value="#{configBean.securityConfig.expirationMdp}"
|
||||
symbol="" min="0" max="365" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Sessions et Connexions</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="dureeSession" value="Durée session (minutes)" />
|
||||
<p:inputNumber id="dureeSession" value="#{configBean.securityConfig.dureeSession}"
|
||||
symbol="" min="15" max="1440" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="tentativesMax" value="Tentatives connexion max" />
|
||||
<p:inputNumber id="tentativesMax" value="#{configBean.securityConfig.tentativesMax}"
|
||||
symbol="" min="3" max="10" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="blocageDuree" value="Durée blocage (minutes)" />
|
||||
<p:inputNumber id="blocageDuree" value="#{configBean.securityConfig.blocageDuree}"
|
||||
symbol="" min="5" max="1440" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="connexionsMultiples" value="#{configBean.securityConfig.connexionsMultiples}" />
|
||||
<p:outputLabel for="connexionsMultiples" value=" Autoriser connexions multiples" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="doubleAuthentification" value="#{configBean.securityConfig.doubleAuthentification}" />
|
||||
<p:outputLabel for="doubleAuthentification" value=" Double authentification (2FA)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h5>Surveillance et Audit</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="logConnexions" value="#{configBean.securityConfig.logConnexions}" />
|
||||
<p:outputLabel for="logConnexions" value=" Journaliser les connexions" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="logActions" value="#{configBean.securityConfig.logActions}" />
|
||||
<p:outputLabel for="logActions" value=" Journaliser les actions" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="alertesSuspectes" value="#{configBean.securityConfig.alertesSuspectes}" />
|
||||
<p:outputLabel for="alertesSuspectes" value=" Alertes activités suspectes" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:tab>
|
||||
|
||||
<!-- Intégrations -->
|
||||
<p:tab title="🔗 Intégrations">
|
||||
<h:form id="formIntegrations">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Wave Money API</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="waveActive" value="#{configBean.waveConfig.actif}" />
|
||||
<p:outputLabel for="waveActive" value=" Activer Wave Money" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="waveApiKey" value="Clé API" />
|
||||
<p:password id="waveApiKey" value="#{configBean.waveConfig.apiKey}"
|
||||
feedback="false" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="waveSecretKey" value="Clé secrète" />
|
||||
<p:password id="waveSecretKey" value="#{configBean.waveConfig.secretKey}"
|
||||
feedback="false" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="waveEnvironnement" value="Environnement" />
|
||||
<p:selectOneMenu id="waveEnvironnement" value="#{configBean.waveConfig.environnement}">
|
||||
<f:selectItem itemLabel="Test (Sandbox)" itemValue="TEST" />
|
||||
<f:selectItem itemLabel="Production" itemValue="PROD" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Tester la connexion"
|
||||
icon="pi pi-link"
|
||||
styleClass="ui-button-outlined ui-button-info w-full"
|
||||
action="#{configBean.testerWave}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>SMS / WhatsApp</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="fournisseurSMS" value="Fournisseur SMS" />
|
||||
<p:selectOneMenu id="fournisseurSMS" value="#{configBean.smsConfig.fournisseur}">
|
||||
<f:selectItem itemLabel="Twilio" itemValue="TWILIO" />
|
||||
<f:selectItem itemLabel="Orange SMS" itemValue="ORANGE" />
|
||||
<f:selectItem itemLabel="Sonatel" itemValue="SONATEL" />
|
||||
<f:selectItem itemLabel="Custom API" itemValue="CUSTOM" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="smsApiKey" value="Clé API SMS" />
|
||||
<p:password id="smsApiKey" value="#{configBean.smsConfig.apiKey}"
|
||||
feedback="false" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="expediteurSMS" value="ID expéditeur" />
|
||||
<p:inputText id="expediteurSMS" value="#{configBean.smsConfig.expediteur}"
|
||||
placeholder="UnionFlow" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="whatsappActive" value="#{configBean.smsConfig.whatsappActif}" />
|
||||
<p:outputLabel for="whatsappActive" value=" Activer WhatsApp Business" />
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Tester SMS"
|
||||
icon="pi pi-comment"
|
||||
styleClass="ui-button-outlined ui-button-success w-full"
|
||||
action="#{configBean.testerSMS}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h5>APIs Externes</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<h6>Géolocalisation</h6>
|
||||
<div class="field">
|
||||
<p:outputLabel for="googleMapsAPI" value="Google Maps API" />
|
||||
<p:password id="googleMapsAPI" value="#{configBean.apisConfig.googleMapsKey}"
|
||||
feedback="false" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<h6>Stockage Cloud</h6>
|
||||
<div class="field">
|
||||
<p:outputLabel for="cloudProvider" value="Fournisseur" />
|
||||
<p:selectOneMenu id="cloudProvider" value="#{configBean.apisConfig.cloudProvider}">
|
||||
<f:selectItem itemLabel="Local" itemValue="LOCAL" />
|
||||
<f:selectItem itemLabel="AWS S3" itemValue="AWS" />
|
||||
<f:selectItem itemLabel="Google Cloud" itemValue="GCP" />
|
||||
<f:selectItem itemLabel="Azure" itemValue="AZURE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<h6>Analytics</h6>
|
||||
<div class="field">
|
||||
<p:outputLabel for="googleAnalytics" value="Google Analytics ID" />
|
||||
<p:inputText id="googleAnalytics" value="#{configBean.apisConfig.googleAnalyticsId}"
|
||||
placeholder="GA-XXXXXXXXX" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:tab>
|
||||
|
||||
<!-- Performance -->
|
||||
<p:tab title="⚡ Performance">
|
||||
<h:form id="formPerformance">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Cache et Mémoire</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="cacheActive" value="#{configBean.perfConfig.cacheActif}" />
|
||||
<p:outputLabel for="cacheActive" value=" Activer le cache" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="dureeCacheDefault" value="Durée cache par défaut (minutes)" />
|
||||
<p:inputNumber id="dureeCacheDefault" value="#{configBean.perfConfig.dureeCacheDefault}"
|
||||
symbol="" min="1" max="1440" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="tailleCacheMax" value="Taille cache max (MB)" />
|
||||
<p:inputNumber id="tailleCacheMax" value="#{configBean.perfConfig.tailleCacheMax}"
|
||||
symbol="" min="10" max="1024" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="compressionActive" value="Compression" />
|
||||
<p:selectBooleanCheckbox id="compressionActive" value="#{configBean.perfConfig.compressionActive}" />
|
||||
<p:outputLabel for="compressionActive" value=" Activer compression GZIP" />
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Vider le cache"
|
||||
icon="pi pi-trash"
|
||||
styleClass="ui-button-outlined ui-button-warning w-full"
|
||||
action="#{configBean.viderCache}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Base de Données</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="poolConnexionsMin" value="Pool connexions min" />
|
||||
<p:inputNumber id="poolConnexionsMin" value="#{configBean.perfConfig.poolConnexionsMin}"
|
||||
symbol="" min="1" max="50" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="poolConnexionsMax" value="Pool connexions max" />
|
||||
<p:inputNumber id="poolConnexionsMax" value="#{configBean.perfConfig.poolConnexionsMax}"
|
||||
symbol="" min="5" max="200" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="timeoutRequete" value="Timeout requête (secondes)" />
|
||||
<p:inputNumber id="timeoutRequete" value="#{configBean.perfConfig.timeoutRequete}"
|
||||
symbol="" min="5" max="300" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="logSlowQueries" value="#{configBean.perfConfig.logSlowQueries}" />
|
||||
<p:outputLabel for="logSlowQueries" value=" Journaliser requêtes lentes" />
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Optimiser base"
|
||||
icon="pi pi-cog"
|
||||
styleClass="ui-button-outlined ui-button-info w-full"
|
||||
action="#{configBean.optimiserBase}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h5>Monitoring en Temps Réel</h5>
|
||||
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-2xl font-bold text-blue-500 mb-2">#{configBean.cpuUsage}%</div>
|
||||
<div class="text-600">Utilisation CPU</div>
|
||||
<p:progressBar value="#{configBean.cpuUsage}" styleClass="mt-2 h-1rem" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-2xl font-bold text-green-500 mb-2">#{configBean.memoryUsage}%</div>
|
||||
<div class="text-600">Mémoire Utilisée</div>
|
||||
<p:progressBar value="#{configBean.memoryUsage}" styleClass="mt-2 h-1rem" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-2xl font-bold text-orange-500 mb-2">#{configBean.activeConnections}</div>
|
||||
<div class="text-600">Connexions Actives</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="text-center p-3 surface-50 border-round">
|
||||
<div class="text-2xl font-bold text-purple-500 mb-2">#{configBean.responseTime}ms</div>
|
||||
<div class="text-600">Temps Réponse Moy.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:tab>
|
||||
|
||||
<!-- Maintenance -->
|
||||
<p:tab title="🔧 Maintenance">
|
||||
<h:form id="formMaintenance">
|
||||
<div class="ui-fluid">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Sauvegarde Automatique</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="sauvegardeAuto" value="#{configBean.maintenanceConfig.sauvegardeAuto}" />
|
||||
<p:outputLabel for="sauvegardeAuto" value=" Sauvegarde automatique" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="frequenceSauvegarde" value="Fréquence" />
|
||||
<p:selectOneMenu id="frequenceSauvegarde" value="#{configBean.maintenanceConfig.frequenceSauvegarde}">
|
||||
<f:selectItem itemLabel="Quotidienne" itemValue="DAILY" />
|
||||
<f:selectItem itemLabel="Hebdomadaire" itemValue="WEEKLY" />
|
||||
<f:selectItem itemLabel="Mensuelle" itemValue="MONTHLY" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="heureSauvegarde" value="Heure de sauvegarde" />
|
||||
<p:calendar id="heureSauvegarde" value="#{configBean.maintenanceConfig.heureSauvegarde}"
|
||||
pattern="HH:mm" timeOnly="true" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="retentionSauvegardes" value="Rétention (jours)" />
|
||||
<p:inputNumber id="retentionSauvegardes" value="#{configBean.maintenanceConfig.retentionSauvegardes}"
|
||||
symbol="" min="7" max="365" />
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Sauvegarder maintenant"
|
||||
icon="pi pi-save"
|
||||
styleClass="ui-button-success w-full"
|
||||
action="#{configBean.sauvegarderMaintenant}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="card">
|
||||
<h5>Nettoyage et Maintenance</h5>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="nettoyageAuto" value="#{configBean.maintenanceConfig.nettoyageAuto}" />
|
||||
<p:outputLabel for="nettoyageAuto" value=" Nettoyage automatique des logs" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="retentionLogs" value="Rétention logs (jours)" />
|
||||
<p:inputNumber id="retentionLogs" value="#{configBean.maintenanceConfig.retentionLogs}"
|
||||
symbol="" min="7" max="90" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:selectBooleanCheckbox id="optimisationAuto" value="#{configBean.maintenanceConfig.optimisationAuto}" />
|
||||
<p:outputLabel for="optimisationAuto" value=" Optimisation automatique des tables" />
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Nettoyer logs"
|
||||
icon="pi pi-trash"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
action="#{configBean.nettoyerLogs}" />
|
||||
<p:commandButton value="Optimiser DB"
|
||||
icon="pi pi-cog"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{configBean.optimiserDB}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h5>Mode Maintenance</h5>
|
||||
|
||||
<div class="surface-50 p-3 border-round mb-3">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-info-circle text-blue-500 mr-2"></i>
|
||||
<div class="text-600">
|
||||
Le mode maintenance bloque l'accès utilisateur pendant les opérations critiques.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="messageMaintenance" value="Message de maintenance" />
|
||||
<p:inputTextarea id="messageMaintenance" value="#{configBean.maintenanceConfig.messageMaintenance}"
|
||||
rows="3" placeholder="Le système est temporairement indisponible..." />
|
||||
</div>
|
||||
|
||||
<p:commandButton value="#{configBean.maintenanceConfig.modeMaintenanceActif ? 'Désactiver' : 'Activer'} maintenance"
|
||||
icon="pi #{configBean.maintenanceConfig.modeMaintenanceActif ? 'pi-play' : 'pi-pause'}"
|
||||
styleClass="ui-button-#{configBean.maintenanceConfig.modeMaintenanceActif ? 'success' : 'danger'} w-full"
|
||||
action="#{configBean.toggleModeMaintenance}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
</div>
|
||||
|
||||
<!-- Actions globales -->
|
||||
<div class="card">
|
||||
<div class="flex justify-content-center gap-3">
|
||||
<p:commandButton value="💾 Sauvegarder toute la configuration"
|
||||
icon="pi pi-save"
|
||||
styleClass="ui-button-success"
|
||||
action="#{configBean.sauvegarderTout}" />
|
||||
<p:commandButton value="🔄 Redémarrer application"
|
||||
icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
onclick="return confirm('Redémarrer l\\'application ? Tous les utilisateurs seront déconnectés.');"
|
||||
action="#{configBean.redemarrerApplication}" />
|
||||
<p:commandButton value="📋 Voir logs système"
|
||||
icon="pi pi-list"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{configBean.voirLogs}" />
|
||||
<p:commandButton value="📊 Rapport de santé"
|
||||
icon="pi pi-chart-line"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{configBean.genererRapportSante}" />
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user