feat: Migration complète vers Quarkus PrimeFaces Freya

Migration du frontend React/Next.js vers Quarkus + PrimeFaces Freya 5.0.0

Dashboard:
- Extension de BtpXpressApiClient avec tous les endpoints dashboard
- Création de DashboardService pour récupérer les données API
- Refactorisation DashboardView : uniquement données réelles de l'API
- Restructuration dashboard.xhtml avec tous les aspects métiers BTP
- Suppression complète de toutes les données fictives

Topbar:
- Amélioration du menu profil utilisateur avec header professionnel
- Ajout UserSessionBean pour gérer les informations utilisateur
- Styles CSS personnalisés pour une disposition raffinée
- Badges de notifications conditionnels

Configuration:
- Intégration du thème Freya 5.0.0-jakarta
- Configuration OIDC pour Keycloak (security.lions.dev)
- Gestion des erreurs HTTP 431 (headers size)
- Support du format Fcfa avec séparateurs d'espaces

Converters:
- Création de FcfaConverter pour formater les montants en Fcfa avec espaces (x xxx xxx format)

Code Quality:
- Code entièrement documenté en français avec Javadoc exemplaire
- Respect du principe Java 'Write once, use many times'
- Logging complet pour le débogage
- Gestion d'erreurs robuste
This commit is contained in:
dahoud
2025-11-01 19:55:30 +00:00
commit b749f2df37
269 changed files with 29252 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:po="http://primefaces.org/freya">
<div class="layout-topbar">
<div class="layout-topbar-wrapper">
<div class="layout-topbar-left">
<a href="#" class="menu-button">
<i class="pi pi-bars"/>
</a>
<h:link id="logolink" outcome="/dashboard" styleClass="layout-topbar-logo">
<p:graphicImage name="images/#{ guestPreferences.lightLogo ? 'logo-freya-white.svg' : 'logo-freya.svg'}" library="freya-layout" />
</h:link>
</div>
<ui:include src="./menu.xhtml" />
<div class="layout-topbar-right">
<ul class="layout-topbar-actions">
<li class="topbar-item search-item">
<a href="#">
<i class="topbar-icon pi pi-search"/>
</a>
<h:form>
<h:panelGroup styleClass="search-input-wrapper">
<p:inputText placeholder="Search..." />
<i class="pi pi-search"/>
</h:panelGroup>
</h:form>
<ul>
<h:form onsubmit="return false;">
<h:panelGroup styleClass="search-input-wrapper">
<p:inputText placeholder="Search..." />
<i class="pi pi-search"/>
</h:panelGroup>
</h:form>
</ul>
</li>
<li class="topbar-item notifications-item">
<a href="/notifications">
<i class="topbar-icon pi pi-bell"/>
<p:outputPanel rendered="#{userSession.nombreNotificationsNonLues > 0}">
<span class="ui-badge">#{userSession.nombreNotificationsNonLues}</span>
</p:outputPanel>
</a>
</li>
<li class="topbar-item messages-item">
<a href="/messages">
<i class="topbar-icon pi pi-envelope"/>
<p:outputPanel rendered="#{userSession.nombreMessagesNonLus > 0}">
<span class="ui-badge">#{userSession.nombreMessagesNonLus}</span>
</p:outputPanel>
</a>
</li>
<li class="topbar-item user-profile">
<a href="#">
<p:graphicImage name="images/avatar-profilemenu.png" library="freya-layout" />
</a>
<ul>
<li class="user-profile-header">
<div class="user-info">
<p:graphicImage name="images/avatar-profilemenu.png" library="freya-layout" styleClass="profile-avatar-small" />
<div class="user-details">
<span class="user-name">#{userSession.nomComplet}</span>
<span class="user-role">#{userSession.role}</span>
</div>
</div>
</li>
<li class="user-profile-divider">
<hr/>
</li>
<li>
<a href="/profile">
<i class="pi pi-user"></i>
<span>Profile</span>
</a>
</li>
<li>
<a href="#">
<i class="pi pi-cog"></i>
<span>Settings</span>
</a>
</li>
<li>
<a href="/messages">
<i class="pi pi-envelope"></i>
<span>Messages</span>
<p:outputPanel rendered="#{userSession.nombreMessagesNonLus > 0}">
<span class="ui-badge">#{userSession.nombreMessagesNonLus}</span>
</p:outputPanel>
</a>
</li>
<li>
<a href="/notifications">
<i class="pi pi-bell"></i>
<span>Notifications</span>
<p:outputPanel rendered="#{userSession.nombreNotificationsNonLues > 0}">
<span class="ui-badge">#{userSession.nombreNotificationsNonLues}</span>
</p:outputPanel>
</a>
</li>
<li class="user-profile-divider">
<hr/>
</li>
<li>
<h:form>
<h:commandLink action="#{userSession.deconnecter()}" styleClass="logout-link">
<i class="pi pi-sign-out"></i>
<span>Logout</span>
</h:commandLink>
</h:form>
</li>
</ul>
</li>
</ul>
<a href="#" class="layout-rightpanel-button">
<i class="pi pi-arrow-left"/>
</a>
</div>
</div>
</div>
</ui:composition>