fix(client): version 1.0.4, accesseurs JavaBean sur OrganisationSummaryResponse (compat JSF/EL)

This commit is contained in:
dahoud
2026-04-11 02:00:48 +00:00
parent 05b97f04cd
commit 237922891d
30 changed files with 898 additions and 220 deletions

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>dev.lions.unionflow</groupId>
<artifactId>unionflow-parent</artifactId>
<version>1.0.3</version>
<version>1.0.4</version>
<relativePath>../unionflow-server-api/parent-pom.xml</relativePath>
</parent>
@@ -129,7 +129,7 @@
<dependency>
<groupId>dev.lions.unionflow</groupId>
<artifactId>unionflow-server-api</artifactId>
<version>1.0.3</version>
<version>1.0.4</version>
</dependency>
<!-- Lions User Manager Client - Module réutilisable de gestion d'utilisateurs Keycloak -->

View File

@@ -1,5 +1,9 @@
package dev.lions.unionflow.client.api.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
@@ -7,29 +11,33 @@ import java.time.LocalDate;
/**
* DTO received from the backend for the member dashboard synthesis.
*/
public record MembreDashboardResponse(
String prenom,
String nom,
LocalDate dateInscription,
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MembreDashboardResponse implements Serializable {
// Cotisations
BigDecimal mesCotisationsPaiement,
String statutCotisations,
Integer tauxCotisationsPerso,
private String prenom;
private String nom;
private LocalDate dateInscription;
// Epargne
BigDecimal monSoldeEpargne,
BigDecimal evolutionEpargneNombre,
String evolutionEpargne,
Integer objectifEpargne,
// Cotisations
private BigDecimal mesCotisationsPaiement;
private String statutCotisations;
private Integer tauxCotisationsPerso;
// Evenements
Integer mesEvenementsInscrits,
Integer evenementsAVenir,
Integer tauxParticipationPerso,
// Epargne
private BigDecimal monSoldeEpargne;
private BigDecimal evolutionEpargneNombre;
private String evolutionEpargne;
private Integer objectifEpargne;
// Aides
Integer mesDemandesAide,
Integer aidesEnCours,
Integer tauxAidesApprouvees) implements Serializable {
// Evenements
private Integer mesEvenementsInscrits;
private Integer evenementsAVenir;
private Integer tauxParticipationPerso;
// Aides
private Integer mesDemandesAide;
private Integer aidesEnCours;
private Integer tauxAidesApprouvees;
}

View File

@@ -152,11 +152,11 @@ public class AdhesionsBean implements Serializable {
items.add(new SelectItem(null, "Sélectionner une organisation"));
if (listeAssociations != null) {
for (OrganisationSummaryResponse assoc : listeAssociations) {
String label = assoc.nom();
if (assoc.typeOrganisation() != null) {
label += " (" + assoc.typeOrganisation() + ")";
String label = assoc.getNom();
if (assoc.getTypeOrganisation() != null) {
label += " (" + assoc.getTypeOrganisation() + ")";
}
items.add(new SelectItem(assoc.id(), label));
items.add(new SelectItem(assoc.getId(), label));
}
}
return items;

View File

@@ -680,7 +680,7 @@ public class CotisationsBean implements Serializable {
try {
IntentionStatutResponse statut = paiementClientService.getStatutIntention(waveIntentionId);
this.waveStatut = statut.statut();
this.waveStatut = statut.getStatut();
if ("COMPLETEE".equals(waveStatut)) {
waveDialogOuvert = false;

View File

@@ -352,8 +352,8 @@ public class CotisationsGestionBean implements Serializable {
if (response != null && response.getData() != null) {
for (OrganisationSummaryResponse assoc : response.getData()) {
Organisation org = new Organisation();
org.setId(assoc.id());
org.setNom(assoc.nom());
org.setId(assoc.getId());
org.setNom(assoc.getNom());
listeOrganisations.add(org);
}
}
@@ -391,7 +391,7 @@ public class CotisationsGestionBean implements Serializable {
for (OrganisationSummaryResponse assoc : associations.stream().limit(5).collect(Collectors.toList())) {
List<CotisationResponse> cotisationsOrg = cotisationsDTO.stream()
.filter(c -> c.getOrganisationId() != null && c.getOrganisationId().equals(assoc.id()))
.filter(c -> c.getOrganisationId() != null && c.getOrganisationId().equals(assoc.getId()))
.collect(Collectors.toList());
long total = cotisationsOrg.size();
@@ -404,7 +404,7 @@ public class CotisationsGestionBean implements Serializable {
.reduce(BigDecimal.ZERO, BigDecimal::add);
OrganisationPerformante org = new OrganisationPerformante();
org.setNom(assoc.nom());
org.setNom(assoc.getNom());
org.setTauxRecouvrement(taux);
org.setMontantCollecte(formatMontant(montantCollecte));
org.setNombreMembresAJour((int) payees);

View File

@@ -94,22 +94,22 @@ public class DashboardMembreBean implements Serializable {
try {
MembreDashboardResponse data = dashboardClient.getMonDashboard();
if (data != null) {
this.prenomMembre = data.prenom();
this.nomMembre = data.nom();
this.dateInscription = data.dateInscription();
this.mesCotisationsPaiement = formatMontant(data.mesCotisationsPaiement());
this.statutCotisations = data.statutCotisations() != null ? data.statutCotisations() : "Non disponible";
this.tauxCotisationsPerso = data.tauxCotisationsPerso();
this.monSoldeEpargne = formatMontant(data.monSoldeEpargne());
this.evolutionEpargneNombre = formatMontant(data.evolutionEpargneNombre());
this.evolutionEpargne = data.evolutionEpargne() != null ? data.evolutionEpargne() : "+0%";
this.objectifEpargne = data.objectifEpargne();
this.mesEvenementsInscrits = data.mesEvenementsInscrits() != null ? data.mesEvenementsInscrits() : 0;
this.evenementsAVenir = data.evenementsAVenir() != null ? data.evenementsAVenir() : 0;
this.tauxParticipationPerso = data.tauxParticipationPerso();
this.mesDemandesAide = data.mesDemandesAide() != null ? data.mesDemandesAide() : 0;
this.aidesEnCours = data.aidesEnCours() != null ? data.aidesEnCours() : 0;
this.tauxAidesApprouvees = data.tauxAidesApprouvees();
this.prenomMembre = data.getPrenom();
this.nomMembre = data.getNom();
this.dateInscription = data.getDateInscription();
this.mesCotisationsPaiement = formatMontant(data.getMesCotisationsPaiement());
this.statutCotisations = data.getStatutCotisations() != null ? data.getStatutCotisations() : "Non disponible";
this.tauxCotisationsPerso = data.getTauxCotisationsPerso();
this.monSoldeEpargne = formatMontant(data.getMonSoldeEpargne());
this.evolutionEpargneNombre = formatMontant(data.getEvolutionEpargneNombre());
this.evolutionEpargne = data.getEvolutionEpargne() != null ? data.getEvolutionEpargne() : "+0%";
this.objectifEpargne = data.getObjectifEpargne();
this.mesEvenementsInscrits = data.getMesEvenementsInscrits() != null ? data.getMesEvenementsInscrits() : 0;
this.evenementsAVenir = data.getEvenementsAVenir() != null ? data.getEvenementsAVenir() : 0;
this.tauxParticipationPerso = data.getTauxParticipationPerso();
this.mesDemandesAide = data.getMesDemandesAide() != null ? data.getMesDemandesAide() : 0;
this.aidesEnCours = data.getAidesEnCours() != null ? data.getAidesEnCours() : 0;
this.tauxAidesApprouvees = data.getTauxAidesApprouvees();
}
} catch (Exception e) {
LOG.error("Erreur chargement KPI dashboard", e);

View File

@@ -113,10 +113,10 @@ public class EntitesGestionBean implements Serializable {
associations = response.getData();
}
statistiques.setTotalEntites(associations.size());
long actives = associations.stream().filter(a -> "ACTIVE".equals(a.statut())).count();
long actives = associations.stream().filter(a -> "ACTIVE".equals(a.getStatut())).count();
statistiques.setEntitesActives((int) actives);
int totalMembres = associations.stream()
.mapToInt(a -> a.nombreMembres() != null ? a.nombreMembres() : 0)
.mapToInt(a -> a.getNombreMembres() != null ? a.getNombreMembres() : 0)
.sum();
statistiques.setTotalMembres(totalMembres);
double moyenne = associations.isEmpty() ? 0 : (double) totalMembres / associations.size();
@@ -154,15 +154,15 @@ public class EntitesGestionBean implements Serializable {
private Entite convertToEntite(OrganisationSummaryResponse dto) {
Entite entite = new Entite();
entite.setId(dto.id());
entite.setNom(dto.nom());
entite.setCodeEntite(dto.nomCourt()); // Using nomCourt as code
entite.setType(dto.typeOrganisation());
entite.setTypeLibelle(typeCatalogueService.resolveLibelle(dto.typeOrganisation()));
entite.setId(dto.getId());
entite.setNom(dto.getNom());
entite.setCodeEntite(dto.getNomCourt()); // Using nomCourt as code
entite.setType(dto.getTypeOrganisation());
entite.setTypeLibelle(typeCatalogueService.resolveLibelle(dto.getTypeOrganisation()));
entite.setRegion(null); // Not available in Summary
entite.setStatut(dto.statut());
entite.setNombreMembres(dto.nombreMembres() != null ? dto.nombreMembres() : 0);
entite.setMembresUtilises(dto.nombreMembres() != null ? dto.nombreMembres() : 0);
entite.setStatut(dto.getStatut());
entite.setNombreMembres(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0);
entite.setMembresUtilises(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0);
entite.setAdresse(null); // Not available in Summary
entite.setTelephone(null); // Not available in Summary
entite.setEmail(null); // Not available in Summary
@@ -170,7 +170,7 @@ public class EntitesGestionBean implements Serializable {
entite.setDerniereActivite(null); // Not available in Summary
try {
SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(dto.id());
SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(dto.getId());
if (souscription != null) {
entite.setForfaitSouscrit(
souscription.getPlanCommercial() != null ? souscription.getPlanCommercial() : "Non défini");
@@ -572,7 +572,7 @@ public class EntitesGestionBean implements Serializable {
for (OrganisationSummaryResponse assoc : associations) {
try {
SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(assoc.id());
SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(assoc.getId());
if (souscription != null) {
totalSouscriptions++;
if ("ACTIVE".equals(souscription.getStatut())) {

View File

@@ -98,8 +98,8 @@ public class MembreExportBean implements Serializable {
: new ArrayList<>();
for (OrganisationSummaryResponse assoc : associations) {
OrganisationResponse org = new OrganisationResponse();
org.setId(assoc.id());
org.setNom(assoc.nom());
org.setId(assoc.getId());
org.setNom(assoc.getNom());
org.setVille(null /* ville not in Summary */);
organisationsDisponibles.add(org);
}

View File

@@ -81,8 +81,8 @@ public class MembreImportBean implements Serializable {
: new ArrayList<>();
for (OrganisationSummaryResponse assoc : associations) {
OrganisationResponse org = new OrganisationResponse();
org.setId(assoc.id());
org.setNom(assoc.nom());
org.setId(assoc.getId());
org.setNom(assoc.getNom());
org.setVille(null /* ville not in Summary */);
organisationsDisponibles.add(org);
}

View File

@@ -97,7 +97,7 @@ public class MembreLazyDataModel extends LazyDataModelBase<MembreSummaryResponse
@Override
public String getRowKey(MembreSummaryResponse object) {
return object != null && object.id() != null ? object.id().toString() : null;
return object != null && object.getId() != null ? object.getId().toString() : null;
}
@Override

View File

@@ -148,8 +148,8 @@ public class MembreRechercheBean implements Serializable {
if (response != null && response.getData() != null) {
for (dev.lions.unionflow.server.api.dto.organisation.response.OrganisationSummaryResponse assoc : response.getData()) {
Entite entite = new Entite();
entite.setId(assoc.id());
entite.setNom(assoc.nom());
entite.setId(assoc.getId());
entite.setNom(assoc.getNom());
entitesDisponibles.add(entite);
}
}

View File

@@ -70,9 +70,9 @@ public class MessagingBean implements Serializable {
public void ouvrirConversation(ConversationResponse conversation) {
this.conversationActive = conversation;
chargerMessages(conversation.id());
chargerMessages(conversation.getId());
try {
conversationService.marquerCommeLue(conversation.id());
conversationService.marquerCommeLue(conversation.getId());
} catch (Exception e) {
LOGGER.warning("Impossible de marquer comme lue: " + e.getMessage());
}
@@ -94,7 +94,7 @@ public class MessagingBean implements Serializable {
}
try {
SendMessageRequest request = SendMessageRequest.builder()
.conversationId(conversationActive.id())
.conversationId(conversationActive.getId())
.content(contenuMessage.trim())
.build();
MessageResponse envoye = messageService.envoyer(request);
@@ -135,7 +135,7 @@ public class MessagingBean implements Serializable {
public void archiverConversation(ConversationResponse conversation) {
try {
conversationService.archiver(conversation.id(), !conversation.isArchived());
conversationService.archiver(conversation.getId(), !conversation.isArchived());
chargerConversations();
} catch (Exception e) {
ajouterMessageErreur("Impossible de modifier la conversation.");
@@ -144,7 +144,7 @@ public class MessagingBean implements Serializable {
public void basculerSilence(ConversationResponse conversation) {
try {
conversationService.basculerSilence(conversation.id());
conversationService.basculerSilence(conversation.getId());
chargerConversations();
} catch (Exception e) {
ajouterMessageErreur("Impossible de modifier le silence.");
@@ -153,7 +153,7 @@ public class MessagingBean implements Serializable {
public void basculerEpinglage(ConversationResponse conversation) {
try {
conversationService.basculerEpinglage(conversation.id());
conversationService.basculerEpinglage(conversation.getId());
chargerConversations();
} catch (Exception e) {
ajouterMessageErreur("Impossible de modifier l'épinglage.");
@@ -162,7 +162,7 @@ public class MessagingBean implements Serializable {
public void supprimerMessage(MessageResponse message) {
try {
messageService.supprimer(message.id());
messageService.supprimer(message.getId());
messagesConversationActive.remove(message);
ajouterMessageSucces("Message supprimé.");
} catch (Exception e) {
@@ -173,7 +173,7 @@ public class MessagingBean implements Serializable {
public void actualiser() {
chargerConversations();
if (conversationActive != null) {
chargerMessages(conversationActive.id());
chargerMessages(conversationActive.getId());
}
}

View File

@@ -82,7 +82,7 @@ public class OrganisationStatistiquesBean implements Serializable {
long total = organisations.size();
long actives = organisations.stream()
.filter(o -> o.statut() != null && StatutOrganisationConstants.ACTIVE.equals(o.statut()))
.filter(o -> o.getStatut() != null && StatutOrganisationConstants.ACTIVE.equals(o.getStatut()))
.count();
long inactives = total - actives;

View File

@@ -159,7 +159,7 @@ public class OrganisationsBean implements Serializable {
totalOrganisations = toutes.size();
organisationsActives = toutes.stream()
.filter(o -> o.statut() != null && StatutOrganisationConstants.ACTIVE.equals(o.statut()))
.filter(o -> o.getStatut() != null && StatutOrganisationConstants.ACTIVE.equals(o.getStatut()))
.count();
organisationsInactives = totalOrganisations - organisationsActives;
@@ -321,7 +321,7 @@ public class OrganisationsBean implements Serializable {
public void preparerModification(OrganisationSummaryResponse org) {
try {
organisationSelectionnee = retryService.executeWithRetrySupplier(
() -> organisationService.obtenirParId(org.id()),
() -> organisationService.obtenirParId(org.getId()),
"chargement de l'organisation pour modification");
} catch (Exception e) {
errorHandler.handleException(e, "lors du chargement de l'organisation", null);
@@ -368,9 +368,9 @@ public class OrganisationsBean implements Serializable {
*/
public void preparerSuppression(OrganisationSummaryResponse org) {
OrganisationResponse full = new OrganisationResponse();
full.setId(org.id());
full.setNom(org.nom());
full.setStatut(org.statut());
full.setId(org.getId());
full.setNom(org.getNom());
full.setStatut(org.getStatut());
organisationPourSuppression = full;
}
@@ -399,9 +399,9 @@ public class OrganisationsBean implements Serializable {
*/
public void preparerBasculerStatut(OrganisationSummaryResponse org) {
OrganisationResponse full = new OrganisationResponse();
full.setId(org.id());
full.setNom(org.nom());
full.setStatut(org.statut());
full.setId(org.getId());
full.setNom(org.getNom());
full.setStatut(org.getStatut());
organisationPourStatut = full;
}
@@ -609,22 +609,22 @@ public class OrganisationsBean implements Serializable {
.filter(org -> {
if (rechercheGlobale != null && !rechercheGlobale.trim().isEmpty()) {
String recherche = rechercheGlobale.toLowerCase();
return (org.nom() != null && org.nom().toLowerCase().contains(recherche)) ||
(org.nomCourt() != null && org.nomCourt().toLowerCase().contains(recherche)) ||
(org.typeOrganisationLibelle() != null
&& org.typeOrganisationLibelle().toLowerCase().contains(recherche));
return (org.getNom() != null && org.getNom().toLowerCase().contains(recherche)) ||
(org.getNomCourt() != null && org.getNomCourt().toLowerCase().contains(recherche)) ||
(org.getTypeOrganisationLibelle() != null
&& org.getTypeOrganisationLibelle().toLowerCase().contains(recherche));
}
return true;
})
.filter(org -> {
if (filtreStatut != null && !filtreStatut.trim().isEmpty()) {
return filtreStatut.equals(org.statut());
return filtreStatut.equals(org.getStatut());
}
return true;
})
.filter(org -> {
if (filtreType != null && !filtreType.trim().isEmpty()) {
return filtreType.equals(org.typeOrganisation());
return filtreType.equals(org.getTypeOrganisation());
}
return true;
})

View File

@@ -339,17 +339,17 @@ public class SuperAdminBean implements Serializable {
: new ArrayList<>();
topEntites = associations.stream()
.sorted((a1, a2) -> {
int m1 = a1.nombreMembres() != null ? a1.nombreMembres() : 0;
int m2 = a2.nombreMembres() != null ? a2.nombreMembres() : 0;
int m1 = a1.getNombreMembres() != null ? a1.getNombreMembres() : 0;
int m2 = a2.getNombreMembres() != null ? a2.getNombreMembres() : 0;
return Integer.compare(m2, m1);
})
.limit(5)
.map(a -> {
Entite entite = new Entite();
entite.setId(a.id());
entite.setNom(a.nom());
entite.setTypeEntite(a.typeOrganisation());
entite.setNombreMembres(a.nombreMembres() != null ? a.nombreMembres() : 0);
entite.setId(a.getId());
entite.setNom(a.getNom());
entite.setTypeEntite(a.getTypeOrganisation());
entite.setNombreMembres(a.getNombreMembres() != null ? a.getNombreMembres() : 0);
return entite;
})
.collect(java.util.stream.Collectors.toList());

View File

@@ -91,8 +91,8 @@ public class UtilisateursBean implements Serializable {
: new ArrayList<>();
for (OrganisationSummaryResponse assoc : associations) {
Organisation org = new Organisation();
org.setId(assoc.id());
org.setNom(assoc.nom());
org.setId(assoc.getId());
org.setNom(assoc.getNom());
organisationsDisponibles.add(org);
}
} catch (Exception e) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -13,7 +13,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<!-- Obsolète : apple-mobile-web-app-capable. Remplacé par mobile-web-app-capable -->
<meta name="mobile-web-app-capable" content="yes" />
<link rel="icon" href="#{request.contextPath}/resources/freya-layout/images/favicon.ico" type="image/x-icon" />
<link rel="icon" href="#{request.contextPath}/resources/freya-layout/images/unionflow-logo.png" type="image/png" />
</f:facet>
<title>UnionFlow - Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs</title>
@@ -23,6 +23,7 @@
<h:outputStylesheet name="css/primeflex.min.css" library="freya-layout" />
<h:outputStylesheet name="css/layout-#{guestPreferences.layout}.css" library="freya-layout" />
<h:outputStylesheet name="primefaces-freya-#{guestPreferences.componentTheme}/theme.css" />
<h:outputStylesheet name="css/topbar-elite.css" />
<meta name="description" content="UnionFlow : La solution complète de gestion pour les mutuelles, associations, clubs (informatiques, juridiques, etc.) et organisations similaires. Gestion des membres, cotisations, événements, solidarité et analytics." />
</h:head>
@@ -31,8 +32,13 @@
<!-- Landing Topbar -->
<div class="landing-topbar">
<div class="landing-topbar-left">
<h:link id="logolink" outcome="/pages/secure/dashboard" styleClass="logo">
<p:graphicImage name="images/logo-freya.svg" library="freya-layout" />
<h:link id="logolink" outcome="/pages/secure/dashboard" styleClass="logo unionflow-brand unionflow-brand--landing">
<h:graphicImage value="#{request.contextPath}/resources/freya-layout/images/unionflow-logo.png"
alt="Logo UnionFlow"
styleClass="unionflow-brand-icon" />
<span class="unionflow-brand-text">
<span class="unionflow-brand-name">UNIONFLOW</span>
</span>
</h:link>
<ul class="landing-menu">
@@ -75,8 +81,8 @@
<div id="home" class="landing-banner">
<div class="landing-banner-content">
<span class="title">UnionFlow</span>
<h3>Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs<br/>
Simplifiez la gestion de votre organisation avec une solution complète et moderne</h3>
<h3>Fédérez vos membres. Sécurisez vos flux. Pilotez l'avenir.<br/>
Oubliez la gestion manuelle. La plateforme technologique financière qui apporte transparence et rigueur à votre organisation.</h3>
<a href="#{request.contextPath}/pages/secure/dashboard.xhtml"
style="display:inline-flex;align-items:center;gap:.6rem;
padding:1rem 2.5rem;border-radius:8px;
@@ -103,8 +109,8 @@
<div class="feature-card">
<span>1</span>
<div class="card-content">
<h3>Gestion des Membres</h3>
<h5>Inscription, profils détaillés, gestion des statuts, historique des adhésions et suivi complet de chaque membre.</h5>
<h3>Maîtrisez votre Base Membres</h3>
<h5>Finies les listes papier perdues. Centralisez les profils, gérez les statuts et gardez le contact avec votre communauté.</h5>
</div>
</div>
</div>
@@ -118,8 +124,8 @@
<div class="feature-card">
<span>2</span>
<div class="card-content">
<h3>Gestion des Cotisations</h3>
<h5>Types variés (mensuelle, annuelle, adhésion, événement, formation, projet, solidarité), suivi des paiements et rappels automatiques. <strong>Paiements sécurisés via Wave</strong> (bientôt disponible).</h5>
<h3>Sécurisez vos Collectes</h3>
<h5>Automatisez vos appels à cotisation, suivez vos tontines en temps réel et intégrez <strong>les paiements par mobile money (ex: Wave)</strong>.</h5>
<div style="margin-top: 10px;">
<!-- Image locale du client (servie depuis META-INF/resources/images) -->
<h:graphicImage value="#{request.contextPath}/images/logo-wave.png" style="max-height: 30px; width: auto;" alt="Wave - Paiements mobiles" />
@@ -134,8 +140,8 @@
<div class="feature-card">
<span>3</span>
<div class="card-content">
<h3>Organisation<br/>d'Événements</h3>
<h5>Assemblées générales, réunions, formations, conférences, ateliers, séminaires, événements sociaux avec gestion des inscriptions.</h5>
<h3>Faites vivre<br/>vos Réunions et AG</h3>
<h5>Gérez l'organisation des assemblées générales, traquez les présences lors des réunions statutaires et boostez l'engagement.</h5>
</div>
</div>
</div>
@@ -150,8 +156,8 @@
<div class="feature-card">
<span>4</span>
<div class="card-content">
<h3>Système de Solidarité</h3>
<h5>Gestion complète des demandes d'aide, propositions, évaluations, suivi des statuts et coordination des actions solidaires.</h5>
<h3>L'entraide Transparente</h3>
<h5>Sécurisez la gestion de vos cas sociaux (décès, maladie). Approuvez et décaissez les aides avec une traçabilité totale.</h5>
</div>
</div>
</div>
@@ -162,8 +168,8 @@
<div class="feature-card">
<span>5</span>
<div class="card-content">
<h3>Gestion des Organisations</h3>
<h5>Gestion des clubs et unions avec hiérarchie organisationnelle, statistiques détaillées, rapports et vue d'ensemble complète.</h5>
<h3>Scalabilité Absolue</h3>
<h5>Conçu pour évoluer : d'une amicale de quartier à un district international du Lions ou Rotary Club avec des milliers de membres.</h5>
</div>
</div>
</div>
@@ -176,8 +182,8 @@
<div class="feature-card">
<span>6</span>
<div class="card-content">
<h3>Analytics &amp; Rapports</h3>
<h5>Tableaux de bord interactifs, KPIs en temps réel, analyses approfondies et rapports personnalisables pour une prise de décision éclairée.</h5>
<h3>Reporting et Audit</h3>
<h5>Générez des états financiers en un clic pour vos comptabilités et instaurez une gouvernance irréprochable.</h5>
</div>
</div>
</div>
@@ -188,9 +194,9 @@
<!-- Benefits Section -->
<div id="benefits" class="landing-pricing">
<div class="section-header">
<span class="title">Pourquoi choisir UnionFlow ?</span>
<h3>Une plateforme robuste et moderne bâtie pour les organisations du monde entier<br/>
avec une sensibilité particulière pour les réalités africaines.</h3>
<span class="title">La technologie au service de la gouvernance</span>
<h3>Toute la rigueur exigée par les institutions, accessible depuis votre mobile<br/>
conçu avec une fine compréhension des réalités associatives africaines et mondiales.</h3>
</div>
<!-- Grille des avantages -->
@@ -214,15 +220,15 @@
<ul style="list-style:none;padding:0;margin:0;">
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
<i class="pi pi-check" style="color:var(--green-500);"></i>
OpenID Connect via Keycloak
Infrastructure hautement sécurisée
</li>
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
<i class="pi pi-check" style="color:var(--green-500);"></i>
Contrôle d'accès granulaire par rôle
Chaque action est loggée et traçable
</li>
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);font-size:.85rem;">
<i class="pi pi-check" style="color:var(--green-500);"></i>
Chiffrement de bout en bout
Droits de validation croisée stricts
</li>
</ul>
</div>
@@ -269,16 +275,16 @@
<i class="pi pi-server" style="color:var(--purple-600);font-size:1.25rem;"></i>
</div>
<h3 style="color:var(--text-color);font-size:1.1rem;font-weight:700;margin:0 0 .75rem 0;">
Architecture cloud-native
Architecture ultra-rapide
</h3>
<p style="color:var(--text-color-secondary);line-height:1.7;margin:0 0 1.25rem 0;font-size:.9rem;">
Bâtie sur Quarkus et une architecture microservices, la plateforme monte en
charge automatiquement et garantit une haute disponibilité.
Bâtie sur des technologies cloud de dernière génération, la plateforme reste
fluide et instantanée même avec des milliers de transactions.
</p>
<ul style="list-style:none;padding:0;margin:0;">
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
<i class="pi pi-check" style="color:var(--green-500);"></i>
Microservices Quarkus haute performance
Temps de réponse quasi-instantané
</li>
<li style="display:flex;align-items:center;gap:.5rem;color:var(--text-color-secondary);margin-bottom:.4rem;font-size:.85rem;">
<i class="pi pi-check" style="color:var(--green-500);"></i>

View File

@@ -15,9 +15,9 @@
<div class="card">
<div class="flex align-items-center justify-content-between">
<div class="flex align-items-center">
<div class="bg-blue-100 border-circle flex align-items-center justify-content-center mr-3"
<div class="uf-bg-navy-light border-circle flex align-items-center justify-content-center mr-3"
style="width:60px;height:60px;">
<i class="pi pi-user text-blue-600 text-3xl"></i>
<i class="pi pi-user uf-text-navy text-3xl"></i>
</div>
<div>
<h4 class="m-0 text-900">Bienvenue, #{dashboardMembreBean.prenomMembre}</h4>
@@ -42,7 +42,7 @@
<ui:param name="title" value="Mes Cotisations" />
<ui:param name="value" value="#{dashboardMembreBean.statutCotisations}" />
<ui:param name="icon" value="pi-wallet" />
<ui:param name="iconColor" value="green-600" />
<ui:param name="iconColor" value="uf-text-forest" />
<ui:param name="growthValue" value="#{dashboardMembreBean.mesCotisationsPaiement}" />
<ui:param name="growthLabel" value="FCFA payés ce mois" />
<ui:param name="growthType" value="number" />
@@ -55,7 +55,7 @@
<ui:param name="title" value="Mon Épargne" />
<ui:param name="value" value="#{dashboardMembreBean.monSoldeEpargne} FCFA" />
<ui:param name="icon" value="pi-money-bill" />
<ui:param name="iconColor" value="blue-600" />
<ui:param name="iconColor" value="uf-text-navy" />
<ui:param name="growthValue" value="#{dashboardMembreBean.evolutionEpargneNombre}" />
<ui:param name="growthLabel" value="FCFA ce mois" />
<ui:param name="growthType" value="number" />
@@ -68,7 +68,7 @@
<ui:param name="title" value="Mes Événements" />
<ui:param name="value" value="#{dashboardMembreBean.mesEvenementsInscrits}" />
<ui:param name="icon" value="pi-calendar" />
<ui:param name="iconColor" value="purple-600" />
<ui:param name="iconColor" value="uf-text-gold" />
<ui:param name="growthValue" value="#{dashboardMembreBean.evenementsAVenir}" />
<ui:param name="growthLabel" value="à venir" />
<ui:param name="growthType" value="number" />
@@ -81,7 +81,7 @@
<ui:param name="title" value="Mes Aides" />
<ui:param name="value" value="#{dashboardMembreBean.mesDemandesAide}" />
<ui:param name="icon" value="pi-heart" />
<ui:param name="iconColor" value="orange-600" />
<ui:param name="iconColor" value="uf-text-crimson" />
<ui:param name="growthValue" value="#{dashboardMembreBean.aidesEnCours}" />
<ui:param name="growthLabel" value="en traitement" />
<ui:param name="growthType" value="number" />
@@ -149,7 +149,7 @@
<span>#{cotisAtt.periode}</span>
</p:column>
<p:column headerText="Montant dû">
<span class="font-medium text-orange-600">#{cotisAtt.montantFormatte} FCFA</span>
<span class="font-medium uf-text-gold">#{cotisAtt.montantFormatte} FCFA</span>
</p:column>
<p:column headerText="Échéance" style="width:110px">
<h:outputText value="#{cotisAtt.dateEcheance}">
@@ -228,25 +228,25 @@
<div class="card">
<h5>Statut de mes cotisations</h5>
<div class="flex flex-column gap-3">
<div class="flex align-items-center justify-content-between p-3 border-round surface-50">
<div class="flex align-items-center">
<i class="pi pi-check-circle text-green-500 text-xl mr-3"></i>
<span class="text-900 font-medium">Total historique</span>
<div class="flex align-items-center justify-content-between p-3 border-round surface-50 border-1 uf-border-forest mb-2">
<div class="flex align-items-center">
<i class="pi pi-check-circle uf-text-forest text-xl mr-3"></i>
<span class="text-900 font-medium">Total historique</span>
</div>
<p:badge value="#{dashboardMembreBean.mesCotisations.size()}" severity="success"/>
</div>
<p:badge value="#{dashboardMembreBean.mesCotisations.size()}" severity="success"/>
</div>
<div class="flex align-items-center justify-content-between p-3 border-round surface-50">
<div class="flex align-items-center">
<i class="pi pi-clock text-orange-500 text-xl mr-3"></i>
<span class="text-900 font-medium">En attente</span>
</div>
<p:badge value="#{dashboardMembreBean.mesCotisationsEnAttente.size()}" severity="warning"/>
</div>
<div class="flex align-items-center justify-content-between p-3 border-round surface-50">
<div class="flex align-items-center">
<i class="pi pi-chart-line text-blue-500 text-xl mr-3"></i>
<span class="text-900 font-medium">Taux de paiement</span>
<div class="flex align-items-center justify-content-between p-3 border-round surface-50 border-1 uf-border-gold mb-2">
<div class="flex align-items-center">
<i class="pi pi-clock uf-text-gold text-xl mr-3"></i>
<span class="text-900 font-medium">En attente</span>
</div>
<p:badge value="#{dashboardMembreBean.mesCotisationsEnAttente.size()}" severity="warning"/>
</div>
<div class="flex align-items-center justify-content-between p-3 border-round surface-50 border-1 uf-border-navy">
<div class="flex align-items-center">
<i class="pi pi-chart-line uf-text-navy text-xl mr-3"></i>
<span class="text-900 font-medium">Taux de paiement</span>
</div>
<span class="text-900 font-bold">
<h:outputText value="#{dashboardMembreBean.tauxCotisationsPerso}" rendered="#{dashboardMembreBean.tauxCotisationsPerso != null}" />
<h:outputText value="%" rendered="#{dashboardMembreBean.tauxCotisationsPerso != null}" />

View File

@@ -56,21 +56,21 @@
<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>
<i class="pi pi-exclamation-circle uf-text-gold 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="uf-alert-card p-3 uf-border-left-crimson" style="border-left-width: 4px; border-left-style: solid;">
<div class="flex align-items-center">
<div class="bg-red-100 border-round flex align-items-center justify-content-center mr-3"
<div class="uf-bg-crimson-light 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>
<i class="pi pi-exclamation-triangle uf-text-crimson"></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 class="uf-text-crimson font-bold text-2xl">#{dashboardBean.cotisationsRetard}</div>
<div class="text-700 text-sm font-medium">Cotisations en retard</div>
</div>
</div>
</div>
@@ -78,15 +78,15 @@
<!-- 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="uf-alert-card p-3 uf-border-left-gold" style="border-left-width: 4px; border-left-style: solid;">
<div class="flex align-items-center">
<div class="bg-orange-100 border-round flex align-items-center justify-content-center mr-3"
<div class="uf-bg-gold-light 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>
<i class="pi pi-clock uf-text-gold"></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 class="text-900 font-bold text-2xl">#{dashboardBean.adhesionsExpiration}</div>
<div class="text-700 text-sm font-medium">Expire dans 7 jours</div>
</div>
</div>
</div>
@@ -94,15 +94,15 @@
<!-- À 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="uf-alert-card p-3 uf-border-left-navy" style="border-left-width: 4px; border-left-style: solid;">
<div class="flex align-items-center">
<div class="bg-blue-100 border-round flex align-items-center justify-content-center mr-3"
<div class="uf-bg-navy-light 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>
<i class="pi pi-inbox uf-text-navy"></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 class="uf-text-navy font-bold text-2xl">#{dashboardBean.demandesToTraiter}</div>
<div class="text-700 text-sm font-medium">Demandes en attente</div>
</div>
</div>
</div>
@@ -110,15 +110,15 @@
<!-- 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="uf-alert-card p-3 uf-border-left-forest" style="border-left-width: 4px; border-left-style: solid;">
<div class="flex align-items-center">
<div class="bg-green-100 border-round flex align-items-center justify-content-center mr-3"
<div class="uf-bg-forest-light 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>
<i class="pi pi-check-circle uf-text-forest"></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 class="uf-text-forest font-bold text-2xl">#{dashboardBean.tachesCompletees}</div>
<div class="text-700 text-sm font-medium">Complétées aujourd'hui</div>
</div>
</div>
</div>
@@ -131,7 +131,7 @@
<!-- 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>
<i class="pi pi-chart-bar uf-text-forest mr-2"></i>
Vue d'ensemble
</h5>
</div>
@@ -143,7 +143,7 @@
<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="iconColor" value="uf-text-navy" />
<ui:param name="growthValue" value="#{dashboardBean.membresEvolutionPourcent}" />
<ui:param name="growthLabel" value="ce mois" />
<ui:param name="progressValue" value="#{dashboardBean.tauxActivite}" />
@@ -157,7 +157,7 @@
<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="iconColor" value="uf-text-forest" />
<ui:param name="growthValue" value="#{dashboardBean.cotisationsEvolutionPourcent}" />
<ui:param name="growthLabel" value="vs mois dernier" />
<ui:param name="progressValue" value="#{dashboardBean.tauxObjectifCotisations}" />
@@ -171,7 +171,7 @@
<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="iconColor" value="uf-text-gold" />
<ui:param name="statusIcon" value="pi-circle-fill" />
<ui:param name="statusLabel" value="Demandes en attente" />
<ui:param name="statusValue" value="#{dashboardBean.pendingAides}" />
@@ -185,8 +185,8 @@
<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="icon" value="pi-calendar" />
<ui:param name="iconColor" value="uf-text-navy" />
<ui:param name="statusIcon" value="pi-calendar" />
<ui:param name="statusLabel" value="Événements prévus" />
<ui:param name="statusValue" value="#{dashboardBean.upcomingEvents}" />
@@ -469,8 +469,8 @@
<div class="flex flex-column gap-3">
<!-- Valider adhésions : SECRETAIRE, ADMIN -->
<ui:fragment rendered="#{menuBean.isSecretaire() or menuBean.isAdminOrganisation() or menuBean.isSuperAdmin()}">
<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 align-items-center p-3 border-round uf-bg-navy-light border-1 uf-border-navy">
<i class="pi pi-check-circle uf-text-navy 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>
@@ -485,8 +485,8 @@
<!-- Relancer cotisations : TRESORIER, SECRETAIRE, ADMIN -->
<ui:fragment rendered="#{menuBean.isTresorier() or menuBean.isSecretaire() or menuBean.isAdminOrganisation() or menuBean.isSuperAdmin()}">
<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 align-items-center p-3 border-round uf-bg-gold-light border-1 uf-border-gold">
<i class="pi pi-exclamation-triangle uf-text-gold 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>
@@ -501,8 +501,8 @@
<!-- Traiter aides : RESPONSABLE_SOCIAL, ADMIN -->
<ui:fragment rendered="#{menuBean.isResponsableSocial() or menuBean.isAdminOrganisation() or menuBean.isSuperAdmin()}">
<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 align-items-center p-3 border-round uf-bg-forest-light border-1 uf-border-forest">
<i class="pi pi-heart uf-text-forest 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>
@@ -561,20 +561,20 @@
<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-center p-3 border-round uf-bg-forest-light">
<div class="uf-text-forest 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-center p-3 border-round uf-bg-crimson-light">
<div class="uf-text-crimson 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-center p-3 border-round uf-bg-navy-light">
<div class="uf-text-navy font-medium text-xl">#{dashboardBean.soldeMois} FCFA</div>
<div class="text-500">Solde net</div>
</div>
</div>

View File

@@ -53,7 +53,7 @@
<ui:param name="title" value="Membres Actifs" />
<ui:param name="value" value="#{superAdminBean.totalMembres}" />
<ui:param name="icon" value="pi-users" />
<ui:param name="iconColor" value="blue-600" />
<ui:param name="iconColor" value="uf-text-navy" />
<ui:param name="growthValue" value="#{superAdminBean.croissanceMembres}" />
<ui:param name="growthLabel" value="ce mois" />
<ui:param name="progressValue" value="#{superAdminBean.pourcentageMembres}" />
@@ -63,7 +63,7 @@
<ui:param name="title" value="Organisations" />
<ui:param name="value" value="#{superAdminBean.totalEntites}" />
<ui:param name="icon" value="pi-sitemap" />
<ui:param name="iconColor" value="green-600" />
<ui:param name="iconColor" value="uf-text-forest" />
<ui:param name="growthValue" value="#{superAdminBean.nouvellesEntites}" />
<ui:param name="growthLabel" value="nouvelles" />
<ui:param name="growthType" value="number" />
@@ -75,7 +75,7 @@
<ui:param name="title" value="Revenus (FCFA)" />
<ui:param name="value" value="#{superAdminBean.revenusGlobaux}" />
<ui:param name="icon" value="pi-dollar" />
<ui:param name="iconColor" value="purple-600" />
<ui:param name="iconColor" value="uf-text-gold" />
<ui:param name="growthValue" value="#{superAdminBean.croissanceRevenus}" />
<ui:param name="growthLabel" value="vs mois dernier" />
<ui:param name="progressValue" value="#{superAdminBean.pourcentageRevenus}" />
@@ -85,7 +85,7 @@
<ui:param name="title" value="Activité du Jour" />
<ui:param name="value" value="#{superAdminBean.activiteJournaliere}" />
<ui:param name="icon" value="pi-chart-line" />
<ui:param name="iconColor" value="orange-600" />
<ui:param name="iconColor" value="uf-text-navy" />
<ui:param name="statusIcon" value="pi-check-circle" />
<ui:param name="statusLabel" value="En ligne" />
<ui:param name="statusValue" value="#{superAdminBean.utilisateursActifs} actifs" />
@@ -165,16 +165,16 @@
<div class="card">
<div class="flex align-items-center justify-content-between mb-3">
<h5 class="m-0">
<i class="pi pi-exclamation-triangle text-orange-500 mr-2"></i>
<i class="pi pi-exclamation-triangle uf-text-crimson mr-2"></i>
Alertes Système
</h5>
<p:tag value="#{superAdminBean.alertesCount} alertes" severity="warning" styleClass="text-xs" />
</div>
<ui:repeat value="#{superAdminBean.alertesRecentes}" var="alerte" varStatus="status">
<div class="flex align-items-center p-3 mb-2 border-round border-left-3 border-orange-400"
style="background: var(--surface-50);">
<i class="pi #{alerte.icone} text-orange-500 text-xl mr-3"></i>
<div class="uf-alert-card flex align-items-center p-3 mb-2 border-round uf-border-left-crimson"
style="background: var(--surface-50); border-left-width: 4px; border-left-style: solid;">
<i class="pi #{alerte.icone} uf-text-crimson text-xl mr-3"></i>
<div class="flex-1">
<div class="font-medium text-900">#{alerte.titre}</div>
<small class="text-500">#{alerte.entite} • #{alerte.date}</small>
@@ -283,9 +283,9 @@
</div>
<ui:repeat value="#{superAdminBean.activitesRecentes}" var="activite" varStatus="status">
<div class="flex align-items-start p-3 mb-2 border-round border-left-3 border-blue-300"
style="background: var(--surface-50);">
<i class="pi pi-history text-blue-500 text-xl mr-3 mt-1"></i>
<div class="flex align-items-start p-3 mb-2 border-round uf-border-left-navy"
style="background: var(--surface-50); border-left-width: 4px; border-left-style: solid;">
<i class="pi pi-history uf-text-navy text-xl mr-3 mt-1"></i>
<div class="flex-1">
<div class="font-medium text-900 mb-1">#{activite.description}</div>
<div class="text-600 text-sm">#{activite.entite}</div>
@@ -326,26 +326,26 @@
</div>
<div class="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">#{superAdminBean.revenus.mensuel}</div>
<div class="text-center p-3 border-round uf-bg-forest-light">
<div class="uf-text-forest font-medium text-xl">#{superAdminBean.revenus.mensuel}</div>
<div class="text-500">Revenus ce mois</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">#{superAdminBean.revenus.annuel}</div>
<div class="text-center p-3 border-round uf-bg-navy-light">
<div class="uf-text-navy font-medium text-xl">#{superAdminBean.revenus.annuel}</div>
<div class="text-500">Revenus annuels</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">#{superAdminBean.revenus.croissance}%</div>
<div class="text-center p-3 border-round uf-bg-gold-light">
<div class="uf-text-gold font-medium text-xl">#{superAdminBean.revenus.croissance}%</div>
<div class="text-500">Croissance annuelle</div>
</div>
</div>
<div class="col-12 md:col-3">
<div class="text-center p-3 border-round bg-orange-50">
<div class="text-orange-600 font-medium text-xl">#{superAdminBean.revenus.moyenne}</div>
<div class="text-center p-3 border-round uf-bg-crimson-light">
<div class="uf-text-crimson font-medium text-xl">#{superAdminBean.revenus.moyenne}</div>
<div class="text-500">Revenu moyen / entité</div>
</div>
</div>

View File

@@ -0,0 +1,110 @@
/* ==========================================================================
UnionFlow Premium Dashboard Design System (Banking / Governance aesthetic)
========================================================================== */
/* 1. Custom Color Tokens (Overrides for PrimeFlex) */
/* Primary Blue (Bleu Tech/Moderne) */
.uf-text-navy { color: var(--primary-color, #4F46E5) !important; }
.uf-bg-navy { background-color: var(--primary-color, #4F46E5) !important; }
.uf-bg-navy-light { background-color: rgba(79, 70, 229, 0.08) !important; }
.uf-border-navy { border-color: var(--primary-color, #4F46E5) !important; }
.uf-border-left-navy { border-left-color: var(--primary-color, #4F46E5) !important; }
/* Forest Green (Vert Forêt) */
.uf-text-forest { color: #126A54 !important; }
.uf-bg-forest { background-color: #126A54 !important; }
.uf-bg-forest-light { background-color: rgba(18, 106, 84, 0.08) !important; }
.uf-border-forest { border-color: #126A54 !important; }
.uf-border-left-forest { border-left-color: #126A54 !important; }
/* Premium Gold (Or) */
.uf-text-gold { color: #E6C57A !important; }
.uf-bg-gold { background-color: #E6C57A !important; }
.uf-bg-gold-light { background-color: rgba(230, 197, 122, 0.15) !important; }
.uf-border-gold { border-color: #E6C57A !important; }
.uf-border-left-gold { border-left-color: #E6C57A !important; }
/* Critical Premium Red (Deep Burgundy/Carmine instead of bright aggressive red) */
.uf-text-crimson { color: #C92A2A !important; }
.uf-bg-crimson { background-color: #C92A2A !important; }
.uf-bg-crimson-light { background-color: rgba(201, 42, 42, 0.06) !important; }
.uf-border-crimson { border-color: #C92A2A !important; }
.uf-border-left-crimson { border-left-color: #C92A2A !important; }
/* Neutral Premium (Deep Gray) */
.uf-text-neutral { color: #334155 !important; }
.uf-bg-neutral-light { background-color: #F8FAFC !important; }
/* 2. Premium Card Styles (Glassmorphism & Shadows) */
/* Modernizing the default cards */
.layout-content .card {
border-radius: 16px;
border: 1px solid rgba(79, 70, 229, 0.08); /* Primary color low opacity */
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.02);
background: #FFFFFF;
transition: box-shadow 0.3s ease;
}
.layout-content .card:hover {
box-shadow: 0 6px 24px rgba(79, 70, 229, 0.1);
}
/* KPI Overview Cards (Elevated, Interactive) */
.uf-kpi-card {
border-radius: 12px;
border: 1px solid rgba(0,0,0,0.03) !important;
background: #FFFFFF !important;
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.3s ease !important;
}
.uf-kpi-card:hover {
transform: translateY(-5px) !important;
box-shadow: 0 15px 35px rgba(79, 70, 229, 0.15) !important;
}
/* Alert/Action Cards (With left border) */
.uf-alert-card {
border-radius: 10px;
border: 1px solid rgba(0,0,0,0.02);
background: #FFFFFF;
transition: all 0.25s ease;
}
.uf-alert-card:hover {
transform: translateX(4px);
box-shadow: 0 8px 20px rgba(0,0,0,0.05);
}
/* Icon Containers in Cards */
.uf-icon-box {
width: 3rem;
height: 3rem;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
/* 3. Specialized Elements */
/* Activity Timeline/DataTables in Dashboard */
.ui-datatable .ui-datatable-header {
background: transparent !important;
border-bottom: 2px solid rgba(79, 70, 229, 0.1) !important;
border-top: none !important;
border-left: none !important;
border-right: none !important;
color: var(--primary-color, #4F46E5) !important;
}
.ui-tag.ui-tag-success { background: #126A54; }
.ui-tag.ui-tag-warning { background: #E6C57A; color: var(--primary-color, #4F46E5); }
.ui-tag.ui-tag-info { background: var(--primary-color, #4F46E5); }
.ui-tag.ui-tag-danger { background: #C92A2A; }
/* Progress bars */
.bg-gray-200 { background-color: #EDF2F7 !important; }

View File

@@ -913,3 +913,554 @@
color: var(--primary-color, #6366f1);
font-size: 0.875rem;
}
/* ═══════════════════════════════════════════════════════════════════ */
/* UNIONFLOW BRAND IDENTITY — EXHAUSTIVE DARK/LIGHT MODE SUPPORT */
/* Charte: #0B304A (Bleu Nuit), #126A54 (Vert Forêt), */
/* #E6C57A (Or Premium), #F4F6F8 (Fond), #E8EAEC */
/* */
/* Freya theme axes: */
/* 1. topbarTheme → .layout-topbar-light | .layout-topbar-dark */
/* 2. menuTheme → .layout-menu-light | .layout-menu-dark */
/* 3. darkMode → layout-light.css | layout-dark.css */
/* 4. menuMode → .layout-sidebar | .layout-static */
/* .layout-horizontal | .layout-slim */
/* ═══════════════════════════════════════════════════════════════════ */
/* ──────────────────────────────────────────────────
1. BASE — Brand Composition (Logo + Text)
Now uses .unionflow-topbar-brand (outside of
.layout-topbar-logo to avoid Freya display:none)
────────────────────────────────────────────────── */
.unionflow-topbar-brand,
.unionflow-brand {
display: flex !important;
align-items: center;
gap: 0.625rem;
text-decoration: none !important;
height: auto !important;
}
.unionflow-brand-icon {
width: 36px;
height: 36px;
object-fit: contain;
flex-shrink: 0;
border-radius: 4px;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.unionflow-topbar-brand:hover .unionflow-brand-icon,
.unionflow-brand:hover .unionflow-brand-icon {
transform: scale(1.05) rotate(-2deg);
}
.unionflow-brand-text {
display: flex;
flex-direction: column;
line-height: 1;
gap: 0.1875rem;
}
.unionflow-brand-name {
font-size: 1.125rem;
font-weight: 800;
letter-spacing: 0.15em;
text-transform: uppercase;
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
transition: color 0.2s ease;
}
.unionflow-brand-slogan {
font-size: 0.5625rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
transition: color 0.2s ease;
}
/* ──────────────────────────────────────────────────
2. TOPBAR — Dark mode (default: gradient/dark bg)
Classes: .layout-topbar-dark, .unionflow-elite
────────────────────────────────────────────────── */
.layout-topbar-dark .unionflow-brand-name,
.unionflow-elite .unionflow-brand-name {
color: #FFFFFF;
}
.layout-topbar-dark .unionflow-brand-slogan,
.unionflow-elite .unionflow-brand-slogan {
color: rgba(230, 197, 122, 0.9); /* Or Premium #E6C57A */
}
/* ──────────────────────────────────────────────────
3. TOPBAR — Light mode (white bg)
Class: .layout-topbar-light
────────────────────────────────────────────────── */
.layout-topbar-light .unionflow-brand-name {
color: #0B304A; /* Bleu Nuit */
}
.layout-topbar-light .unionflow-brand-slogan {
color: #126A54; /* Vert Forêt */
}
/* ──────────────────────────────────────────────────
4. SIDEBAR BRAND — Single source of branding
Collapsed (62px): icon only
Expanded (230px): icon + UNIONFLOW + slogan + v1.0
────────────────────────────────────────────────── */
/* --- Logo link container --- */
.sidebar-logo-link {
display: flex;
align-items: center;
gap: 0.5rem;
text-decoration: none !important;
overflow: hidden;
flex: 1;
min-width: 0;
}
.sidebar-logo-link:hover .unionflow-sidebar-icon {
transform: scale(1.08);
}
/* --- Icon (always visible — 24px for visual parity with menu icons) --- */
.unionflow-sidebar-icon {
width: 24px !important;
height: 24px !important;
object-fit: contain;
border-radius: 3px;
border: 0 none !important;
flex-shrink: 0;
transition: all 0.2s ease;
}
/* Override Freya's .menu-wrapper .sidebar-logo img { width:17px; height:20px } */
.menu-wrapper .sidebar-logo .unionflow-sidebar-icon {
width: 24px !important;
height: 24px !important;
}
/* --- Text block (hidden when collapsed) --- */
.unionflow-sidebar-text {
display: flex;
flex-direction: column;
line-height: 1;
gap: 0.125rem;
white-space: nowrap;
overflow: hidden;
visibility: hidden;
opacity: 0;
width: 0;
transition: opacity 0.2s ease, visibility 0.2s ease;
}
.unionflow-sidebar-name {
font-size: 0.9375rem;
font-weight: 800;
letter-spacing: 0.15em;
text-transform: uppercase;
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
}
.unionflow-sidebar-slogan {
font-size: 0.5rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
opacity: 0.7;
}
/* --- Version badge (hidden when collapsed) --- */
.unionflow-sidebar-version {
display: inline-flex;
align-items: center;
padding: 0;
border-radius: 8px;
font-size: 0.625rem;
font-weight: 600;
white-space: nowrap;
visibility: hidden;
opacity: 0;
width: 0;
overflow: hidden;
transition: opacity 0.2s ease, visibility 0.2s ease;
}
/* ──────────────────────────────────────────────────
4b. SIDEBAR EXPANDED — Show full brand
Triggered by: layout-static, layout-sidebar-active (hover)
────────────────────────────────────────────────── */
@media (min-width: 992px) {
/* Expanded: icon grows slightly */
.layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-icon,
.menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-icon {
width: 30px !important;
height: 30px !important;
}
/* Expanded: show text */
.layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-text,
.menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-text {
visibility: visible;
opacity: 1;
width: auto;
}
/* Expanded: show version badge */
.layout-wrapper.layout-static .menu-wrapper .sidebar-logo .unionflow-sidebar-version,
.menu-wrapper.layout-sidebar-active .sidebar-logo .unionflow-sidebar-version {
visibility: visible;
opacity: 1;
width: auto;
padding: 0.125rem 0.4rem;
}
}
/* ──────────────────────────────────────────────────
5. SIDEBAR — Menu Dark theme
Class: .layout-menu-dark (menu bg = #293241)
────────────────────────────────────────────────── */
.layout-menu-dark .unionflow-sidebar-name {
color: #FFFFFF;
}
.layout-menu-dark .unionflow-sidebar-slogan {
color: rgba(230, 197, 122, 0.85); /* Or Premium */
}
.layout-menu-dark .unionflow-sidebar-version {
background: rgba(255, 255, 255, 0.15);
color: rgba(255, 255, 255, 0.9);
}
.layout-menu-dark .sidebar-logo-link {
color: #E9E9E9;
}
/* ──────────────────────────────────────────────────
6. SIDEBAR — Menu Light theme
Class: .layout-menu-light (menu bg = white)
────────────────────────────────────────────────── */
.layout-menu-light .unionflow-sidebar-name {
color: #0B304A; /* Bleu Nuit */
}
.layout-menu-light .unionflow-sidebar-slogan {
color: #126A54; /* Vert Forêt */
}
.layout-menu-light .unionflow-sidebar-version {
background: rgba(11, 48, 74, 0.1);
color: #0B304A;
}
.layout-menu-light .sidebar-logo-link {
color: #0B304A;
}
/* ──────────────────────────────────────────────────
9. LANDING PAGE — Variant Premium Unionflow
────────────────────────────────────────────────── */
/* App background */
.landing-body {
background-color: #F4F6F8 !important; /* Très léger gris/bleu pour le fond de page */
}
/* Banner (Hero section) - Deep Blue modern gradient instead of the generic mountain */
.landing-body .landing-banner {
background: linear-gradient(135deg, #0B304A 0%, #154B73 50%, #126A54 100%) !important;
position: relative;
overflow: hidden;
}
/* Add a subtle geometric overlay effect to the banner for depth */
.landing-body .landing-banner::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.03) 0%, transparent 60%);
opacity: 0.8;
pointer-events: none;
animation: rotate-slow 60s linear infinite;
}
@keyframes rotate-slow {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Typography on Banner */
.landing-body .landing-banner .landing-banner-content .title {
color: #FFFFFF !important;
text-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
font-weight: 800 !important;
letter-spacing: -0.02em;
}
.landing-body .landing-banner .landing-banner-content h3 {
color: rgba(255, 255, 255, 0.9) !important;
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
font-weight: 400 !important;
letter-spacing: 0;
}
/* Topbar on Landing */
.landing-body .landing-topbar {
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px);
border-bottom: 1px solid rgba(11, 48, 74, 0.05);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.03);
}
/* Override Freya's tiny 16px landing logo */
.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing {
display: flex !important;
align-items: center !important;
gap: 0.75rem !important;
text-decoration: none !important;
}
.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing img.unionflow-brand-icon {
width: 36px !important;
height: 36px !important;
}
.landing-body .landing-topbar .landing-topbar-left .logo.unionflow-brand--landing .unionflow-brand-name {
font-size: 1.35rem !important;
letter-spacing: 0.15em !important;
color: #0B304A !important;
font-weight: 800 !important;
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif !important;
}
.landing-body .landing-topbar .landing-menu > li > a {
color: #0B304A !important;
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 0.75rem !important;
transition: color 0.3s ease;
}
.landing-body .landing-topbar .landing-menu > li > a:hover {
color: #E6C57A !important; /* Premium Gold */
}
/* Topbar Secondary Button - Premium Hover */
.landing-body .landing-topbar-right a[href*="dashboard"] {
border: 2px solid #0B304A !important;
color: #0B304A !important;
transition: all 0.3s ease !important;
}
.landing-body .landing-topbar-right a[href*="dashboard"]:hover {
background: transparent !important;
border-color: #E6C57A !important; /* Premium Gold */
color: #E6C57A !important;
box-shadow: 0 4px 15px rgba(230, 197, 122, 0.2);
}
/* Banner CTA Button - Premium Gold */
.landing-body .landing-banner-content a[href*="dashboard"] {
background: linear-gradient(135deg, #E6C57A 0%, #D4AF37 100%) !important;
color: #0B304A !important;
border: none !important;
box-shadow: 0 8px 24px rgba(230, 197, 122, 0.4) !important;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.landing-body .landing-banner-content a[href*="dashboard"]:hover {
transform: translateY(-4px) !important;
box-shadow: 0 12px 30px rgba(230, 197, 122, 0.6) !important;
}
/* Feature Cards - Glassmorphism & Shadows */
.landing-body .landing-features {
background: transparent !important;
}
.landing-body .feature-card {
background: #FFFFFF !important;
border: 1px solid rgba(11, 48, 74, 0.05) !important;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.04) !important;
border-radius: 20px !important;
transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.4s ease !important;
}
.landing-body .feature-card:hover {
transform: translateY(-12px) !important; /* Increased lift */
box-shadow: 0 25px 60px rgba(11, 48, 74, 0.12) !important;
}
.landing-body .feature-card h3 {
color: #0B304A !important;
font-weight: 700 !important;
}
.landing-body .feature-card h5 {
color: rgba(11, 48, 74, 0.7) !important;
}
/* Feature Icon numbers styling */
.landing-body .feature > span {
color: #E6C57A !important; /* Premium Gold */
font-weight: 800 !important;
font-size: 28px !important;
}
/* Sub-section headings */
.landing-body .section-header .title {
color: #0B304A !important;
font-weight: 800 !important;
}
.landing-body .section-header h3 {
color: rgba(11, 48, 74, 0.7) !important;
}
/* Benefit Icons Scale-up */
.landing-body .landing-pricing h3 + p + ul {
margin-top: 1rem !important;
}
.landing-body .landing-pricing .pi {
font-size: 1.5rem !important; /* Bumped from 1.25 to 1.5 for presence */
}
/* Bottom banner trust section */
.landing-body .landing-pricing > div:last-of-type > div {
background: linear-gradient(135deg, #0B304A 0%, #126A54 100%) !important;
border-radius: 24px !important;
box-shadow: 0 15px 40px rgba(11, 48, 74, 0.2) !important;
}
/* Final CTA */
.landing-body .mt-5 > a {
background: #0B304A !important;
color: #FFFFFF !important;
box-shadow: 0 4px 18px rgba(11, 48, 74, 0.3) !important;
}
.landing-body .mt-5 > a:hover {
transform: translateY(-3px) !important;
box-shadow: 0 10px 30px rgba(11, 48, 74, 0.4) !important;
background: #154B73 !important;
}
/* Footer styling */
.landing-body .layout-footer {
border-top: 1px solid rgba(11, 48, 74, 0.05);
}
.landing-body .layout-footer .footer-menutitle {
color: #0B304A !important;
font-weight: 700;
}
.landing-body .layout-footer ul > li,
.landing-body .layout-footer ul > li > a {
color: rgba(11, 48, 74, 0.6) !important;
}
.landing-body .layout-footer ul > li > a:hover {
color: #126A54 !important;
}
@media (max-width: 991px) {
.unionflow-brand--landing .unionflow-brand-icon {
width: 32px;
height: 32px;
}
.unionflow-brand--landing .unionflow-brand-name {
font-size: 1.1rem;
}
}
/* ──────────────────────────────────────────────────
10. EXCEPTION PAGES — 404, Access Denied, Error
────────────────────────────────────────────────── */
.exception-body .exception-topbar .unionflow-brand-icon {
width: 38px;
height: 38px;
}
.exception-body .exception-topbar .unionflow-brand-name {
color: #0B304A;
}
.exception-body .exception-topbar .unionflow-brand-slogan {
color: #126A54;
}
/* ──────────────────────────────────────────────────
11. RESPONSIVE BREAKPOINTS
────────────────────────────────────────────────── */
@media (max-width: 991px) {
/* On tablets: smaller icon, keep text */
.unionflow-brand-icon {
width: 30px;
height: 30px;
}
.unionflow-brand-name {
font-size: 1rem;
}
.unionflow-brand-slogan {
font-size: 0.5rem;
}
}
@media (max-width: 768px) {
/* On small tablets: hide text, only icon */
.unionflow-brand-text {
display: none;
}
.unionflow-brand-icon {
width: 30px;
height: 30px;
}
}
@media (max-width: 576px) {
/* On phones: even smaller icon */
.unionflow-brand-icon {
width: 26px;
height: 26px;
}
.unionflow-brand--landing .unionflow-brand-icon {
width: 32px;
height: 32px;
}
/* Still show name on landing for brand recognition */
.unionflow-brand--landing .unionflow-brand-text {
display: flex;
}
.unionflow-brand--landing .unionflow-brand-name {
font-size: 1.1rem;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -80,14 +80,14 @@
<ui:param name="noDataLabel" value="Données non disponibles" />
<div class="field #{colSize}">
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
<div class="card uf-kpi-card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
<div class="p-4" style="min-height: 9rem;">
<!-- Header: Titre et Icône -->
<div class="flex align-items-center justify-content-between mb-3">
<span class="block text-600 font-medium text-sm">#{title}</span>
<div class="flex align-items-center justify-content-center surface-100 border-round-lg"
style="width: 2.5rem; height: 2.5rem;">
<i class="pi #{icon} text-#{iconColor} text-lg"></i>
<i class="pi #{icon} #{iconColor.startsWith('uf-') ? '' : 'text-'}#{iconColor} text-lg"></i>
</div>
</div>

View File

@@ -7,8 +7,15 @@
<div class="menu-wrapper">
<div class="sidebar-logo">
<a href="dashboard.xhtml">
<p:graphicImage name="images/logo-freya-single.svg" library="freya-layout" />
<a href="dashboard.xhtml" class="sidebar-logo-link">
<h:graphicImage value="#{request.contextPath}/resources/freya-layout/images/unionflow-logo.png"
alt="UnionFlow"
styleClass="unionflow-sidebar-icon" />
<span class="unionflow-sidebar-text">
<span class="unionflow-sidebar-name">UNIONFLOW</span>
<span class="unionflow-sidebar-slogan">Connecter · Unir · Avancer</span>
</span>
<span class="unionflow-sidebar-version">v1.0</span>
</a>
<a href="#" class="sidebar-pin" title="Toggle Menu">
<span class="pin"></span>

View File

@@ -21,13 +21,7 @@
<a href="#" class="menu-button">
<i class="pi pi-bars"/>
</a>
<h:link id="logolink" outcome="/pages/secure/dashboard" styleClass="layout-topbar-logo">
<p:graphicImage name="images/#{guestPreferences.lightLogo ? 'logo-freya-white.svg' : 'logo-freya.svg'}"
library="freya-layout"
alt="UnionFlow"
title="Retour au tableau de bord"/>
</h:link>
<span class="app-version">v1.0</span>
<h:link id="logolink" outcome="/pages/secure/dashboard" styleClass="layout-topbar-logo" style="display:none"/>
</div>
<!-- CENTER - Menu -->

View File

@@ -13,7 +13,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<!-- Obsolète : apple-mobile-web-app-capable. Remplacé par mobile-web-app-capable -->
<meta name="mobile-web-app-capable" content="yes" />
<link rel="icon" href="#{request.contextPath}/resources/freya-layout/images/favicon.ico" type="image/x-icon"></link>
<link rel="icon" href="#{request.contextPath}/resources/freya-layout/images/unionflow-logo.png" type="image/png"></link>
</f:facet>
<title><ui:insert name="title">UnionFlow</ui:insert></title>
<h:outputScript name="js/layout.js" library="freya-layout" />
@@ -52,6 +52,8 @@
<h:outputStylesheet name="css/primeflex.min.css" library="freya-layout" />
<h:outputStylesheet name="css/layout-#{guestPreferences.layout}.css" library="freya-layout" />
<h:outputStylesheet name="primefaces-freya-#{guestPreferences.componentTheme}/theme.css" />
<h:outputStylesheet name="css/topbar-elite.css" />
<h:outputStylesheet name="css/dashboard-premium.css" />
</h:body>
</html>

View File

@@ -12,7 +12,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<!-- Obsolète : apple-mobile-web-app-capable. Remplacé par mobile-web-app-capable -->
<meta name="mobile-web-app-capable" content="yes"/>
<link rel="icon" type="image/x-icon" href="#{resource['images/favicon.ico']}"/>
<link rel="icon" type="image/png" href="#{resource['freya-layout:images/unionflow-logo.png']}"/>
</f:facet>
<title>