Création de 2 écrans professionnels pour le module Devis:
1. devis/nouveau.xhtml:
- 4 sections: Informations générales, Détail du devis, Montants, Conditions
- Numéro auto-généré avec icône
- Statut avec 5 valeurs (BROUILLON, ATTENTE, ACCEPTE, REFUSE, EXPIRE)
- Dates d'émission et validité avec calendriers
- Client et objet du devis requis
- Placeholder pour lignes de devis (future développement)
- Calcul automatique TVA 18% et TTC
- Récapitulatif visuel HT/TVA/TTC avec composant monétaire
- Conditions de paiement et remarques (section collapsible)
- 3 boutons: Annuler, Brouillon, Envoyer
2. devis/details.xhtml:
- En-tête: numéro, statut, client, objet, dates
- Actions: Retour, Convertir en chantier, PDF, Modifier
- 4 KPI cards: Montant HT, TVA, TTC, Statut
- 6 onglets professionnels:
* Vue d'ensemble: infos + récap financier + actions rapides
* Détail des lignes: table lignes (placeholder)
* Conditions: paiement, délais, garanties
* Documents: GED associée (placeholder)
* Suivi: timeline actions
* Historique: modifications (placeholder)
Corrections:
- Fix navigation /factures/nouvelle -> /factures/nouveau (factures.xhtml)
- Fix menu /factures/nouvelle -> /factures/nouveau (menu.xhtml)
Tous les composants réutilisables utilisés (status-badge, monetary-display).
Validation complète côté client et serveur.
UI/UX professionnel adapté au métier BTP.
122 lines
5.6 KiB
HTML
122 lines
5.6 KiB
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:c="http://xmlns.jcp.org/jsp/jstl/core">
|
|
|
|
<!--
|
|
Composant réutilisable: Badge de statut coloré
|
|
|
|
Principe DRY: Un seul composant pour tous les badges de statut dans l'application
|
|
Write Once, Use Anywhere: Mapping automatique statut → couleur
|
|
|
|
Paramètres:
|
|
- value: Valeur du statut (requis)
|
|
- severity: Gravité explicite (success, info, warning, danger) - optionnel
|
|
- icon: Icône à afficher - optionnel
|
|
- rounded: Badge arrondi (true/false - défaut: true)
|
|
- size: Taille (normal, large - défaut: normal)
|
|
|
|
Mapping automatique des statuts métier:
|
|
SUCCESS (vert): EN_COURS, ACTIF, TERMINE, VALIDE, PAYE, LIVRE, DISPONIBLE, APPROUVE
|
|
INFO (bleu): PLANIFIE, NOUVEAU, EN_ATTENTE, BROUILLON, PENDING
|
|
WARNING (orange): RETARD, SUSPENDU, IMPAYE, ALERTE, MAINTENANCE
|
|
DANGER (rouge): ANNULE, REFUSE, EXPIRE, HORS_SERVICE, BLOQUE
|
|
|
|
Utilisation:
|
|
<ui:include src="/WEB-INF/components/status-badge.xhtml">
|
|
<ui:param name="value" value="#{chantier.statut}"/>
|
|
</ui:include>
|
|
|
|
Avec icône personnalisée:
|
|
<ui:include src="/WEB-INF/components/status-badge.xhtml">
|
|
<ui:param name="value" value="#{facture.statut}"/>
|
|
<ui:param name="icon" value="pi pi-check-circle"/>
|
|
</ui:include>
|
|
|
|
Gravité manuelle:
|
|
<ui:include src="/WEB-INF/components/status-badge.xhtml">
|
|
<ui:param name="value" value="#{custom.status}"/>
|
|
<ui:param name="severity" value="danger"/>
|
|
</ui:include>
|
|
-->
|
|
|
|
<c:set var="upperValue" value="#{value.toString().toUpperCase().replace(' ', '_')}"/>
|
|
|
|
<!-- Déterminer la gravité automatiquement si non fournie -->
|
|
<c:choose>
|
|
<!-- SUCCESS - Vert -->
|
|
<c:when test="#{not empty severity}">
|
|
<c:set var="badgeSeverity" value="#{severity}"/>
|
|
</c:when>
|
|
<c:when test="#{upperValue eq 'EN_COURS' or upperValue eq 'ACTIF' or upperValue eq 'ACTIVE' or
|
|
upperValue eq 'TERMINE' or upperValue eq 'COMPLETE' or upperValue eq 'VALIDE' or
|
|
upperValue eq 'PAYE' or upperValue eq 'PAYEE' or upperValue eq 'LIVRE' or
|
|
upperValue eq 'DISPONIBLE' or upperValue eq 'APPROUVE' or upperValue eq 'ACCEPTE' or
|
|
upperValue eq 'OPERATIONNEL'}">
|
|
<c:set var="badgeSeverity" value="success"/>
|
|
</c:when>
|
|
|
|
<!-- INFO - Bleu -->
|
|
<c:when test="#{upperValue eq 'PLANIFIE' or upperValue eq 'PLANIFIEE' or upperValue eq 'NOUVEAU' or
|
|
upperValue eq 'NOUVELLE' or upperValue eq 'EN_ATTENTE' or upperValue eq 'BROUILLON' or
|
|
upperValue eq 'PENDING' or upperValue eq 'PROGRAMME' or upperValue eq 'PREVU'}">
|
|
<c:set var="badgeSeverity" value="info"/>
|
|
</c:when>
|
|
|
|
<!-- WARNING - Orange -->
|
|
<c:when test="#{upperValue eq 'RETARD' or upperValue eq 'EN_RETARD' or upperValue eq 'SUSPENDU' or
|
|
upperValue eq 'IMPAYE' or upperValue eq 'IMPAYEE' or upperValue eq 'ALERTE' or
|
|
upperValue eq 'MAINTENANCE' or upperValue eq 'UTILISE' or upperValue eq 'OCCUPE' or
|
|
upperValue eq 'PARTIEL' or upperValue eq 'PARTIELLE'}">
|
|
<c:set var="badgeSeverity" value="warning"/>
|
|
</c:when>
|
|
|
|
<!-- DANGER - Rouge -->
|
|
<c:when test="#{upperValue eq 'ANNULE' or upperValue eq 'ANNULEE' or upperValue eq 'REFUSE' or
|
|
upperValue eq 'REFUSEE' or upperValue eq 'EXPIRE' or upperValue eq 'EXPIREE' or
|
|
upperValue eq 'HORS_SERVICE' or upperValue eq 'BLOQUE' or upperValue eq 'INACTIVE' or
|
|
upperValue eq 'INACTIF' or upperValue eq 'URGENT' or upperValue eq 'CRITIQUE'}">
|
|
<c:set var="badgeSeverity" value="danger"/>
|
|
</c:when>
|
|
|
|
<!-- Par défaut - Info (bleu) -->
|
|
<c:otherwise>
|
|
<c:set var="badgeSeverity" value="info"/>
|
|
</c:otherwise>
|
|
</c:choose>
|
|
|
|
<!-- Déterminer l'icône automatiquement -->
|
|
<c:choose>
|
|
<c:when test="#{not empty icon}">
|
|
<c:set var="badgeIcon" value="#{icon}"/>
|
|
</c:when>
|
|
<c:when test="#{badgeSeverity eq 'success'}">
|
|
<c:set var="badgeIcon" value="pi pi-check-circle"/>
|
|
</c:when>
|
|
<c:when test="#{badgeSeverity eq 'info'}">
|
|
<c:set var="badgeIcon" value="pi pi-info-circle"/>
|
|
</c:when>
|
|
<c:when test="#{badgeSeverity eq 'warning'}">
|
|
<c:set var="badgeIcon" value="pi pi-exclamation-triangle"/>
|
|
</c:when>
|
|
<c:when test="#{badgeSeverity eq 'danger'}">
|
|
<c:set var="badgeIcon" value="pi pi-times-circle"/>
|
|
</c:when>
|
|
</c:choose>
|
|
|
|
<!-- Rendu du badge -->
|
|
<p:badge value="#{value}"
|
|
severity="#{badgeSeverity}"
|
|
styleClass="#{rounded eq false ? '' : 'border-round'}
|
|
#{size eq 'large' ? 'text-lg px-3 py-2' : 'px-2'}"
|
|
style="display: inline-flex; align-items: center; gap: 0.5rem;">
|
|
<i class="#{badgeIcon}" style="font-size: 0.875rem;"/>
|
|
<span style="font-weight: 600; text-transform: capitalize;">
|
|
#{value.toString().toLowerCase().replace('_', ' ')}
|
|
</span>
|
|
</p:badge>
|
|
|
|
</ui:composition>
|