refactor: Suppression de 13 écrans redondants

Nettoyage des doublons pour éviter la redondance :

Suppressions (liste.xhtml redondants avec écrans racine):
- devis/liste.xhtml
- employes/liste.xhtml
- equipes/liste.xhtml
- factures/liste.xhtml
- maintenance/liste.xhtml
- materiels/liste.xhtml
- messages/liste.xhtml
- notifications/liste.xhtml
- planning/liste.xhtml
- rapports/liste.xhtml
- stock/liste.xhtml

Suppressions (inconsistance nouveau/nouvelle):
- equipes/nouvelle.xhtml
- factures/nouvelle.xhtml

Stratégie:
- Un seul écran liste par module (racine)
- Standardisation sur nouveau.xhtml

Résultat: 163 écrans restants (vs 176 avant)
This commit is contained in:
dahoud
2025-11-07 22:36:04 +00:00
parent 7a8233175a
commit 0fad42ccaf
85 changed files with 3715 additions and 986 deletions

View File

@@ -15,4 +15,17 @@
</locale-config>
</application>
<component>
<component-type>org.primefaces.component.FreyaMenu</component-type>
<component-class>org.primefaces.freya.component.FreyaMenu</component-class>
</component>
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.FreyaMenuRenderer</renderer-type>
<renderer-class>org.primefaces.freya.component.FreyaMenuRenderer</renderer-class>
</renderer>
</render-kit>
</faces-config>

View File

@@ -17,6 +17,7 @@
<p:dataTable id="#{tableId}"
value="#{viewBean.items}"
var="#{var}"
rowKey="id"
paginator="true"
rows="10"
rowsPerPageTemplate="10,20,50"

View File

