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:
85
target/classes/META-INF/resources/clients/details.xhtml
Normal file
85
target/classes/META-INF/resources/clients/details.xhtml
Normal file
@@ -0,0 +1,85 @@
|
||||
<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"
|
||||
template="/WEB-INF/template.xhtml">
|
||||
|
||||
<ui:define name="title">Détails du client - BTP Xpress</ui:define>
|
||||
|
||||
<f:metadata>
|
||||
<f:viewParam name="id" value="#{clientsView.clientId}"/>
|
||||
<f:event type="preRenderView" listener="#{clientsView.loadClientById()}"/>
|
||||
</f:metadata>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="layout-dashboard">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h1>Détails du client</h1>
|
||||
<p:commandButton value="Retour" icon="pi pi-arrow-left"
|
||||
outcome="/clients"
|
||||
styleClass="ui-button-secondary"/>
|
||||
</div>
|
||||
|
||||
<h:form id="detailsClientForm">
|
||||
<div class="grid" rendered="#{not empty clientsView.selectedItem}">
|
||||
<div class="col-12">
|
||||
<p:panel header="Informations générales">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<p><strong>Raison sociale :</strong> #{clientsView.selectedItem.raisonSociale}</p>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<p><strong>Nom du contact :</strong> #{clientsView.selectedItem.nomContact}</p>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<p><strong>Email :</strong> #{clientsView.selectedItem.email}</p>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<p><strong>Téléphone :</strong> #{clientsView.selectedItem.telephone}</p>
|
||||
</div>
|
||||
</div>
|
||||
</p:panel>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<p:panel header="Adresse">
|
||||
<p><strong>Adresse :</strong> #{clientsView.selectedItem.adresse}</p>
|
||||
<p><strong>Ville :</strong> #{clientsView.selectedItem.ville}</p>
|
||||
<p><strong>Code postal :</strong> #{clientsView.selectedItem.codePostal}</p>
|
||||
<p><strong>Pays :</strong> #{clientsView.selectedItem.pays}</p>
|
||||
</p:panel>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<p:panel header="Statistiques">
|
||||
<p><strong>Nombre de chantiers :</strong>
|
||||
<p:tag value="#{clientsView.selectedItem.nombreChantiers}" severity="info"/>
|
||||
</p>
|
||||
<p><strong>Chiffre d'affaires total :</strong>
|
||||
<h:outputText value="#{clientsView.selectedItem.chiffreAffairesTotal}">
|
||||
<f:converter converterId="fcfaConverter"/>
|
||||
</h:outputText>
|
||||
<h:outputText value=" Fcfa"/>
|
||||
</p>
|
||||
<p><strong>Date de création :</strong>
|
||||
<h:outputText value="#{clientsView.selectedItem.dateCreation}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy HH:mm"/>
|
||||
</h:outputText>
|
||||
</p>
|
||||
</p:panel>
|
||||
</div>
|
||||
</div>
|
||||
<p:message rendered="#{empty clientsView.selectedItem}" severity="warn"
|
||||
summary="Client introuvable"/>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
95
target/classes/META-INF/resources/clients/nouveau.xhtml
Normal file
95
target/classes/META-INF/resources/clients/nouveau.xhtml
Normal file
@@ -0,0 +1,95 @@
|
||||
<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"
|
||||
template="/WEB-INF/template.xhtml">
|
||||
|
||||
<ui:define name="title">Nouveau client - BTP Xpress</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="layout-dashboard">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h1>Créer un nouveau client</h1>
|
||||
<p:commandButton value="Retour" icon="pi pi-arrow-left"
|
||||
outcome="/clients"
|
||||
styleClass="ui-button-secondary"/>
|
||||
</div>
|
||||
|
||||
<h:form id="nouveauClientForm">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<h:outputLabel for="raisonSociale" value="Raison sociale *"/>
|
||||
<p:inputText id="raisonSociale" value="#{clientsView.selectedItem.raisonSociale}"
|
||||
required="true" requiredMessage="La raison sociale est obligatoire"
|
||||
style="width: 100%;"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h:outputLabel for="nomContact" value="Nom du contact *"/>
|
||||
<p:inputText id="nomContact" value="#{clientsView.selectedItem.nomContact}"
|
||||
required="true" requiredMessage="Le nom du contact est obligatoire"
|
||||
style="width: 100%;"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h:outputLabel for="email" value="Email *"/>
|
||||
<p:inputText id="email" value="#{clientsView.selectedItem.email}"
|
||||
required="true" requiredMessage="L'email est obligatoire"
|
||||
style="width: 100%;"/>
|
||||
<p:message for="email"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<h:outputLabel for="telephone" value="Téléphone"/>
|
||||
<p:inputText id="telephone" value="#{clientsView.selectedItem.telephone}"
|
||||
style="width: 100%;"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<h:outputLabel for="adresse" value="Adresse"/>
|
||||
<p:inputTextarea id="adresse" value="#{clientsView.selectedItem.adresse}"
|
||||
rows="3" style="width: 100%;"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<h:outputLabel for="ville" value="Ville"/>
|
||||
<p:inputText id="ville" value="#{clientsView.selectedItem.ville}"
|
||||
style="width: 100%;"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<h:outputLabel for="codePostal" value="Code postal"/>
|
||||
<p:inputText id="codePostal" value="#{clientsView.selectedItem.codePostal}"
|
||||
style="width: 100%;"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-4">
|
||||
<h:outputLabel for="pays" value="Pays"/>
|
||||
<p:inputText id="pays" value="#{clientsView.selectedItem.pays}"
|
||||
value="France" style="width: 100%;"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
outcome="/clients"
|
||||
styleClass="ui-button-secondary"/>
|
||||
<p:commandButton value="Enregistrer" icon="pi pi-check"
|
||||
action="#{clientsView.saveNew()}"
|
||||
update="@form"
|
||||
styleClass="ui-button-primary"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
96
target/classes/META-INF/resources/clients/recherche.xhtml
Normal file
96
target/classes/META-INF/resources/clients/recherche.xhtml
Normal file
@@ -0,0 +1,96 @@
|
||||
<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"
|
||||
template="/WEB-INF/template.xhtml">
|
||||
|
||||
<ui:define name="title">Recherche de clients - BTP Xpress</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="layout-dashboard">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h1>Recherche avancée de clients</h1>
|
||||
<p:commandButton value="Retour" icon="pi pi-arrow-left"
|
||||
outcome="/clients"
|
||||
styleClass="ui-button-secondary"/>
|
||||
</div>
|
||||
|
||||
<h:form id="rechercheClientForm">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<p:panel header="Critères de recherche">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-4">
|
||||
<h:outputLabel for="rechercheNom" value="Nom / Raison sociale"/>
|
||||
<p:inputText id="rechercheNom" value="#{clientsView.filtreNom}"
|
||||
placeholder="Rechercher..." style="width: 100%;"/>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<h:outputLabel for="rechercheEmail" value="Email"/>
|
||||
<p:inputText id="rechercheEmail" value="#{clientsView.filtreEmail}"
|
||||
placeholder="Rechercher..." style="width: 100%;"/>
|
||||
</div>
|
||||
<div class="col-12 md:col-4">
|
||||
<h:outputLabel for="rechercheVille" value="Ville"/>
|
||||
<p:inputText id="rechercheVille" value="#{clientsView.filtreVille}"
|
||||
placeholder="Rechercher..." style="width: 100%;"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-content-end gap-2 mt-3">
|
||||
<p:commandButton value="Réinitialiser" icon="pi pi-refresh"
|
||||
action="#{clientsView.resetFilters()}"
|
||||
update="@form"
|
||||
styleClass="ui-button-secondary"/>
|
||||
<p:commandButton value="Rechercher" icon="pi pi-search"
|
||||
action="#{clientsView.search()}"
|
||||
update="@form,clientsTable"
|
||||
styleClass="ui-button-primary"/>
|
||||
</div>
|
||||
</p:panel>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<ui:include src="/WEB-INF/components/liste-table.xhtml">
|
||||
<ui:param name="formId" value="clientsForm"/>
|
||||
<ui:param name="tableId" value="clientsTable"/>
|
||||
<ui:param name="viewBean" value="#{clientsView}"/>
|
||||
<ui:param name="var" value="client"/>
|
||||
<ui:param name="title" value="Résultats de recherche"/>
|
||||
<ui:param name="createPath" value=""/>
|
||||
<ui:define name="columns">
|
||||
<p:column headerText="Raison sociale" sortBy="#{client.raisonSociale}">
|
||||
<h:outputText value="#{client.raisonSociale}"/>
|
||||
</p:column>
|
||||
<p:column headerText="Contact" sortBy="#{client.nomContact}">
|
||||
<h:outputText value="#{client.nomContact}"/>
|
||||
</p:column>
|
||||
<p:column headerText="Email" sortBy="#{client.email}">
|
||||
<h:outputText value="#{client.email}"/>
|
||||
</p:column>
|
||||
<p:column headerText="Téléphone">
|
||||
<h:outputText value="#{client.telephone}"/>
|
||||
</p:column>
|
||||
<p:column headerText="Ville" sortBy="#{client.ville}">
|
||||
<h:outputText value="#{client.ville}"/>
|
||||
</p:column>
|
||||
<p:column headerText="Actions" style="width: 150px;">
|
||||
<p:commandButton icon="pi pi-eye" title="Voir les détails"
|
||||
styleClass="ui-button-text"
|
||||
action="#{clientsView.viewDetails(client.id)}"/>
|
||||
</p:column>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
|
||||
Reference in New Issue
Block a user