@@ -1,55 +1,145 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<div class="layout-footer">
<div class="grid">
<div class="col-12 lg:col-4">
<!-- Section 1: À propos -->
<div class="col-12 lg:col-3">
<span class="footer-menutitle">À PROPOS</span>
<p class="footer-description" style="margin-top: 1rem; line-height: 1.8; color: var(--text-color-secondary);">
BTP Xpress est la plateforme de gestion complète pour les professionnels du BTP.
Optimisez vos chantiers, gérez vos équipes et suivez votre activité en temps réel.
</p>
<div style="margin-top: 1.5rem;">
<a href="https://facebook.com/btpxpress" style="margin-right: 1rem; color: var(--text-color-secondary); font-size: 1.5rem;">
<i class="pi pi-facebook"></i>
</a>
<a href="https://twitter.com/btpxpress" style="margin-right: 1rem; color: var(--text-color-secondary); font-size: 1.5rem;">
<i class="pi pi-twitter"></i>
</a>
<a href="https://linkedin.com/company/btpxpress" style="margin-right: 1rem; color: var(--text-color-secondary); font-size: 1.5rem;">
<i class="pi pi-linkedin"></i>
</a>
<a href="https://youtube.com/btpxpress" style="color: var(--text-color-secondary); font-size: 1.5rem;">
<i class="pi pi-youtube"></i>
</a>
</div>
</div>
<!-- Section 2: Navigation rapide -->
<div class="col-12 md:col-6 lg:col-3">
<div class="grid">
<div class="col-6">
<span class="footer-menutitle">PLAN DU SITE</span>
<ul>
<li><a href="dashboard.xhtml">Tableau de bord</a></li>
<li><a href="chantiers.xhtml">Chantiers</a></li>
<li><a href="clients.xhtml">Clients</a></li>
<li><a href="devis.xhtml">Devis</a></li>
<span class="footer-menutitle">MODULES</span>
<ul style="list-style: none; padding: 0; margin-top: 1rem;">
<li style="margin-bottom: 0.75rem;"><a href="dashboard.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-home" style="margin-right: 0.5rem;"></i>Tableau de bord</a></li>
<li style="margin-bottom: 0.75rem;"><a href="chantiers.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-building" style="margin-right: 0.5rem;"></i>Chantiers</a></li>
<li style="margin-bottom: 0.75rem;"><a href="clients.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-users" style="margin-right: 0.5rem;"></i>Clients</a></li>
<li style="margin-bottom: 0.75rem;"><a href="devis.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-file-edit" style="margin-right: 0.5rem;"></i>Devis</a></li>
<li style="margin-bottom: 0.75rem;"><a href="factures.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-dollar" style="margin-right: 0.5rem;"></i>Factures</a></li>
</ul>
</div>
<div class="col-6">
<span class="footer-menutitle"></span>
<ul>
<li><a href="factures.xhtml">Factures</a></li>
<li><a href="materiels.xhtml">Matériels</a></li>
<li><a href="employes.xhtml">Employés</a></li>
<li><a href="rapports.xhtml">Rapports</a></li>
<span class="footer-menutitle">RESSOURCES</span>
<ul style="list-style: none; padding: 0; margin-top: 1rem;">
<li style="margin-bottom: 0.75rem;"><a href="employes.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-id-card" style="margin-right: 0.5rem;"></i>Employés</a></li>
<li style="margin-bottom: 0.75rem;"><a href="materiels.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-wrench" style="margin-right: 0.5rem;"></i>Matériels</a></li>
<li style="margin-bottom: 0.75rem;"><a href="stock.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-box" style="margin-right: 0.5rem;"></i>Stock</a></li>
<li style="margin-bottom: 0.75rem;"><a href="planning.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-calendar" style="margin-right: 0.5rem;"></i>Planning</a></li>
<li style="margin-bottom: 0.75rem;"><a href="rapports.xhtml" style="color: var(--text-color-secondary);"><i class="pi pi-chart-bar" style="margin-right: 0.5rem;"></i>Rapports</a></li>
</ul>
</div>
</div>
</div>
<div class="col-12 md:col-6 lg:col-4">
<span class="footer-menutitle">NOUS CONTACTER</span>
<ul>
<li>Email : contact@btpxpress.com</li>
<li>Support : support@btpxpress.com</li>
<li>Téléphone : +33 (0)1 XX XX XX XX</li>
<!-- Section 3: Support et contact -->
<div class="col-12 md:col-6 lg:col-3">
<span class="footer-menutitle">SUPPORT</span>
<ul style="list-style: none; padding: 0; margin-top: 1rem;">
<li style="margin-bottom: 1rem; display: flex; align-items: start;">
<i class="pi pi-envelope" style="margin-right: 0.75rem; margin-top: 0.25rem; color: var(--primary-color);"></i>
<div>
<strong style="display: block; margin-bottom: 0.25rem;">Email</strong>
<a href="mailto:contact@btpxpress.com" style="color: var(--text-color-secondary);">contact@btpxpress.com</a>
</div>
</li>
<li style="margin-bottom: 1rem; display: flex; align-items: start;">
<i class="pi pi-phone" style="margin-right: 0.75rem; margin-top: 0.25rem; color: var(--primary-color);"></i>
<div>
<strong style="display: block; margin-bottom: 0.25rem;">Téléphone</strong>
<a href="tel:+33123456789" style="color: var(--text-color-secondary);">+33 (0)1 23 45 67 89</a>
</div>
</li>
<li style="margin-bottom: 1rem; display: flex; align-items: start;">
<i class="pi pi-question-circle" style="margin-right: 0.75rem; margin-top: 0.25rem; color: var(--primary-color);"></i>
<div>
<strong style="display: block; margin-bottom: 0.25rem;">Centre d'aide</strong>
<a href="aide.xhtml" style="color: var(--text-color-secondary);">Documentation et FAQ</a>
</div>
</li>
<li style="margin-bottom: 1rem; display: flex; align-items: start;">
<i class="pi pi-book" style="margin-right: 0.75rem; margin-top: 0.25rem; color: var(--primary-color);"></i>
<div>
<strong style="display: block; margin-bottom: 0.25rem;">Documentation</strong>
<a href="documentation.xhtml" style="color: var(--text-color-secondary);">Guide utilisateur</a>
</div>
</li>
</ul>
</div>
<div class="col-12 md:col-6 lg:col-4">
<span class="footer-menutitle">NEWSLETTER</span>
<span class="footer-subtitle">Inscrivez-vous à notre newsletter pour recevoir les dernières nouveautés.</span>
<h:form>
<div class="newsletter-input">
<p:inputText placeholder="Votre adresse email" />
<p:commandButton value="S'inscrire" styleClass="ui-button-secondary"/>
<!-- Section 4: Newsletter et informations légales -->
<div class="col-12 lg:col-3">
<span class="footer-menutitle">RESTEZ INFORMÉ</span>
<p class="footer-subtitle" style="margin-top: 1rem; line-height: 1.8; color: var(--text-color-secondary);">
Recevez nos actualités, conseils et nouveautés directement dans votre boîte mail.
</p>
<h:form style="margin-top: 1.5rem;">
<div class="newsletter-input" style="display: flex; gap: 0.5rem;">
<p:inputText placeholder="Votre email" style="flex: 1;" />
<p:commandButton value="S'inscrire" icon="pi pi-send" styleClass="ui-button-secondary"/>
</div>
</h:form>
<div style="margin-top: 2rem;">
<span class="footer-menutitle">LÉGAL</span>
<ul style="list-style: none; padding: 0; margin-top: 1rem;">
<li style="margin-bottom: 0.5rem;"><a href="mentions-legales.xhtml" style="color: var(--text-color-secondary); font-size: 0.9rem;">Mentions légales</a></li>
<li style="margin-bottom: 0.5rem;"><a href="cgv.xhtml" style="color: var(--text-color-secondary); font-size: 0.9rem;">Conditions générales de vente</a></li>
<li style="margin-bottom: 0.5rem;"><a href="politique-confidentialite.xhtml" style="color: var(--text-color-secondary); font-size: 0.9rem;">Politique de confidentialité</a></li>
<li style="margin-bottom: 0.5rem;"><a href="cookies.xhtml" style="color: var(--text-color-secondary); font-size: 0.9rem;">Gestion des cookies</a></li>
</ul>
</div>
</div>
<!-- Barre de copyright -->
<div class="col-12">
<div class="footer-bottom">
<h4>BTP Xpress</h4>
<h6>Copyright © 2025 - Tous droits réservés</h6>
<hr style="border-color: var(--surface-border); margin: 2rem 0;"/>
<div class="footer-bottom" style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem;">
<div>
<h4 style="margin: 0; font-size: 1.25rem; color: var(--primary-color);">
<i class="pi pi-building" style="margin-right: 0.5rem;"></i>
BTP Xpress
</h4>
<h6 style="margin: 0.5rem 0 0 0; color: var(--text-color-secondary); font-weight: normal;">
Copyright © 2025 BTP Xpress - Tous droits réservés
</h6>
</div>
<div style="display: flex; gap: 1.5rem; align-items: center;">
<span style="color: var(--text-color-secondary); font-size: 0.9rem;">
<i class="pi pi-shield" style="margin-right: 0.5rem; color: var(--primary-color);"></i>
Paiement sécurisé
</span>
<span style="color: var(--text-color-secondary); font-size: 0.9rem;">
<i class="pi pi-lock" style="margin-right: 0.5rem; color: var(--primary-color);"></i>
Données protégées
</span>
<span style="color: var(--text-color-secondary); font-size: 0.9rem;">
Made with <i class="pi pi-heart-fill" style="color: var(--red-500); margin: 0 0.25rem;"></i> in France
</span>
</div>
</div>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:fr="http://primefaces.org/freya">
@@ -10,111 +10,289 @@
<a href="dashboard.xhtml">
<p:graphicImage name="images/logo-freya-single.svg" library="freya-layout" />
</a>
<a href="#" class="sidebar-pin" title="Toggle Menu">
<a href="#" class="sidebar-pin" title="Épingler le menu">
<span class="pin"></span>
</a>
</div>
<div class="layout-menu-container">
<h:form id="menuform">
<fr:menu widgetVar="FreyaMenuWidget">
<p:menuitem id="m_dashboard" value="Dashboard" icon="pi pi-home" outcome="/dashboard" />
<!-- Dashboard Principal -->
<p:menuitem id="m_dashboard" value="Tableau de bord" icon="pi pi-home" outcome="/dashboard" />
<!-- =============================================
GESTION DES CHANTIERS
============================================= -->
<p:submenu id="m_chantiers" label="Chantiers" icon="pi pi-building">
<p:menuitem id="m_chantiers_liste" value="List" icon="pi pi-list" outcome="/chantiers" />
<p:menuitem id="m_chantiers_nouveau" value="New" icon="pi pi-plus-circle" outcome="/chantiers/nouveau" />
<p:menuitem id="m_chantiers_en_cours" value="In Progress" icon="pi pi-spin pi-spinner" outcome="/chantiers/en-cours" />
<p:menuitem id="m_chantiers_termines" value="Completed" icon="pi pi-check-circle" outcome="/chantiers/termines" />
<p:menuitem id="m_chantiers_planifies" value="Scheduled" icon="pi pi-calendar" outcome="/chantiers/planifies" />
<p:menuitem id="m_chantiers_liste" value="Tous les chantiers" icon="pi pi-list" outcome="/chantiers" />
<p:menuitem id="m_chantiers_nouveau" value="Nouveau chantier" icon="pi pi-plus-circle" outcome="/chantiers/nouveau" />
<p:separator/>
<p:menuitem id="m_chantiers_planifies" value="Planifiés" icon="pi pi-calendar" outcome="/chantiers/planifies" />
<p:menuitem id="m_chantiers_en_cours" value="En cours" icon="pi pi-spin pi-spinner" outcome="/chantiers/en-cours" />
<p:menuitem id="m_chantiers_suspendus" value="Suspendus" icon="pi pi-pause" outcome="/chantiers/suspendus" />
<p:menuitem id="m_chantiers_termines" value="Terminés" icon="pi pi-check-circle" outcome="/chantiers/termines" />
<p:separator/>
<p:menuitem id="m_chantiers_phases" value="Phases de chantier" icon="pi pi-sitemap" outcome="/chantiers/phases" />
<p:menuitem id="m_chantiers_templates" value="Templates de phases" icon="pi pi-clone" outcome="/chantiers/templates" />
<p:menuitem id="m_chantiers_contraintes" value="Contraintes construction" icon="pi pi-exclamation-triangle" outcome="/chantiers/contraintes" />
</p:submenu>
<!-- =============================================
GESTION COMMERCIALE
============================================= -->
<p:submenu id="m_clients" label="Clients" icon="pi pi-users">
<p:menuitem id="m_clients_liste" value="List" icon="pi pi-list" outcome="/clients" />
<p:menuitem id="m_clients_nouveau" value="New" icon="pi pi-user-plus" outcome="/clients/nouveau" />
<p:menuitem id="m_clients_recherche" value="Search" icon="pi pi-search" outcome="/clients/recherche" />
<p:menuitem id="m_clients_liste" value="Tous les clients" icon="pi pi-list" outcome="/clients" />
<p:menuitem id="m_clients_nouveau" value="Nouveau client" icon="pi pi-user-plus" outcome="/clients/nouveau" />
<p:menuitem id="m_clients_recherche" value="Recherche avancée" icon="pi pi-search" outcome="/clients/recherche" />
<p:separator/>
<p:menuitem id="m_clients_entreprises" value="Profils entreprises" icon="pi pi-briefcase" outcome="/clients/entreprises" />
<p:menuitem id="m_clients_avis" value="Avis clients" icon="pi pi-star" outcome="/clients/avis" />
</p:submenu>
<p:submenu id="m_devis" label="Devis" icon="pi pi-file-edit">
<p:menuitem id="m_devis_liste" value="List" icon="pi pi-list" outcome="/devis" />
<p:menuitem id="m_devis_nouveau" value="New" icon="pi pi-plus" outcome="/devis/nouveau" />
<p:menuitem id="m_devis_attente" value="Pending" icon="pi pi-clock" outcome="/devis/attente" />
<p:menuitem id="m_devis_acceptes" value="Accepted" icon="pi pi-check" outcome="/devis/acceptes" />
<p:menuitem id="m_devis_expires" value="Expired" icon="pi pi-exclamation-triangle" outcome="/devis/expires" />
<p:menuitem id="m_devis_liste" value="Tous les devis" icon="pi pi-list" outcome="/devis" />
<p:menuitem id="m_devis_nouveau" value="Nouveau devis" icon="pi pi-plus" outcome="/devis/nouveau" />
<p:separator/>
<p:menuitem id="m_devis_brouillon" value="Brouillons" icon="pi pi-pencil" outcome="/devis/brouillon" />
<p:menuitem id="m_devis_attente" value="En attente" icon="pi pi-clock" outcome="/devis/attente" />
<p:menuitem id="m_devis_acceptes" value="Acceptés" icon="pi pi-check" outcome="/devis/acceptes" />
<p:menuitem id="m_devis_refuses" value="Refusés" icon="pi pi-times" outcome="/devis/refuses" />
<p:menuitem id="m_devis_expires" value="Expirés" icon="pi pi-exclamation-triangle" outcome="/devis/expires" />
</p:submenu>
<!-- =============================================
GESTION FINANCIÈRE
============================================= -->
<p:submenu id="m_factures" label="Factures" icon="pi pi-dollar">
<p:menuitem id="m_factures_liste" value="List" icon="pi pi-list" outcome="/factures" />
<p:menuitem id="m_factures_nouvelle" value="New" icon="pi pi-plus" outcome="/factures/nouvelle" />
<p:menuitem id="m_factures_payees" value="Paid" icon="pi pi-check-circle" outcome="/factures/payees" />
<p:menuitem id="m_factures_impayees" value="Unpaid" icon="pi pi-exclamation-circle" outcome="/factures/impayees" />
<p:menuitem id="m_factures_retard" value="Overdue" icon="pi pi-clock" outcome="/factures/retard" />
<p:menuitem id="m_factures_liste" value="Toutes les factures" icon="pi pi-list" outcome="/factures" />
<p:menuitem id="m_factures_nouvelle" value="Nouvelle facture" icon="pi pi-plus" outcome="/factures/nouvelle" />
<p:separator/>
<p:menuitem id="m_factures_brouillon" value="Brouillons" icon="pi pi-pencil" outcome="/factures/brouillon" />
<p:menuitem id="m_factures_emises" value="Émises" icon="pi pi-send" outcome="/factures/emises" />
<p:menuitem id="m_factures_payees" value="Payées" icon="pi pi-check-circle" outcome="/factures/payees" />
<p:menuitem id="m_factures_impayees" value="Impayées" icon="pi pi-exclamation-circle" outcome="/factures/impayees" />
<p:menuitem id="m_factures_retard" value="En retard" icon="pi pi-clock" outcome="/factures/retard" />
<p:separator/>
<p:menuitem id="m_factures_conditions" value="Conditions de paiement" icon="pi pi-credit-card" outcome="/factures/conditions-paiement" />
</p:submenu>
<p:submenu id="m_materiels" label="Matériels" icon="pi pi-wrench">
<p:menuitem id="m_materiels_liste" value="Inventory" icon="pi pi-list" outcome="/materiels" />
<p:menuitem id="m_materiels_nouveau" value="New" icon="pi pi-plus" outcome="/materiels/nouveau" />
<p:menuitem id="m_materiels_disponibles" value="Available" icon="pi pi-check" outcome="/materiels/disponibles" />
<p:menuitem id="m_materiels_maintenance" value="Maintenance" icon="pi pi-cog" outcome="/materiels/maintenance-prevue" />
<p:submenu id="m_budget" label="Budgets" icon="pi pi-money-bill">
<p:menuitem id="m_budget_liste" value="Tous les budgets" icon="pi pi-list" outcome="/budgets" />
<p:menuitem id="m_budget_nouveau" value="Nouveau budget" icon="pi pi-plus" outcome="/budgets/nouveau" />
<p:menuitem id="m_budget_suivi" value="Suivi budgétaire" icon="pi pi-chart-line" outcome="/budgets/suivi" />
<p:menuitem id="m_budget_alertes" value="Alertes dépassement" icon="pi pi-exclamation-triangle" outcome="/budgets/alertes" />
</p:submenu>
<p:submenu id="m_stock" label="Stock" icon="pi pi-box">
<p:menuitem id="m_stock_liste" value="Management" icon="pi pi-list" outcome="/stock" />
<p:menuitem id="m_stock_inventaire" value="Inventory" icon="pi pi-check-square" outcome="/stock/inventaire" />
<p:menuitem id="m_stock_commandes" value="Orders" icon="pi pi-shopping-cart" outcome="/stock/commandes" />
<p:menuitem id="m_stock_sorties" value="Outgoing" icon="pi pi-sign-out" outcome="/stock/sorties" />
</p:submenu>
<!-- =============================================
GESTION DES RESSOURCES HUMAINES
============================================= -->
<p:submenu id="m_employes" label="Employés" icon="pi pi-id-card">
<p:menuitem id="m_employes_liste" value="List" icon="pi pi-list" outcome="/employes" />
<p:menuitem id="m_employes_nouveau" value="New" icon="pi pi-user-plus" outcome="/employes/nouveau" />
<p:menuitem id="m_employes_actifs" value="Active" icon="pi pi-check-circle" outcome="/employes/actifs" />
<p:menuitem id="m_employes_disponibles" value="Available" icon="pi pi-users" outcome="/employes/disponibles" />
<p:menuitem id="m_employes_liste" value="Tous les employés" icon="pi pi-list" outcome="/employes" />
<p:menuitem id="m_employes_nouveau" value="Nouvel employé" icon="pi pi-user-plus" outcome="/employes/nouveau" />
<p:separator/>
<p:menuitem id="m_employes_actifs" value="Actifs" icon="pi pi-check-circle" outcome="/employes/actifs" />
<p:menuitem id="m_employes_disponibles" value="Disponibles" icon="pi pi-users" outcome="/employes/disponibles" />
<p:menuitem id="m_employes_conges" value="En congés" icon="pi pi-calendar-minus" outcome="/employes/conges" />
<p:menuitem id="m_employes_inactifs" value="Inactifs" icon="pi pi-times-circle" outcome="/employes/inactifs" />
<p:separator/>
<p:menuitem id="m_employes_competences" value="Compétences" icon="pi pi-star" outcome="/employes/competences" />
<p:menuitem id="m_employes_fonctions" value="Fonctions" icon="pi pi-briefcase" outcome="/employes/fonctions" />
<p:menuitem id="m_employes_disponibilites" value="Disponibilités" icon="pi pi-calendar" outcome="/employes/disponibilites" />
</p:submenu>
<p:submenu id="m_equipes" label="Équipes" icon="pi pi-users">
<p:menuitem id="m_equipes_liste" value="List" icon="pi pi-list" outcome="/equipes" />
<p:menuitem id="m_equipes_nouvelle" value="New" icon="pi pi-plus" outcome="/equipes/nouvelle" />
<p:menuitem id="m_equipes_disponibles" value="Available" icon="pi pi-check" outcome="/equipes/disponibles" />
<p:menuitem id="m_equipes_specialites" value="Specialties" icon="pi pi-tags" outcome="/equipes/specialites" />
<p:menuitem id="m_equipes_liste" value="Toutes les équipes" icon="pi pi-list" outcome="/equipes" />
<p:menuitem id="m_equipes_nouvelle" value="Nouvelle équipe" icon="pi pi-plus" outcome="/equipes/nouvelle" />
<p:separator/>
<p:menuitem id="m_equipes_actives" value="Équipes actives" icon="pi pi-check" outcome="/equipes/actives" />
<p:menuitem id="m_equipes_disponibles" value="Disponibles" icon="pi pi-calendar-plus" outcome="/equipes/disponibles" />
<p:menuitem id="m_equipes_specialites" value="Par spécialité" icon="pi pi-tags" outcome="/equipes/specialites" />
</p:submenu>
<!-- =============================================
GESTION DU MATÉRIEL
============================================= -->
<p:submenu id="m_materiels" label="Matériels" icon="pi pi-wrench">
<p:menuitem id="m_materiels_liste" value="Inventaire complet" icon="pi pi-list" outcome="/materiels" />
<p:menuitem id="m_materiels_nouveau" value="Nouveau matériel" icon="pi pi-plus" outcome="/materiels/nouveau" />
<p:separator/>
<p:menuitem id="m_materiels_disponibles" value="Disponibles" icon="pi pi-check" outcome="/materiels/disponibles" />
<p:menuitem id="m_materiels_utilises" value="En utilisation" icon="pi pi-spin pi-spinner" outcome="/materiels/utilises" />
<p:menuitem id="m_materiels_maintenance" value="En maintenance" icon="pi pi-cog" outcome="/materiels/maintenance-prevue" />
<p:menuitem id="m_materiels_hors_service" value="Hors service" icon="pi pi-times-circle" outcome="/materiels/hors-service" />
<p:separator/>
<p:menuitem id="m_materiels_reservations" value="Réservations" icon="pi pi-calendar" outcome="/materiels/reservations" />
<p:menuitem id="m_materiels_marques" value="Marques" icon="pi pi-tag" outcome="/materiels/marques" />
<p:menuitem id="m_materiels_competences" value="Compétences requises" icon="pi pi-shield" outcome="/materiels/competences" />
<p:menuitem id="m_materiels_tests_qualite" value="Tests qualité" icon="pi pi-check-square" outcome="/materiels/tests-qualite" />
</p:submenu>
<!-- =============================================
GESTION DES STOCKS
============================================= -->
<p:submenu id="m_stock" label="Stock" icon="pi pi-box">
<p:menuitem id="m_stock_liste" value="Gestion du stock" icon="pi pi-list" outcome="/stock" />
<p:menuitem id="m_stock_nouveau" value="Nouvel article" icon="pi pi-plus" outcome="/stock/nouveau" />
<p:separator/>
<p:menuitem id="m_stock_inventaire" value="Inventaire" icon="pi pi-check-square" outcome="/stock/inventaire" />
<p:menuitem id="m_stock_categories" value="Catégories" icon="pi pi-sitemap" outcome="/stock/categories" />
<p:menuitem id="m_stock_alertes" value="Alertes stock" icon="pi pi-exclamation-triangle" outcome="/stock/alertes" />
<p:separator/>
<p:menuitem id="m_stock_entrees" value="Entrées de stock" icon="pi pi-sign-in" outcome="/stock/entrees" />
<p:menuitem id="m_stock_sorties" value="Sorties de stock" icon="pi pi-sign-out" outcome="/stock/sorties" />
<p:separator/>
<p:menuitem id="m_stock_unites_mesure" value="Unités de mesure" icon="pi pi-calculator" outcome="/stock/unites-mesure" />
<p:menuitem id="m_stock_unites_prix" value="Unités de prix" icon="pi pi-euro" outcome="/stock/unites-prix" />
</p:submenu>
<!-- =============================================
GESTION DES FOURNISSEURS
============================================= -->
<p:submenu id="m_fournisseurs" label="Fournisseurs" icon="pi pi-shopping-bag">
<p:menuitem id="m_fournisseurs_liste" value="Tous les fournisseurs" icon="pi pi-list" outcome="/fournisseurs" />
<p:menuitem id="m_fournisseurs_nouveau" value="Nouveau fournisseur" icon="pi pi-plus" outcome="/fournisseurs/nouveau" />
<p:separator/>
<p:menuitem id="m_fournisseurs_actifs" value="Actifs" icon="pi pi-check-circle" outcome="/fournisseurs/actifs" />
<p:menuitem id="m_fournisseurs_suspendus" value="Suspendus" icon="pi pi-pause" outcome="/fournisseurs/suspendus" />
<p:separator/>
<p:menuitem id="m_fournisseurs_catalogues" value="Catalogues" icon="pi pi-book" outcome="/fournisseurs/catalogues" />
<p:menuitem id="m_fournisseurs_specialites" value="Spécialités" icon="pi pi-tags" outcome="/fournisseurs/specialites" />
<p:menuitem id="m_fournisseurs_comparaison" value="Comparaison" icon="pi pi-chart-bar" outcome="/fournisseurs/comparaison" />
<p:menuitem id="m_fournisseurs_materiels" value="Matériels fournis" icon="pi pi-wrench" outcome="/fournisseurs/materiels" />
</p:submenu>
<p:submenu id="m_bon_commande" label="Bons de commande" icon="pi pi-shopping-cart">
<p:menuitem id="m_bon_commande_liste" value="Tous les bons" icon="pi pi-list" outcome="/bon-commande" />
<p:menuitem id="m_bon_commande_nouveau" value="Nouveau bon" icon="pi pi-plus" outcome="/bon-commande/nouveau" />
<p:separator/>
<p:menuitem id="m_bon_commande_brouillon" value="Brouillons" icon="pi pi-pencil" outcome="/bon-commande/brouillon" />
<p:menuitem id="m_bon_commande_valides" value="Validés" icon="pi pi-check" outcome="/bon-commande/valides" />
<p:menuitem id="m_bon_commande_envoyes" value="Envoyés" icon="pi pi-send" outcome="/bon-commande/envoyes" />
<p:menuitem id="m_bon_commande_recus" value="Reçus" icon="pi pi-inbox" outcome="/bon-commande/recus" />
<p:menuitem id="m_bon_commande_annules" value="Annulés" icon="pi pi-times" outcome="/bon-commande/annules" />
<p:separator/>
<p:menuitem id="m_bon_commande_livraisons" value="Livraisons" icon="pi pi-truck" outcome="/bon-commande/livraisons" />
</p:submenu>
<!-- =============================================
PLANNING ET RÉSERVATIONS
============================================= -->
<p:submenu id="m_planning" label="Planning" icon="pi pi-calendar">
<p:menuitem id="m_planning_calendrier" value="Calendar" icon="pi pi-calendar" outcome="/planning/calendrier" />
<p:menuitem id="m_planning_materiel" value="Equipment" icon="pi pi-wrench" outcome="/planning/materiel" />
<p:menuitem id="m_planning_equipes" value="Teams" icon="pi pi-users" outcome="/planning/equipes" />
<p:menuitem id="m_planning_calendrier" value="Calendrier général" icon="pi pi-calendar" outcome="/planning/calendrier" />
<p:menuitem id="m_planning_nouveau" value="Nouvel événement" icon="pi pi-plus" outcome="/planning/nouveau" />
<p:separator/>
<p:menuitem id="m_planning_chantiers" value="Planning chantiers" icon="pi pi-building" outcome="/planning/chantiers" />
<p:menuitem id="m_planning_materiel" value="Planning matériel" icon="pi pi-wrench" outcome="/planning/materiel" />
<p:menuitem id="m_planning_equipes" value="Planning équipes" icon="pi pi-users" outcome="/planning/equipes" />
<p:separator/>
<p:menuitem id="m_planning_evenements" value="Événements" icon="pi pi-calendar-plus" outcome="/planning/evenements" />
<p:menuitem id="m_planning_rappels" value="Rappels" icon="pi pi-bell" outcome="/planning/rappels" />
<p:menuitem id="m_planning_vues" value="Vues personnalisées" icon="pi pi-eye" outcome="/planning/vues" />
</p:submenu>
<!-- =============================================
MAINTENANCE
============================================= -->
<p:submenu id="m_maintenance" label="Maintenance" icon="pi pi-cog">
<p:menuitem id="m_maintenance_liste" value="List" icon="pi pi-list" outcome="/maintenance" />
<p:menuitem id="m_maintenance_nouvelle" value="New" icon="pi pi-plus" outcome="/maintenance/nouveau" />
<p:menuitem id="m_maintenance_preventive" value="Preventive" icon="pi pi-shield" outcome="/maintenance/preventive" />
<p:menuitem id="m_maintenance_liste" value="Toutes les maintenances" icon="pi pi-list" outcome="/maintenance" />
<p:menuitem id="m_maintenance_nouvelle" value="Nouvelle maintenance" icon="pi pi-plus" outcome="/maintenance/nouveau" />
<p:separator/>
<p:menuitem id="m_maintenance_preventive" value="Préventive" icon="pi pi-shield" outcome="/maintenance/preventive" />
<p:menuitem id="m_maintenance_corrective" value="Corrective" icon="pi pi-exclamation-triangle" outcome="/maintenance/corrective" />
<p:menuitem id="m_maintenance_urgente" value="Urgent" icon="pi pi-bolt" outcome="/maintenance/urgente" />
<p:menuitem id="m_maintenance_urgente" value="Urgente" icon="pi pi-bolt" outcome="/maintenance/urgente" />
<p:separator/>
<p:menuitem id="m_maintenance_planifiees" value="Planifiées" icon="pi pi-calendar" outcome="/maintenance/planifiees" />
<p:menuitem id="m_maintenance_en_cours" value="En cours" icon="pi pi-spin pi-spinner" outcome="/maintenance/en-cours" />
<p:menuitem id="m_maintenance_terminees" value="Terminées" icon="pi pi-check-circle" outcome="/maintenance/terminees" />
<p:menuitem id="m_maintenance_en_retard" value="En retard" icon="pi pi-clock" outcome="/maintenance/en-retard" />
</p:submenu>
<!-- =============================================
DOCUMENTS
============================================= -->
<p:submenu id="m_documents" label="Documents" icon="pi pi-file">
<p:menuitem id="m_documents_liste" value="Tous les documents" icon="pi pi-list" outcome="/documents" />
<p:menuitem id="m_documents_nouveau" value="Nouveau document" icon="pi pi-upload" outcome="/documents/nouveau" />
<p:separator/>
<p:menuitem id="m_documents_contrats" value="Contrats" icon="pi pi-file-edit" outcome="/documents/contrats" />
<p:menuitem id="m_documents_plans" value="Plans" icon="pi pi-map" outcome="/documents/plans" />
<p:menuitem id="m_documents_factures_docs" value="Factures" icon="pi pi-file-pdf" outcome="/documents/factures" />
<p:menuitem id="m_documents_devis_docs" value="Devis" icon="pi pi-file-edit" outcome="/documents/devis" />
<p:menuitem id="m_documents_rapports" value="Rapports" icon="pi pi-chart-bar" outcome="/documents/rapports" />
<p:menuitem id="m_documents_autres" value="Autres" icon="pi pi-folder" outcome="/documents/autres" />
</p:submenu>
<!-- =============================================
RAPPORTS ET ANALYSES
============================================= -->
<p:submenu id="m_rapports" label="Rapports" icon="pi pi-chart-bar">
<p:menuitem id="m_rapports_liste" value="List" icon="pi pi-list" outcome="/rapports" />
<p:menuitem id="m_rapports_ca" value="Revenue" icon="pi pi-dollar" outcome="/rapports/ca" />
<p:menuitem id="m_rapports_rentabilite" value="Profitability" icon="pi pi-chart-line" outcome="/rapports/rentabilite" />
<p:menuitem id="m_rapports_clients" value="By Client" icon="pi pi-users" outcome="/rapports/clients" />
<p:menuitem id="m_rapports_equipes" value="By Team" icon="pi pi-id-card" outcome="/rapports/equipes" />
<p:menuitem id="m_rapports_tableau_bord" value="Tableau de bord" icon="pi pi-chart-line" outcome="/rapports/tableau-bord" />
<p:separator/>
<p:menuitem id="m_rapports_ca" value="Chiffre d'affaires" icon="pi pi-dollar" outcome="/rapports/ca" />
<p:menuitem id="m_rapports_rentabilite" value="Rentabilité" icon="pi pi-chart-line" outcome="/rapports/rentabilite" />
<p:menuitem id="m_rapports_marge" value="Analyse des marges" icon="pi pi-percentage" outcome="/rapports/marge" />
<p:separator/>
<p:menuitem id="m_rapports_chantiers" value="Rapports chantiers" icon="pi pi-building" outcome="/rapports/chantiers" />
<p:menuitem id="m_rapports_clients" value="Rapports clients" icon="pi pi-users" outcome="/rapports/clients" />
<p:menuitem id="m_rapports_equipes" value="Rapports équipes" icon="pi pi-id-card" outcome="/rapports/equipes" />
<p:menuitem id="m_rapports_materiels" value="Utilisation matériel" icon="pi pi-wrench" outcome="/rapports/materiels" />
<p:separator/>
<p:menuitem id="m_rapports_personnalises" value="Rapports personnalisés" icon="pi pi-sliders-h" outcome="/rapports/personnalises" />
<p:menuitem id="m_rapports_export" value="Exports" icon="pi pi-download" outcome="/rapports/export" />
</p:submenu>
<!-- =============================================
COMMUNICATION
============================================= -->
<p:submenu id="m_notifications" label="Notifications" icon="pi pi-bell">
<p:menuitem id="m_notifications_liste" value="All" icon="pi pi-list" outcome="/notifications" />
<p:menuitem id="m_notifications_recentes" value="Recent" icon="pi pi-clock" outcome="/notifications/recentes" />
<p:menuitem id="m_notifications_non_lues" value="Unread" icon="pi pi-envelope" outcome="/notifications/non-lues" />
<p:menuitem id="m_notifications_statistiques" value="Statistics" icon="pi pi-chart-pie" outcome="/notifications/statistiques" />
<p:menuitem id="m_notifications_liste" value="Toutes" icon="pi pi-list" outcome="/notifications" />
<p:menuitem id="m_notifications_non_lues" value="Non lues" icon="pi pi-envelope" outcome="/notifications/non-lues" />
<p:menuitem id="m_notifications_recentes" value="Récentes" icon="pi pi-clock" outcome="/notifications/recentes" />
<p:menuitem id="m_notifications_importantes" value="Importantes" icon="pi pi-star" outcome="/notifications/importantes" />
<p:separator/>
<p:menuitem id="m_notifications_parametres" value="Paramètres" icon="pi pi-cog" outcome="/notifications/parametres" />
<p:menuitem id="m_notifications_statistiques" value="Statistiques" icon="pi pi-chart-pie" outcome="/notifications/statistiques" />
</p:submenu>
<p:submenu id="m_messages" label="Messages" icon="pi pi-comments">
<p:menuitem id="m_messages_liste" value="Inbox" icon="pi pi-inbox" outcome="/messages" />
<p:menuitem id="m_messages_nouveau" value="New" icon="pi pi-plus" outcome="/messages/nouveau" />
<p:menuitem id="m_messages_envoyes" value="Sent" icon="pi pi-send" outcome="/messages/envoyes" />
<p:menuitem id="m_messages_archives" value="Archived" icon="pi pi-archive" outcome="/messages/archives" />
<p:menuitem id="m_messages_liste" value="Boîte de réception" icon="pi pi-inbox" outcome="/messages" />
<p:menuitem id="m_messages_nouveau" value="Nouveau message" icon="pi pi-plus" outcome="/messages/nouveau" />
<p:separator/>
<p:menuitem id="m_messages_non_lus" value="Non lus" icon="pi pi-envelope" outcome="/messages/non-lus" />
<p:menuitem id="m_messages_envoyes" value="Messages envoyés" icon="pi pi-send" outcome="/messages/envoyes" />
<p:menuitem id="m_messages_brouillons" value="Brouillons" icon="pi pi-pencil" outcome="/messages/brouillons" />
<p:menuitem id="m_messages_archives" value="Archivés" icon="pi pi-archive" outcome="/messages/archives" />
<p:menuitem id="m_messages_corbeille" value="Corbeille" icon="pi pi-trash" outcome="/messages/corbeille" />
</p:submenu>
<p:menuitem id="m_profile" value="Profile" icon="pi pi-user" outcome="/profile" />
<!-- =============================================
ADMINISTRATION
============================================= -->
<p:submenu id="m_utilisateurs" label="Utilisateurs" icon="pi pi-user">
<p:menuitem id="m_utilisateurs_liste" value="Tous les utilisateurs" icon="pi pi-list" outcome="/utilisateurs" />
<p:menuitem id="m_utilisateurs_nouveau" value="Nouvel utilisateur" icon="pi pi-user-plus" outcome="/utilisateurs/nouveau" />
<p:separator/>
<p:menuitem id="m_utilisateurs_roles" value="Rôles" icon="pi pi-shield" outcome="/utilisateurs/roles" />
<p:menuitem id="m_utilisateurs_permissions" value="Permissions" icon="pi pi-key" outcome="/utilisateurs/permissions" />
<p:menuitem id="m_utilisateurs_abonnements" value="Abonnements" icon="pi pi-credit-card" outcome="/utilisateurs/abonnements" />
</p:submenu>
<p:submenu id="m_parametres" label="Paramètres" icon="pi pi-cog">
<p:menuitem id="m_parametres_generaux" value="Paramètres généraux" icon="pi pi-sliders-h" outcome="/parametres/generaux" />
<p:menuitem id="m_parametres_entreprise" value="Informations entreprise" icon="pi pi-building" outcome="/parametres/entreprise" />
<p:menuitem id="m_parametres_facturation" value="Facturation" icon="pi pi-dollar" outcome="/parametres/facturation" />
<p:menuitem id="m_parametres_notifications" value="Notifications" icon="pi pi-bell" outcome="/parametres/notifications" />
<p:menuitem id="m_parametres_securite" value="Sécurité" icon="pi pi-lock" outcome="/parametres/securite" />
<p:menuitem id="m_parametres_integrations" value="Intégrations" icon="pi pi-link" outcome="/parametres/integrations" />
</p:submenu>
<!-- =============================================
MENU UTILISATEUR
============================================= -->
<p:separator/>
<p:menuitem id="m_profile" value="Mon profil" icon="pi pi-user" outcome="/profile" />
<p:menuitem id="m_documentation" value="Documentation" icon="pi pi-book" outcome="/documentation" />
<p:menuitem id="m_aide" value="Aide et support" icon="pi pi-question-circle" outcome="/aide" />
</fr:menu>
</h:form>
</div>

View File

@@ -12,17 +12,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta name="apple-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="#{resource['freya-layout:images/favicon.ico']}" type="image/x-icon"></link>
</f:facet>
<title><ui:insert name="title">BTP Xpress - Gestion de Projets BTP</ui:insert></title>
<h:outputStylesheet name="theme.css" library="primefaces-freya-#{guestPreferences.componentTheme}-#{guestPreferences.darkMode}"/>
<h:outputStylesheet name="css/primeicons.css" library="freya-layout" />
<h:outputStylesheet name="css/primeflex.min.css" library="freya-layout" />
<h:outputStylesheet name="css/#{guestPreferences.layout}.css" library="freya-layout" />
<h:outputStylesheet name="css/custom-topbar.css" />
<h:outputScript name="js/custom-menu.js" />
<h:outputScript name="js/layout.js" library="freya-layout" />
<h:outputScript name="js/prism.js" library="freya-layout"/>
<ui:insert name="head"/>
@@ -46,13 +39,18 @@
<f:facet name="start">
<i class="pi pi-spin pi-spinner ajax-loader" aria-hidden="true"/>
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<div class="layout-mask modal-in"></div>
</div>
<h:outputStylesheet name="css/primeicons.css" library="freya-layout" />
<h:outputStylesheet name="css/primeflex.min.css" library="freya-layout" />
<h:outputStylesheet name="css/#{guestPreferences.layout}.css" library="freya-layout" />
<h:outputStylesheet name="css/custom-topbar.css" />
<h:outputStylesheet name="css/custom-dashboard.css" />
</h:body>
</html>

View File

@@ -70,7 +70,7 @@
<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%;"/>
style="width: 100%;"/>
</div>
<div class="col-12">

View File

@@ -1,325 +1,483 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:p="http://primefaces.org/ui"
template="/WEB-INF/template.xhtml">
<ui:define name="title">Tableau de bord - BTP Xpress</ui:define>
<ui:define name="head">
<h:outputScript name="chartjs/chart.js" library="demo" />
<script>
//<![CDATA[
$(function(){
var ctx1 = document.getElementById("chartChantiers");
if (ctx1) {
var chartChantiers = new Chart(ctx1.getContext('2d'), {
type: 'line',
data: {
labels: ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin'],
datasets: [{
label: 'Chantiers',
data: [12, 19, 15, 25, 22, 28],
borderColor: '#464DF2',
borderWidth: 3,
fill: true,
backgroundColor: 'rgba(70, 77, 242, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: { y: { beginAtZero: true } }
}
});
}
});
//]]>
</script>
</ui:define>
<ui:define name="content">
<div class="layout-dashboard">
<div class="grid">
<!-- KPI Cards - Vue d'ensemble -->
<div class="col-12">
<div class="grid" style="margin: -1rem;">
<div class="col-12 md:col-3">
<div class="card">
<h1>Tableau de bord - BTP Xpress</h1>
<p>Bean dashboardView disponible: #{not empty dashboardView}</p>
<p>Chantiers actifs: #{dashboardView.chantiersActifs}</p>
<p>Test de contenu simple</p>
</div>
</div>
</div>
<!-- ========================================================================
BARRE D'ALERTES (affichée uniquement si alertes critiques)
======================================================================== -->
<p:outputPanel rendered="#{dashboardView.alerteCritique}" styleClass="col-12">
<div class="notification notification-danger">
<i class="pi pi-exclamation-triangle"></i>
<strong>#{dashboardView.totalAlertes} alertes</strong> nécessitent votre attention immédiate
<span style="margin-left: 1rem; opacity: 0.9;">
Maintenance: #{dashboardView.alertesMaintenanceCount} •
Chantiers: #{dashboardView.alertesChantiersCount} •
Disponibilités: #{dashboardView.alertesDisponibilitesCount}
</span>
<p:commandButton value="Rafraîchir"
icon="pi pi-refresh"
action="#{dashboardView.rafraichir}"
update="@form"
styleClass="ui-button-text"
style="float: right;"/>
</div>
</p:outputPanel>
<div class="grid">
<!-- ====================================================================
KPIs PRINCIPAUX (3 cartes en ligne)
==================================================================== -->
<div class="col-12">
<div class="grid" style="margin: -0.5rem;">
<!-- KPI 1: Chantiers Actifs -->
<div class="col-12 md:col-6 xl:col-4">
<div class="card overview-box white">
<div class="overview-info">
<h6>Chantiers actifs</h6>
<h1>#{dashboardView.chantiersActifs}</h1>
<p class="subtitle">Sur #{dashboardView.nombreChantiers} au total</p>
<p class="subtitle">
Sur #{dashboardView.nombreChantiers} au total
</p>
<p:progressBar value="#{dashboardView.tauxActiviteChantiers}"
showValue="true"
displayValue="#{dashboardView.tauxActiviteChantiers}%"
styleClass="ui-progressbar-info"/>
</div>
<i class="pi pi-building"></i>
</div>
</div>
<div class="col-12 md:col-3">
<!-- KPI 2: Équipes Disponibles -->
<div class="col-12 md:col-6 xl:col-4">
<div class="card overview-box blue">
<div class="overview-info">
<h6>Clients</h6>
<h1>#{dashboardView.nombreClients}</h1>
<p class="subtitle">Actifs</p>
<h6>Équipes disponibles</h6>
<h1>#{dashboardView.equipesDisponibles}/#{dashboardView.nombreEquipes}</h1>
<p class="subtitle">Taux de disponibilité</p>
<p:progressBar value="#{dashboardView.tauxDisponibiliteEquipes}"
showValue="true"
displayValue="#{dashboardView.tauxDisponibiliteEquipes}%"
style="background: rgba(255,255,255,0.3);"/>
</div>
<i class="pi pi-users"></i>
</div>
</div>
<div class="col-12 md:col-3">
<div class="card overview-box orange">
<!-- KPI 3: Maintenances Critiques -->
<div class="col-12 md:col-12 xl:col-4">
<div class="card overview-box #{dashboardView.alerteRetardMaintenance ? 'red' : 'green'}">
<div class="overview-info">
<h6>Devis en attente</h6>
<h1>#{dashboardView.nombreDevis}</h1>
<p class="subtitle">À traiter</p>
<h6>Maintenances en retard</h6>
<h1>#{dashboardView.maintenancesEnRetard}</h1>
<p class="subtitle">#{dashboardView.maintenancesPlanifiees} planifiées</p>
<p:badge value="#{dashboardView.alerteRetardMaintenance ? 'URGENT' : 'OK'}"
severity="#{dashboardView.alerteRetardMaintenance ? 'danger' : 'success'}"
style="margin-top: 0.5rem;"/>
</div>
<i class="pi pi-file-edit"></i>
<i class="pi pi-wrench"></i>
</div>
</div>
<div class="col-12 md:col-3">
<div class="card overview-box red">
<div class="overview-info">
<h6>Factures impayées</h6>
<h1>#{dashboardView.facturesImpayees}</h1>
<p class="subtitle">Attention requise</p>
</div>
</div>
<!-- ====================================================================
SECTION CENTRALE : Graphique + KPIs Ressources
==================================================================== -->
<!-- Colonne gauche: Statistiques chantiers (placeholder pour graphique futur) -->
<div class="col-12 xl:col-8">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Vue d'ensemble</h6>
<p class="subtitle">Statistiques globales</p>
</div>
</div>
<div class="grid">
<!-- Chantiers actifs avec progression -->
<div class="col-12 md:col-6">
<div class="statistic-item" style="padding: 1.5rem; background: var(--blue-50); border-radius: var(--border-radius); border-left: 4px solid var(--blue-500);">
<div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 0.75rem;">
<i class="pi pi-building" style="font-size: 2rem; color: var(--blue-500);"></i>
<div style="flex: 1;">
<h5 style="margin: 0; font-size: 1.75rem; color: var(--blue-600);">#{dashboardView.chantiersActifs}</h5>
<h6 style="margin: 0.25rem 0 0 0; font-weight: 500; color: var(--text-color-secondary);">Chantiers actifs</h6>
</div>
</div>
<p:progressBar value="#{dashboardView.tauxActiviteChantiers}"
showValue="true"
displayValue="#{dashboardView.tauxActiviteChantiers}% d'activité"
styleClass="ui-progressbar-info"
style="height: 1rem;"/>
</div>
</div>
<!-- Chantiers en retard -->
<div class="col-12 md:col-6">
<div class="statistic-item" style="padding: 1.5rem; background: var(--orange-50); border-radius: var(--border-radius); border-left: 4px solid var(--orange-500);">
<div style="display: flex; align-items: center; gap: 1rem;">
<i class="pi pi-exclamation-triangle" style="font-size: 2rem; color: var(--orange-500);"></i>
<div style="flex: 1;">
<h5 style="margin: 0; font-size: 1.75rem; color: var(--orange-600);">#{dashboardView.chantiersEnRetardList.size()}</h5>
<h6 style="margin: 0.25rem 0 0 0; font-weight: 500; color: var(--text-color-secondary);">Chantiers en retard</h6>
</div>
</div>
<p:outputPanel rendered="#{dashboardView.chantiersEnRetardList.size() > 0}">
<small style="display: block; margin-top: 0.75rem; color: var(--orange-700);">
<i class="pi pi-info-circle"></i> Attention requise
</small>
</p:outputPanel>
</div>
</div>
<!-- Événements aujourd'hui -->
<div class="col-12 md:col-6">
<div class="statistic-item" style="padding: 1.5rem; background: var(--purple-50); border-radius: var(--border-radius); border-left: 4px solid var(--purple-500);">
<div style="display: flex; align-items: center; gap: 1rem;">
<i class="pi pi-calendar" style="font-size: 2rem; color: var(--purple-500);"></i>
<div style="flex: 1;">
<h5 style="margin: 0; font-size: 1.75rem; color: var(--purple-600);">#{dashboardView.evenementsAujourdhui}</h5>
<h6 style="margin: 0.25rem 0 0 0; font-weight: 500; color: var(--text-color-secondary);">Événements aujourd'hui</h6>
</div>
</div>
</div>
</div>
<!-- Documents totaux -->
<div class="col-12 md:col-6">
<div class="statistic-item" style="padding: 1.5rem; background: var(--cyan-50); border-radius: var(--border-radius); border-left: 4px solid var(--cyan-500);">
<div style="display: flex; align-items: center; gap: 1rem;">
<i class="pi pi-file" style="font-size: 2rem; color: var(--cyan-500);"></i>
<div style="flex: 1;">
<h5 style="margin: 0; font-size: 1.75rem; color: var(--cyan-600);">#{dashboardView.nombreDocuments}</h5>
<h6 style="margin: 0.25rem 0 0 0; font-weight: 500; color: var(--text-color-secondary);">Documents totaux</h6>
</div>
</div>
</div>
<i class="pi pi-exclamation-triangle"></i>
</div>
</div>
</div>
</div>
<!-- Alertes critiques -->
<p:outputPanel rendered="#{dashboardView.alerteCritique}" styleClass="col-12">
<div class="card" style="background: #fff3cd; border-left: 4px solid #ffc107;">
<div class="grid align-items-center">
<div class="col">
<h5 style="margin: 0; color: #856404;">
<i class="pi pi-exclamation-triangle"></i>
Alertes critiques : #{dashboardView.totalAlertes}
</h5>
<p style="margin: 0.5rem 0 0 0; color: #856404;">
Des actions nécessitent votre attention immédiate
</p>
</div>
<div class="col-auto">
<p:commandButton value="Voir les alertes" icon="pi pi-bell"
outcome="/dashboard/alertes"
styleClass="ui-button-warning"/>
<!-- Colonne droite: KPIs Ressources -->
<div class="col-12 xl:col-4">
<div class="card" style="height: 100%;">
<div class="card-header">
<div class="card-title">
<h6>Ressources</h6>
<p class="subtitle">État actuel des ressources</p>
</div>
</div>
</div>
</p:outputPanel>
<div style="padding: 1rem; display: flex; flex-direction: column; gap: 1.5rem;">
<!-- Graphiques et métriques financières -->
<div class="col-12 lg:col-8">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Évolution des chantiers</h6>
<p class="subtitle">Sur 6 mois</p>
</div>
</div>
<canvas id="chartChantiers" style="max-height: 300px;"></canvas>
</div>
</div>
<div class="col-12 lg:col-4">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Chiffre d'affaires</h6>
<p class="subtitle">Ce mois</p>
</div>
</div>
<div class="statistic-item">
<h1 style="margin: 0;">
<h:outputText value="#{dashboardView.chiffreAffairesMois}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</h1>
<p style="color: var(--text-color-secondary); margin-top: 0.5rem;">
<i class="pi pi-info-circle"></i>
Données réelles de l'API
</p>
</div>
</div>
<div class="card" style="margin-top: 1rem;">
<div class="card-header">
<div class="card-title">
<h6>Budget consommé</h6>
<p class="subtitle">Sur #{dashboardView.budgetTotal} Fcfa</p>
</div>
</div>
<div class="statistic-item">
<p:progressBar value="#{dashboardView.tauxConsommationBudget}"
showValue="true"
styleClass="ui-progressbar-#{dashboardView.tauxConsommationBudget > 80 ? 'warn' : 'success'}"/>
<p style="color: var(--text-color-secondary); margin-top: 0.5rem;">
<h:outputText value="#{dashboardView.budgetConsomme}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa consommés"/>
</p>
</div>
</div>
</div>
<!-- Ressources : Employés, Équipes, Matériel -->
<div class="col-12 lg:col-4">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Ressources humaines</h6>
<p class="subtitle">Employés et équipes</p>
</div>
</div>
<div class="grid" style="gap: 1rem;">
<div class="col-12">
<div class="flex align-items-center justify-content-between">
<span><i class="pi pi-users"></i> Employés</span>
<strong>#{dashboardView.nombreEmployes}</strong>
<!-- Employés actifs -->
<div class="statistic-item" style="padding: 1.25rem; background: var(--green-50); border-radius: var(--border-radius); border-left: 4px solid var(--green-500);">
<div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 0.75rem;">
<i class="pi pi-users" style="font-size: 1.75rem; color: var(--green-500);"></i>
<div style="flex: 1;">
<h5 style="margin: 0; font-size: 1.5rem; color: var(--green-600);">
#{dashboardView.employesActifs}<span style="font-size: 1rem; color: var(--text-color-secondary);">/#{dashboardView.nombreEmployes}</span>
</h5>
<h6 style="margin: 0.25rem 0 0 0; font-weight: 500; color: var(--text-color-secondary);">Employés actifs</h6>
</div>
</div>
</div>
<div class="col-12">
<div class="flex align-items-center justify-content-between">
<span><i class="pi pi-users"></i> Équipes</span>
<strong>#{dashboardView.nombreEquipes}</strong>
</div>
<p:progressBar value="#{dashboardView.nombreEquipes > 0 ? (dashboardView.equipesDisponibles * 100 / dashboardView.nombreEquipes) : 0}"
<p:progressBar value="#{dashboardView.tauxActiviteEmployes}"
showValue="true"
styleClass="ui-progressbar-info"/>
<small style="color: var(--text-color-secondary);">
#{dashboardView.equipesDisponibles} disponibles
displayValue="#{dashboardView.tauxActiviteEmployes}%"
styleClass="ui-progressbar-#{dashboardView.tauxActiviteEmployes > 80 ? 'success' : (dashboardView.tauxActiviteEmployes > 60 ? 'warning' : 'danger')}"
style="height: 1rem;"/>
</div>
<!-- Matériel disponible -->
<div class="statistic-item" style="padding: 1.25rem; background: var(--teal-50); border-radius: var(--border-radius); border-left: 4px solid var(--teal-500);">
<div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 0.75rem;">
<i class="pi pi-cog" style="font-size: 1.75rem; color: var(--teal-500);"></i>
<div style="flex: 1;">
<h5 style="margin: 0; font-size: 1.5rem; color: var(--teal-600);">
#{dashboardView.materielDisponible}<span style="font-size: 1rem; color: var(--text-color-secondary);">/#{dashboardView.nombreMateriel}</span>
</h5>
<h6 style="margin: 0.25rem 0 0 0; font-weight: 500; color: var(--text-color-secondary);">Matériel disponible</h6>
</div>
</div>
<p:progressBar value="#{dashboardView.tauxDisponibiliteMateriel}"
showValue="true"
displayValue="#{dashboardView.tauxDisponibiliteMateriel}%"
styleClass="ui-progressbar-success"
style="height: 1rem;"/>
</div>
<!-- Taux d'utilisation global -->
<div class="statistic-item" style="padding: 1.25rem; background: var(--indigo-50); border-radius: var(--border-radius); border-left: 4px solid var(--indigo-500); flex: 1; display: flex; flex-direction: column; justify-content: center;">
<div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 0.5rem;">
<i class="pi pi-chart-line" style="font-size: 1.75rem; color: var(--indigo-500);"></i>
<div style="flex: 1;">
<h5 style="margin: 0; font-size: 1.75rem; color: var(--indigo-600);">#{dashboardView.tauxUtilisationGlobal}%</h5>
<h6 style="margin: 0.25rem 0 0 0; font-weight: 500; color: var(--text-color-secondary);">Taux d'utilisation global</h6>
</div>
</div>
<small style="display: block; color: var(--text-color-secondary); font-style: italic; padding-left: 2.75rem;">
<i class="pi pi-info-circle" style="font-size: 0.875rem;"></i>
Moyenne chantiers, employés et matériel
</small>
</div>
</div>
</div>
</div>
<div class="col-12 lg:col-4">
<!-- ====================================================================
TABLEAU CHANTIERS ACTIFS
==================================================================== -->
<div class="col-12">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Matériel</h6>
<p class="subtitle">Équipements disponibles</p>
<h6>Chantiers actifs</h6>
<p class="subtitle">#{dashboardView.chantiersActifsList.size()} chantiers en cours</p>
</div>
</div>
<div class="grid" style="gap: 1rem;">
<div class="col-12">
<div class="flex align-items-center justify-content-between">
<span><i class="pi pi-wrench"></i> Total matériel</span>
<strong>#{dashboardView.nombreMateriel}</strong>
</div>
<p:progressBar value="#{dashboardView.nombreMateriel > 0 ? (dashboardView.materielDisponible * 100 / dashboardView.nombreMateriel) : 0}"
showValue="true"
styleClass="ui-progressbar-success"/>
<small style="color: var(--text-color-secondary);">
#{dashboardView.materielDisponible} disponibles
</small>
</div>
</div>
</div>
</div>
<div class="col-12 lg:col-4">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Maintenance</h6>
<p class="subtitle">État des maintenances</p>
</div>
</div>
<div class="grid" style="gap: 1rem;">
<div class="col-12">
<div class="flex align-items-center justify-content-between">
<span><i class="pi pi-exclamation-circle" style="color: red;"></i> En retard</span>
<strong style="color: red;">#{dashboardView.maintenancesEnRetard}</strong>
</div>
</div>
<div class="col-12">
<div class="flex align-items-center justify-content-between">
<span><i class="pi pi-calendar"></i> Planifiées</span>
<strong>#{dashboardView.maintenancesPlanifiees}</strong>
</div>
</div>
<div class="col-12">
<p:commandButton value="Voir les maintenances" icon="pi pi-cog"
outcome="/maintenance"
styleClass="ui-button-text" style="width: 100%;"/>
</div>
</div>
</div>
</div>
<!-- Chantiers récents -->
<div class="col-12 lg:col-8">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Chantiers récents</h6>
<p class="subtitle">Derniers chantiers actifs</p>
</div>
<p:commandButton value="Voir tout" icon="pi pi-arrow-right"
<p:commandButton value="Voir tout"
icon="pi pi-arrow-right"
outcome="/chantiers"
styleClass="ui-button-text"/>
</div>
<p:dataTable value="#{dashboardView.chantiersRecents}" var="chantier"
emptyMessage="Aucun chantier récent">
<p:column headerText="Nom">
<p:dataTable value="#{dashboardView.chantiersActifsList}"
var="chantier"
emptyMessage="Aucun chantier actif pour le moment"
styleClass="p-datatable-sm"
paginator="true"
rows="10"
paginatorPosition="bottom">
<p:column headerText="Nom" sortBy="#{chantier.nom}">
<h:outputText value="#{chantier.nom}"/>
</p:column>
<p:column headerText="Client">
<p:column headerText="Client" sortBy="#{chantier.client}">
<h:outputText value="#{chantier.client}"/>
</p:column>
<p:column headerText="Date de début">
<p:column headerText="Date début" sortBy="#{chantier.dateDebut}">
<h:outputText value="#{chantier.dateDebutFormatee}"/>
</p:column>
<p:column headerText="Fin prévue" sortBy="#{chantier.dateFinPrevue}">
<h:outputText value="#{chantier.dateFinPrevueFormatee}"/>
</p:column>
<p:column headerText="Avancement">
<p:progressBar value="#{chantier.avancement}"
showValue="true"
styleClass="ui-progressbar-success"/>
<p:progressBar value="#{chantier.avancement}"
showValue="true"
displayValue="#{chantier.avancement}%"
styleClass="ui-progressbar-success"/>
</p:column>
<p:column headerText="Actions">
<p:commandButton icon="pi pi-eye" title="Voir les détails"
styleClass="ui-button-text"
outcome="/chantiers/details?id=#{chantier.id}"/>
<p:column headerText="Budget" sortBy="#{chantier.budget}">
<h:outputText value="#{chantier.budget}">
<f:convertNumber type="number" groupingUsed="true"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</p:column>
<p:column headerText="Coût réel" sortBy="#{chantier.coutReel}">
<h:outputText value="#{chantier.coutReel}"
style="#{chantier.depassementBudget ? 'color: var(--red-500); font-weight: bold;' : ''}">
<f:convertNumber type="number" groupingUsed="true"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
<p:badge value="!" severity="danger"
style="margin-left: 0.5rem;"
rendered="#{chantier.depassementBudget}"/>
</p:column>
<p:column headerText="Statut">
<p:badge value="#{chantier.statut}"
severity="#{chantier.statut == 'EN_COURS' ? 'info' : 'success'}"/>
</p:column>
</p:dataTable>
</div>
</div>
<!-- ====================================================================
SECTION BAS : Chantiers en retard + Maintenances en retard
==================================================================== -->
<!-- Chantiers en retard -->
<div class="col-12 lg:col-4">
<div class="col-12 md:col-6">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Chantiers en retard</h6>
<p class="subtitle">Attention requise</p>
<p class="subtitle">#{dashboardView.chantiersEnRetardList.size()} chantiers en retard</p>
</div>
</div>
<p:dataList value="#{dashboardView.chantiersEnRetard}" var="chantier"
emptyMessage="Aucun chantier en retard">
<div class="flex align-items-center justify-content-between" style="padding: 0.75rem; border-bottom: 1px solid var(--surface-border);">
<div>
<strong>#{chantier.nom}</strong>
<br/>
<small style="color: var(--text-color-secondary);">
#{chantier.dateFinPrevueFormatee}
</small>
<ui:repeat value="#{dashboardView.chantiersEnRetardList}" var="chantier">
<div class="chantier-retard-item" style="padding: 1rem; border-bottom: 1px solid var(--surface-border); background: var(--orange-50);">
<div style="display: flex; justify-content: space-between; align-items: start;">
<div>
<h6 style="margin: 0 0 0.5rem 0;">
<i class="pi pi-building" style="color: var(--orange-500);"></i>
#{chantier.nom}
</h6>
<p style="margin: 0.25rem 0; font-size: 0.9rem;">
<strong>Date fin prévue:</strong> #{chantier.dateFinPrevueFormatee}
</p>
</div>
<p:badge value="+#{chantier.joursRetard}j" severity="warning" size="large"/>
</div>
<p:tag value="+#{chantier.joursRetard}j" severity="danger"/>
</div>
</p:dataList>
<p:outputPanel rendered="#{empty dashboardView.chantiersEnRetard}">
<p style="text-align: center; padding: 1rem; color: var(--text-color-secondary);">
<i class="pi pi-check-circle" style="color: green;"></i>
Aucun chantier en retard
</p>
</ui:repeat>
<p:outputPanel rendered="#{empty dashboardView.chantiersEnRetardList}">
<div style="padding: 2rem; text-align: center; color: var(--green-500);">
<i class="pi pi-check-circle" style="font-size: 3rem;"></i>
<p style="margin-top: 1rem;">Tous les chantiers sont dans les temps</p>
</div>
</p:outputPanel>
</div>
</div>
<!-- Maintenances en retard -->
<div class="col-12 md:col-6">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Maintenances en retard</h6>
<p class="subtitle">#{dashboardView.maintenancesEnRetardList.size()} maintenances urgentes</p>
</div>
</div>
<ui:repeat value="#{dashboardView.maintenancesEnRetardList}" var="maintenance">
<div class="maintenance-item" style="padding: 1rem; border-bottom: 1px solid var(--surface-border); background: var(--red-50);">
<div style="display: flex; justify-content: space-between; align-items: start;">
<div>
<h6 style="margin: 0 0 0.5rem 0;">
<i class="pi pi-wrench" style="color: var(--red-500);"></i>
#{maintenance.materiel}
</h6>
<p style="margin: 0.25rem 0; font-size: 0.9rem;">
<strong>Type:</strong> #{maintenance.type} •
<strong>Prévue:</strong> #{maintenance.datePrevueFormatee}
</p>
<p style="margin: 0.25rem 0; font-size: 0.85rem; color: var(--text-color-secondary);">
#{maintenance.description}
</p>
</div>
<p:badge value="+#{maintenance.joursRetard}j" severity="danger" size="large"/>
</div>
</div>
</ui:repeat>
<p:outputPanel rendered="#{empty dashboardView.maintenancesEnRetardList}">
<div style="padding: 2rem; text-align: center; color: var(--green-500);">
<i class="pi pi-check-circle" style="font-size: 3rem;"></i>
<p style="margin-top: 1rem;">Toutes les maintenances sont à jour</p>
</div>
</p:outputPanel>
</div>
</div>
<!-- ====================================================================
SECTION BAS 2 : Disponibilités en attente + Documents récents
==================================================================== -->
<!-- Disponibilités en attente -->
<div class="col-12 md:col-6">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Disponibilités en attente</h6>
<p class="subtitle">#{dashboardView.disponibilitesEnAttenteList.size()} demandes à valider</p>
</div>
</div>
<ui:repeat value="#{dashboardView.disponibilitesEnAttenteList}" var="dispo">
<div class="disponibilite-card" style="padding: 1rem; border-bottom: 1px solid var(--surface-border);">
<div style="display: flex; justify-content: space-between; align-items: start;">
<div style="flex: 1;">
<div style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;">
<i class="pi pi-user"></i>
<strong>#{dispo.employe}</strong>
</div>
<div style="margin: 0.5rem 0;">
<p:badge value="#{dispo.type}"
severity="#{dashboardView.getSeveriteDisponibilite(dispo.type)}"/>
<span style="margin-left: 0.5rem; font-size: 0.9rem;">
Du #{dispo.dateDebutFormatee} au #{dispo.dateFinFormatee}
(#{dispo.nombreJours} jours)
</span>
</div>
<small style="color: var(--text-color-secondary);">
<strong>Motif:</strong> #{dispo.motif}
</small>
</div>
</div>
</div>
</ui:repeat>
<p:outputPanel rendered="#{empty dashboardView.disponibilitesEnAttenteList}">
<div style="padding: 2rem; text-align: center; color: var(--text-color-secondary);">
<i class="pi pi-inbox" style="font-size: 2rem;"></i>
<p style="margin-top: 1rem;">Aucune demande de disponibilité en attente</p>
</div>
</p:outputPanel>
</div>
</div>
<!-- Documents récents -->
<div class="col-12 md:col-6">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Documents récents</h6>
<p class="subtitle">5 derniers documents ajoutés</p>
</div>
</div>
<ul class="documents-list" style="list-style: none; padding: 0; margin: 0;">
<ui:repeat value="#{dashboardView.documentsRecentsList}" var="doc">
<li style="padding: 1rem; border-bottom: 1px solid var(--surface-border); display: flex; align-items: center; gap: 1rem;">
<i class="#{dashboardView.getIconeDocument(doc.type)}"
style="font-size: 2rem; color: var(--primary-color);"></i>
<div style="flex: 1;">
<div style="font-weight: 500;">#{doc.nom}</div>
<small style="color: var(--text-color-secondary);">
#{doc.type} • Ajouté le #{doc.dateCreationFormatee}
</small>
</div>
<p:button icon="pi pi-download" styleClass="ui-button-text ui-button-sm"/>
</li>
</ui:repeat>
</ul>
<p:outputPanel rendered="#{empty dashboardView.documentsRecentsList}">
<div style="padding: 2rem; text-align: center; color: var(--text-color-secondary);">
<i class="pi pi-file" style="font-size: 2rem;"></i>
<p style="margin-top: 1rem;">Aucun document récent</p>
</div>
</p:outputPanel>
</div>
</div>

View File

@@ -1,8 +1,8 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:p="http://primefaces.org/ui"
template="/WEB-INF/template.xhtml">
<ui:define name="title">Devis - BTP Xpress</ui:define>
@@ -12,12 +12,101 @@
<div class="grid">
<div class="col-12">
<div class="card">
<h1>Gestion des Devis</h1>
<p>Module en cours de développement...</p>
<div class="flex align-items-center justify-content-between mb-3">
<h1>Gestion des Devis</h1>
<p:commandButton value="Nouveau devis" icon="pi pi-plus"
action="#{devisView.createNew()}"
styleClass="ui-button-primary"/>
</div>
</div>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-filters.xhtml">
<ui:param name="formId" value="filtresForm"/>
<ui:param name="viewBean" value="#{devisView}"/>
<ui:param name="tableId" value="devisTable"/>
<ui:define name="filter-fields">
<div class="grid">
<div class="col-12 md:col-4">
<h:outputLabel for="filtreNumero" value="Numéro"/>
<p:inputText id="filtreNumero" value="#{devisView.filtreNumero}"
placeholder="Rechercher par numéro..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreClient" value="Client"/>
<p:inputText id="filtreClient" value="#{devisView.filtreClient}"
placeholder="Rechercher par client..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreStatut" value="Statut"/>
<p:selectOneMenu id="filtreStatut" value="#{devisView.filtreStatut}" style="width: 100%;">
<f:selectItem itemLabel="Tous" itemValue="TOUS"/>
<f:selectItem itemLabel="Brouillon" itemValue="BROUILLON"/>
<f:selectItem itemLabel="En attente" itemValue="EN_ATTENTE"/>
<f:selectItem itemLabel="Accepté" itemValue="ACCEPTE"/>
<f:selectItem itemLabel="Refusé" itemValue="REFUSE"/>
<f:selectItem itemLabel="Expiré" itemValue="EXPIRE"/>
</p:selectOneMenu>
</div>
</div>
</ui:define>
</ui:include>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-table.xhtml">
<ui:param name="formId" value="devisForm"/>
<ui:param name="tableId" value="devisTable"/>
<ui:param name="viewBean" value="#{devisView}"/>
<ui:param name="var" value="devis"/>
<ui:param name="title" value="Liste des devis"/>
<ui:param name="createPath" value="/devis/nouveau"/>
<ui:define name="columns">
<p:column headerText="Numéro" sortBy="#{devis.numero}">
<h:outputText value="#{devis.numero}"/>
</p:column>
<p:column headerText="Objet" sortBy="#{devis.objet}">
<h:outputText value="#{devis.objet}"/>
</p:column>
<p:column headerText="Client" sortBy="#{devis.client}">
<h:outputText value="#{devis.client}"/>
</p:column>
<p:column headerText="Date émission" sortBy="#{devis.dateEmission}">
<h:outputText value="#{devis.dateEmission}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
<p:column headerText="Date validité" sortBy="#{devis.dateValidite}">
<h:outputText value="#{devis.dateValidite}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
<p:column headerText="Montant HT">
<h:outputText value="#{devis.montantHT}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</p:column>
<p:column headerText="Montant TTC">
<h:outputText value="#{devis.montantTTC}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</p:column>
<p:column headerText="Statut" sortBy="#{devis.statut}">
<p:tag value="#{devis.statut}"
severity="#{devis.statut == 'ACCEPTE' ? 'success' : (devis.statut == 'REFUSE' ? 'danger' : (devis.statut == 'EXPIRE' ? 'warning' : 'info'))}"/>
</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="#{devisView.viewDetails(devis.id)}"/>
</p:column>
</ui:define>
</ui:include>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1 +1,27 @@
<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">Acceptes - DEVIS - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>Acceptes</h1><p>Module en cours de développement...</p><p:commandButton value="Retour" icon="pi pi-arrow-left" outcome="/devis" styleClass="ui-button-secondary"/></div></div></div></div></ui:define></ui:composition>
<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">Devis acceptés - BTP Xpress</ui:define>
<ui:define name="content">
<div class="layout-dashboard">
<div class="grid">
<div class="col-12">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Devis acceptés</h6>
<p class="subtitle">Devis acceptés par les clients</p>
</div>
</div>
<p>Page en développement</p>
</div>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1 +1,27 @@
<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">Expires - DEVIS - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>Expires</h1><p>Module en cours de développement...</p><p:commandButton value="Retour" icon="pi pi-arrow-left" outcome="/devis" styleClass="ui-button-secondary"/></div></div></div></div></ui:define></ui:composition>
<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">Devis expirés - BTP Xpress</ui:define>
<ui:define name="content">
<div class="layout-dashboard">
<div class="grid">
<div class="col-12">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Devis expirés</h6>
<p class="subtitle">Devis dont la validité est expirée</p>
</div>
</div>
<p>Page en développement</p>
</div>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1 +0,0 @@
<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">DEVIS - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>DEVIS</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1,8 +1,8 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:p="http://primefaces.org/ui"
template="/WEB-INF/template.xhtml">
<ui:define name="title">Employés - BTP Xpress</ui:define>
@@ -12,12 +12,91 @@
<div class="grid">
<div class="col-12">
<div class="card">
<h1>Gestion des Employés</h1>
<p>Module en cours de développement...</p>
<div class="flex align-items-center justify-content-between mb-3">
<h1>Gestion des Employés</h1>
<p:commandButton value="Nouvel employé" icon="pi pi-user-plus"
action="#{employeView.createNew()}"
styleClass="ui-button-primary"/>
</div>
</div>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-filters.xhtml">
<ui:param name="formId" value="filtresForm"/>
<ui:param name="viewBean" value="#{employeView}"/>
<ui:param name="tableId" value="employesTable"/>
<ui:define name="filter-fields">
<div class="grid">
<div class="col-12 md:col-4">
<h:outputLabel for="filtreNom" value="Nom"/>
<p:inputText id="filtreNom" value="#{employeView.filtreNom}"
placeholder="Rechercher par nom..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtrePoste" value="Poste"/>
<p:inputText id="filtrePoste" value="#{employeView.filtrePoste}"
placeholder="Rechercher par poste..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreStatut" value="Statut"/>
<p:selectOneMenu id="filtreStatut" value="#{employeView.filtreStatut}" style="width: 100%;">
<f:selectItem itemLabel="Tous" itemValue="TOUS"/>
<f:selectItem itemLabel="Actif" itemValue="ACTIF"/>
<f:selectItem itemLabel="Inactif" itemValue="INACTIF"/>
<f:selectItem itemLabel="En congé" itemValue="EN_CONGE"/>
</p:selectOneMenu>
</div>
</div>
</ui:define>
</ui:include>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-table.xhtml">
<ui:param name="formId" value="employesForm"/>
<ui:param name="tableId" value="employesTable"/>
<ui:param name="viewBean" value="#{employeView}"/>
<ui:param name="var" value="employe"/>
<ui:param name="title" value="Liste des employés"/>
<ui:param name="createPath" value="/employes/nouveau"/>
<ui:define name="columns">
<p:column headerText="Nom complet" sortBy="#{employe.nomComplet}">
<h:outputText value="#{employe.nomComplet}"/>
</p:column>
<p:column headerText="Email" sortBy="#{employe.email}">
<h:outputText value="#{employe.email}"/>
</p:column>
<p:column headerText="Téléphone">
<h:outputText value="#{employe.telephone}"/>
</p:column>
<p:column headerText="Poste" sortBy="#{employe.poste}">
<h:outputText value="#{employe.poste}"/>
</p:column>
<p:column headerText="Taux horaire">
<h:outputText value="#{employe.tauxHoraire}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa/h"/>
</p:column>
<p:column headerText="Date embauche" sortBy="#{employe.dateEmbauche}">
<h:outputText value="#{employe.dateEmbauche}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
<p:column headerText="Statut" sortBy="#{employe.statut}">
<p:tag value="#{employe.statut}"
severity="#{employe.statut == 'ACTIF' ? 'success' : 'warning'}"/>
</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="#{employeView.viewDetails(employe.id)}"/>
</p:column>
</ui:define>
</ui:include>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1 +0,0 @@
<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">EMPLOYES - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>EMPLOYES</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1,8 +1,8 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:p="http://primefaces.org/ui"
template="/WEB-INF/template.xhtml">
<ui:define name="title">Équipes - BTP Xpress</ui:define>
@@ -12,12 +12,82 @@
<div class="grid">
<div class="col-12">
<div class="card">
<h1>Gestion des Équipes</h1>
<p>Module en cours de développement...</p>
<div class="flex align-items-center justify-content-between mb-3">
<h1>Gestion des Équipes</h1>
<p:commandButton value="Nouvelle équipe" icon="pi pi-users"
action="#{equipeView.createNew()}"
styleClass="ui-button-primary"/>
</div>
</div>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-filters.xhtml">
<ui:param name="formId" value="filtresForm"/>
<ui:param name="viewBean" value="#{equipeView}"/>
<ui:param name="tableId" value="equipesTable"/>
<ui:define name="filter-fields">
<div class="grid">
<div class="col-12 md:col-4">
<h:outputLabel for="filtreNom" value="Nom de l'équipe"/>
<p:inputText id="filtreNom" value="#{equipeView.filtreNom}"
placeholder="Rechercher par nom..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreSpecialite" value="Spécialité"/>
<p:inputText id="filtreSpecialite" value="#{equipeView.filtreSpecialite}"
placeholder="Rechercher par spécialité..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreStatut" value="Statut"/>
<p:selectOneMenu id="filtreStatut" value="#{equipeView.filtreStatut}" style="width: 100%;">
<f:selectItem itemLabel="Tous" itemValue="TOUS"/>
<f:selectItem itemLabel="Active" itemValue="ACTIVE"/>
<f:selectItem itemLabel="Inactive" itemValue="INACTIVE"/>
</p:selectOneMenu>
</div>
</div>
</ui:define>
</ui:include>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-table.xhtml">
<ui:param name="formId" value="equipesForm"/>
<ui:param name="tableId" value="equipesTable"/>
<ui:param name="viewBean" value="#{equipeView}"/>
<ui:param name="var" value="equipe"/>
<ui:param name="title" value="Liste des équipes"/>
<ui:param name="createPath" value="/equipes/nouvelle"/>
<ui:define name="columns">
<p:column headerText="Nom" sortBy="#{equipe.nom}">
<h:outputText value="#{equipe.nom}"/>
</p:column>
<p:column headerText="Chef d'équipe" sortBy="#{equipe.chef}">
<h:outputText value="#{equipe.chef}"/>
</p:column>
<p:column headerText="Spécialité" sortBy="#{equipe.specialite}">
<h:outputText value="#{equipe.specialite}"/>
</p:column>
<p:column headerText="Nombre de membres">
<p:tag value="#{equipe.nombreMembres}" severity="info"/>
</p:column>
<p:column headerText="Description">
<h:outputText value="#{equipe.description}"/>
</p:column>
<p:column headerText="Statut" sortBy="#{equipe.statut}">
<p:tag value="#{equipe.statut}"
severity="#{equipe.statut == 'ACTIVE' ? 'success' : 'warning'}"/>
</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="#{equipeView.viewDetails(equipe.id)}"/>
</p:column>
</ui:define>
</ui:include>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1 +0,0 @@
<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">EQUIPES - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>EQUIPES</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1 +0,0 @@
<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">Nouvelle - EQUIPES - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>Nouvelle</h1><p>Module en cours de développement...</p><p:commandButton value="Retour" icon="pi pi-arrow-left" outcome="/equipes" styleClass="ui-button-secondary"/></div></div></div></div></ui:define></ui:composition>

View File

@@ -1,8 +1,8 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:p="http://primefaces.org/ui"
template="/WEB-INF/template.xhtml">
<ui:define name="title">Factures - BTP Xpress</ui:define>
@@ -12,12 +12,111 @@
<div class="grid">
<div class="col-12">
<div class="card">
<h1>Gestion des Factures</h1>
<p>Module en cours de développement...</p>
<div class="flex align-items-center justify-content-between mb-3">
<h1>Gestion des Factures</h1>
<p:commandButton value="Nouvelle facture" icon="pi pi-plus"
action="#{factureView.createNew()}"
styleClass="ui-button-primary"/>
</div>
</div>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-filters.xhtml">
<ui:param name="formId" value="filtresForm"/>
<ui:param name="viewBean" value="#{factureView}"/>
<ui:param name="tableId" value="facturesTable"/>
<ui:define name="filter-fields">
<div class="grid">
<div class="col-12 md:col-4">
<h:outputLabel for="filtreNumero" value="Numéro"/>
<p:inputText id="filtreNumero" value="#{factureView.filtreNumero}"
placeholder="Rechercher par numéro..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreClient" value="Client"/>
<p:inputText id="filtreClient" value="#{factureView.filtreClient}"
placeholder="Rechercher par client..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreStatut" value="Statut"/>
<p:selectOneMenu id="filtreStatut" value="#{factureView.filtreStatut}" style="width: 100%;">
<f:selectItem itemLabel="Tous" itemValue="TOUS"/>
<f:selectItem itemLabel="Brouillon" itemValue="BROUILLON"/>
<f:selectItem itemLabel="Émise" itemValue="EMISE"/>
<f:selectItem itemLabel="Envoyée" itemValue="ENVOYEE"/>
<f:selectItem itemLabel="Payée" itemValue="PAYEE"/>
<f:selectItem itemLabel="En retard" itemValue="EN_RETARD"/>
<f:selectItem itemLabel="Annulée" itemValue="ANNULEE"/>
</p:selectOneMenu>
</div>
</div>
</ui:define>
</ui:include>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-table.xhtml">
<ui:param name="formId" value="facturesForm"/>
<ui:param name="tableId" value="facturesTable"/>
<ui:param name="viewBean" value="#{factureView}"/>
<ui:param name="var" value="facture"/>
<ui:param name="title" value="Liste des factures"/>
<ui:param name="createPath" value="/factures/nouvelle"/>
<ui:define name="columns">
<p:column headerText="Numéro" sortBy="#{facture.numero}">
<h:outputText value="#{facture.numero}"/>
</p:column>
<p:column headerText="Objet" sortBy="#{facture.objet}">
<h:outputText value="#{facture.objet}"/>
</p:column>
<p:column headerText="Client" sortBy="#{facture.client}">
<h:outputText value="#{facture.client}"/>
</p:column>
<p:column headerText="Date émission" sortBy="#{facture.dateEmission}">
<h:outputText value="#{facture.dateEmission}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
<p:column headerText="Date échéance" sortBy="#{facture.dateEcheance}">
<h:outputText value="#{facture.dateEcheance}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
<h:outputText value=" ⚠️" rendered="#{factureView.isEnRetard(facture)}"
title="Facture en retard" style="color: red;"/>
</p:column>
<p:column headerText="Montant TTC">
<h:outputText value="#{facture.montantTTC}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</p:column>
<p:column headerText="Montant payé">
<h:outputText value="#{facture.montantPaye}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</p:column>
<p:column headerText="Reste à payer">
<h:outputText value="#{factureView.getMontantRestant(facture)}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"
style="#{factureView.getMontantRestant(facture) > 0 ? 'color: red; font-weight: bold;' : ''}"/>
</p:column>
<p:column headerText="Statut" sortBy="#{facture.statut}">
<p:tag value="#{facture.statut}"
severity="#{facture.statut == 'PAYEE' ? 'success' : (facture.statut == 'ANNULEE' ? 'danger' : (factureView.isEnRetard(facture) ? 'danger' : 'warning'))}"/>
</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="#{factureView.viewDetails(facture.id)}"/>
</p:column>
</ui:define>
</ui:include>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1 +0,0 @@
<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">FACTURES - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>FACTURES</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1 +0,0 @@
<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">Nouvelle - FACTURES - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>Nouvelle</h1><p>Module en cours de développement...</p><p:commandButton value="Retour" icon="pi pi-arrow-left" outcome="/factures" styleClass="ui-button-secondary"/></div></div></div></div></ui:define></ui:composition>

View File

@@ -1,13 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<meta http-equiv="refresh" content="0;url=dashboard.xhtml" />
<title>BTP Xpress - Redirection</title>
</h:head>
<h:body>
<h:outputText value="Redirection en cours..." />
</h:body>
</html>

View File

@@ -1 +0,0 @@
<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">MAINTENANCE - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>MAINTENANCE</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1 +1,27 @@
<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">Preventive - MAINTENANCE - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>Preventive</h1><p>Module en cours de développement...</p><p:commandButton value="Retour" icon="pi pi-arrow-left" outcome="/maintenance" styleClass="ui-button-secondary"/></div></div></div></div></ui:define></ui:composition>
<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">Maintenance préventive - BTP Xpress</ui:define>
<ui:define name="content">
<div class="layout-dashboard">
<div class="grid">
<div class="col-12">
<div class="card">
<div class="card-header">
<div class="card-title">
<h6>Maintenance préventive</h6>
<p class="subtitle">Maintenances préventives planifiées</p>
</div>
</div>
<p>Page en développement</p>
</div>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1,8 +1,8 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:p="http://primefaces.org/ui"
template="/WEB-INF/template.xhtml">
<ui:define name="title">Matériels - BTP Xpress</ui:define>
@@ -12,12 +12,100 @@
<div class="grid">
<div class="col-12">
<div class="card">
<h1>Inventaire des Matériels</h1>
<p>Module en cours de développement...</p>
<div class="flex align-items-center justify-content-between mb-3">
<h1>Gestion des Matériels</h1>
<p:commandButton value="Nouveau matériel" icon="pi pi-wrench"
action="#{materielView.createNew()}"
styleClass="ui-button-primary"/>
</div>
</div>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-filters.xhtml">
<ui:param name="formId" value="filtresForm"/>
<ui:param name="viewBean" value="#{materielView}"/>
<ui:param name="tableId" value="materielsTable"/>
<ui:define name="filter-fields">
<div class="grid">
<div class="col-12 md:col-4">
<h:outputLabel for="filtreNom" value="Nom"/>
<p:inputText id="filtreNom" value="#{materielView.filtreNom}"
placeholder="Rechercher par nom..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreType" value="Type"/>
<p:selectOneMenu id="filtreType" value="#{materielView.filtreType}" style="width: 100%;">
<f:selectItem itemLabel="Tous" itemValue="TOUS"/>
<f:selectItem itemLabel="Engin" itemValue="ENGIN"/>
<f:selectItem itemLabel="Outil" itemValue="OUTIL"/>
<f:selectItem itemLabel="Véhicule" itemValue="VEHICULE"/>
<f:selectItem itemLabel="Équipement" itemValue="EQUIPEMENT"/>
</p:selectOneMenu>
</div>
<div class="col-12 md:col-4">
<h:outputLabel for="filtreStatut" value="Statut"/>
<p:selectOneMenu id="filtreStatut" value="#{materielView.filtreStatut}" style="width: 100%;">
<f:selectItem itemLabel="Tous" itemValue="TOUS"/>
<f:selectItem itemLabel="Disponible" itemValue="DISPONIBLE"/>
<f:selectItem itemLabel="En service" itemValue="EN_SERVICE"/>
<f:selectItem itemLabel="En maintenance" itemValue="EN_MAINTENANCE"/>
<f:selectItem itemLabel="Hors service" itemValue="HORS_SERVICE"/>
</p:selectOneMenu>
</div>
</div>
</ui:define>
</ui:include>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-table.xhtml">
<ui:param name="formId" value="materielsForm"/>
<ui:param name="tableId" value="materielsTable"/>
<ui:param name="viewBean" value="#{materielView}"/>
<ui:param name="var" value="materiel"/>
<ui:param name="title" value="Liste des matériels"/>
<ui:param name="createPath" value="/materiels/nouveau"/>
<ui:define name="columns">
<p:column headerText="Nom" sortBy="#{materiel.nom}">
<h:outputText value="#{materiel.nom}"/>
</p:column>
<p:column headerText="Type" sortBy="#{materiel.type}">
<p:tag value="#{materiel.type}" severity="info"/>
</p:column>
<p:column headerText="Marque" sortBy="#{materiel.marque}">
<h:outputText value="#{materiel.marque}"/>
</p:column>
<p:column headerText="Modèle">
<h:outputText value="#{materiel.modele}"/>
</p:column>
<p:column headerText="N° série">
<h:outputText value="#{materiel.numeroSerie}"/>
</p:column>
<p:column headerText="Valeur d'achat">
<h:outputText value="#{materiel.valeurAchat}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</p:column>
<p:column headerText="Date achat" sortBy="#{materiel.dateAchat}">
<h:outputText value="#{materiel.dateAchat}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
<p:column headerText="Statut" sortBy="#{materiel.statut}">
<p:tag value="#{materiel.statut}"
severity="#{materiel.statut == 'DISPONIBLE' ? 'success' : (materiel.statut == 'HORS_SERVICE' ? 'danger' : 'warning')}"/>
</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="#{materielView.viewDetails(materiel.id)}"/>
</p:column>
</ui:define>
</ui:include>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1 +0,0 @@
<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">MATERIELS - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>MATERIELS</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1 +0,0 @@
<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">MESSAGES - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>MESSAGES</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1 +0,0 @@
<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">NOTIFICATIONS - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>NOTIFICATIONS</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1 +0,0 @@
<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">PLANNING - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>PLANNING</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1 +0,0 @@
<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">RAPPORTS - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>RAPPORTS</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -1,8 +1,8 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
<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:p="http://primefaces.org/ui"
template="/WEB-INF/template.xhtml">
<ui:define name="title">Stock - BTP Xpress</ui:define>
@@ -12,12 +12,110 @@
<div class="grid">
<div class="col-12">
<div class="card">
<h1>Gestion du Stock</h1>
<p>Module en cours de développement...</p>
<div class="flex align-items-center justify-content-between mb-3">
<h1>Gestion du Stock</h1>
<p:commandButton value="Nouvel article" icon="pi pi-box"
action="#{stockView.createNew()}"
styleClass="ui-button-primary"/>
</div>
</div>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-filters.xhtml">
<ui:param name="formId" value="filtresForm"/>
<ui:param name="viewBean" value="#{stockView}"/>
<ui:param name="tableId" value="stocksTable"/>
<ui:define name="filter-fields">
<div class="grid">
<div class="col-12 md:col-3">
<h:outputLabel for="filtreReference" value="Référence"/>
<p:inputText id="filtreReference" value="#{stockView.filtreReference}"
placeholder="Rechercher par référence..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-3">
<h:outputLabel for="filtreDesignation" value="Désignation"/>
<p:inputText id="filtreDesignation" value="#{stockView.filtreDesignation}"
placeholder="Rechercher par désignation..." style="width: 100%;"/>
</div>
<div class="col-12 md:col-3">
<h:outputLabel for="filtreCategorie" value="Catégorie"/>
<p:selectOneMenu id="filtreCategorie" value="#{stockView.filtreCategorie}" style="width: 100%;">
<f:selectItem itemLabel="Tous" itemValue="TOUS"/>
<f:selectItem itemLabel="Matériaux" itemValue="MATERIAUX"/>
<f:selectItem itemLabel="Outillage" itemValue="OUTILLAGE"/>
<f:selectItem itemLabel="Équipement" itemValue="EQUIPEMENT"/>
<f:selectItem itemLabel="Consommables" itemValue="CONSOMMABLES"/>
</p:selectOneMenu>
</div>
<div class="col-12 md:col-3">
<h:outputLabel for="filtreStatut" value="Statut"/>
<p:selectOneMenu id="filtreStatut" value="#{stockView.filtreStatut}" style="width: 100%;">
<f:selectItem itemLabel="Tous" itemValue="TOUS"/>
<f:selectItem itemLabel="Disponible" itemValue="DISPONIBLE"/>
<f:selectItem itemLabel="En rupture" itemValue="EN_RUPTURE"/>
<f:selectItem itemLabel="Seuil d'alerte" itemValue="SEUIL_ALERTE"/>
</p:selectOneMenu>
</div>
</div>
</ui:define>
</ui:include>
</div>
<div class="col-12">
<ui:include src="/WEB-INF/components/liste-table.xhtml">
<ui:param name="formId" value="stocksForm"/>
<ui:param name="tableId" value="stocksTable"/>
<ui:param name="viewBean" value="#{stockView}"/>
<ui:param name="var" value="stock"/>
<ui:param name="title" value="Inventaire du stock"/>
<ui:param name="createPath" value="/stock/nouveau"/>
<ui:define name="columns">
<p:column headerText="Référence" sortBy="#{stock.reference}">
<h:outputText value="#{stock.reference}"/>
</p:column>
<p:column headerText="Désignation" sortBy="#{stock.designation}">
<h:outputText value="#{stock.designation}"/>
</p:column>
<p:column headerText="Catégorie" sortBy="#{stock.categorie}">
<p:tag value="#{stock.categorie}" severity="info"/>
</p:column>
<p:column headerText="Quantité disponible">
<h:outputText value="#{stock.quantiteDisponible}"
style="#{stockView.isEnAlerte(stock) ? 'color: red; font-weight: bold;' : ''}"/>
<h:outputText value=" #{stock.uniteMesure}"/>
<h:outputText value=" ⚠️" rendered="#{stockView.isEnAlerte(stock)}"
title="Stock en alerte" style="color: red;"/>
</p:column>
<p:column headerText="Seuil d'alerte">
<h:outputText value="#{stock.seuilAlerte}"/>
<h:outputText value=" #{stock.uniteMesure}"/>
</p:column>
<p:column headerText="Prix unitaire">
<h:outputText value="#{stock.prixUnitaire}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</p:column>
<p:column headerText="Valeur totale">
<h:outputText value="#{stock.quantiteDisponible * stock.prixUnitaire}">
<f:converter converterId="fcfaConverter"/>
</h:outputText>
<h:outputText value=" Fcfa"/>
</p:column>
<p:column headerText="Statut" sortBy="#{stock.statut}">
<p:tag value="#{stock.statut}"
severity="#{stock.statut == 'DISPONIBLE' ? 'success' : 'danger'}"/>
</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="#{stockView.viewDetails(stock.id)}"/>
</p:column>
</ui:define>
</ui:include>
</div>
</div>
</div>
</ui:define>
</ui:composition>

View File

@@ -1 +0,0 @@
<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">STOCK - BTP Xpress</ui:define><ui:define name="content"><div class="layout-dashboard"><div class="grid"><div class="col-12"><div class="card"><h1>STOCK</h1><p>Module en cours de développement...</p></div></div></div></div></ui:define></ui:composition>

View File

@@ -31,6 +31,18 @@
<param-name>jakarta.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>jakarta.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/primefaces-freya.taglib.xml</param-value>
</context-param>
<context-param>
<param-name>jakarta.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>0</param-value>
</context-param>
<context-param>
<param-name>jakarta.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<!-- Configuration PrimeFaces -->
<context-param>
@@ -60,6 +72,16 @@
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Filtre de sécurité - Headers HTTP de sécurité -->
<filter>
<filter-name>Security Headers Filter</filter-name>
<filter-class>dev.lions.btpxpress.filter.SecurityHeadersFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Security Headers Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Servlet JSF -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
@@ -74,6 +96,10 @@
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Configuration MIME types -->
<mime-mapping>

View File

@@ -19,21 +19,39 @@ quarkus.http.port=8081
quarkus.http.cors=true
quarkus.http.cors.origins=http://localhost:8080,https://security.lions.dev
%dev.quarkus.oidc.enabled=false
%dev.quarkus.oidc.enabled=true
%prod.quarkus.oidc.enabled=true
quarkus.oidc.auth-server-url=https://security.lions.dev/realms/btpxpress
quarkus.oidc.client-id=btpxpress-frontend
quarkus.oidc.application-type=web-app
quarkus.oidc.tls.verification=required
quarkus.oidc.authentication.redirect-path=/
# Client confidential avec secret
quarkus.oidc.credentials.secret=0Ph4e31lQQuonodmLQG3JycehbFL1Hei
# PKCE activé (requis par Keycloak)
quarkus.oidc.authentication.pkce-required=true
# Laisser Quarkus auto-générer le secret PKCE (ne pas définir pkce-secret ni state-secret)
# Redirection après authentification
quarkus.oidc.authentication.redirect-path=/dashboard.xhtml
quarkus.oidc.authentication.restore-path-after-redirect=true
quarkus.oidc.authentication.cookie-path=/
quarkus.oidc.authentication.session-age-extension=PT30M
quarkus.oidc.authentication.java-script-auto-redirect=false
quarkus.oidc.authentication.force-redirect-https-scheme=false
# Token et découverte
quarkus.oidc.token.issuer=https://security.lions.dev/realms/btpxpress
quarkus.oidc.discovery-enabled=true
# Logout
quarkus.oidc.logout.path=/logout
quarkus.oidc.logout.post-logout-path=/index.xhtml
quarkus.oidc.token-state-manager.split-tokens=true
quarkus.oidc.token-state-manager.strategy=id-refresh-tokens
quarkus.oidc.token-state-manager.encryption-secret=btpxpress-secure-cookie-encryption-key-32chars-2025
quarkus.oidc.token-state-manager.encryption-required=false
quarkus.oidc.token-state-manager.cookie-max-size=8192
@@ -51,6 +69,8 @@ quarkus.security.deny-unannotated-endpoints=false
quarkus.log.level=INFO
quarkus.log.category."dev.lions.btpxpress".level=DEBUG
quarkus.log.category."io.quarkus.oidc".level=DEBUG
quarkus.log.category."io.quarkus.security".level=DEBUG
quarkus.log.console.enable=true
quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n
@@ -62,5 +82,15 @@ quarkus.rest-client."dev.lions.btpxpress.service.BtpXpressApiClient".scope=jakar
quarkus.locale=fr_FR
quarkus.http.auth.permission.public.paths=/*,/login.xhtml,/index.xhtml,/dashboard.xhtml,/chantiers.xhtml,/chantiers/*,/clients.xhtml,/clients/*
quarkus.http.auth.permission.public.policy=permit
# Ressources publiques (ordre important - du plus spécifique au plus général)
# 1. Ressources statiques JSF et layout
quarkus.http.auth.permission.static.paths=/resources/*,/jakarta.faces.resource/*,/layout/*,/demo/*,/theme/*
quarkus.http.auth.permission.static.policy=permit
# 2. Pages d'erreur seulement (pas d'index ni login)
quarkus.http.auth.permission.public-pages.paths=/error.xhtml,/access-denied.xhtml
quarkus.http.auth.permission.public-pages.policy=permit
# 3. Toutes les autres pages nécessitent une authentification (y compris / et /index.xhtml)
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated