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:
@@ -181,5 +181,93 @@ public interface BtpXpressApiClient {
|
||||
@GET
|
||||
@Path("/factures")
|
||||
Response getFactures();
|
||||
|
||||
// === ENDPOINTS EMPLOYÉS ===
|
||||
|
||||
/**
|
||||
* Récupère la liste des employés.
|
||||
* Correspond à {@code EmployeResource.getAllEmployes()} dans le serveur.
|
||||
*
|
||||
* @return Réponse HTTP contenant la liste des employés.
|
||||
*/
|
||||
@GET
|
||||
@Path("/employes")
|
||||
Response getEmployes();
|
||||
|
||||
/**
|
||||
* Récupère un employé par son identifiant.
|
||||
*
|
||||
* @param id L'identifiant de l'employé.
|
||||
* @return Réponse HTTP contenant l'employé.
|
||||
*/
|
||||
@GET
|
||||
@Path("/employes/{id}")
|
||||
Response getEmploye(@PathParam("id") String id);
|
||||
|
||||
// === ENDPOINTS ÉQUIPES ===
|
||||
|
||||
/**
|
||||
* Récupère la liste des équipes.
|
||||
* Correspond à {@code EquipeResource.getAllEquipes()} dans le serveur.
|
||||
*
|
||||
* @return Réponse HTTP contenant la liste des équipes.
|
||||
*/
|
||||
@GET
|
||||
@Path("/equipes")
|
||||
Response getEquipes();
|
||||
|
||||
/**
|
||||
* Récupère une équipe par son identifiant.
|
||||
*
|
||||
* @param id L'identifiant de l'équipe.
|
||||
* @return Réponse HTTP contenant l'équipe.
|
||||
*/
|
||||
@GET
|
||||
@Path("/equipes/{id}")
|
||||
Response getEquipe(@PathParam("id") String id);
|
||||
|
||||
// === ENDPOINTS MATÉRIELS ===
|
||||
|
||||
/**
|
||||
* Récupère la liste des matériels.
|
||||
* Correspond à {@code MaterielResource.getAllMateriels()} dans le serveur.
|
||||
*
|
||||
* @return Réponse HTTP contenant la liste des matériels.
|
||||
*/
|
||||
@GET
|
||||
@Path("/materiels")
|
||||
Response getMateriels();
|
||||
|
||||
/**
|
||||
* Récupère un matériel par son identifiant.
|
||||
*
|
||||
* @param id L'identifiant du matériel.
|
||||
* @return Réponse HTTP contenant le matériel.
|
||||
*/
|
||||
@GET
|
||||
@Path("/materiels/{id}")
|
||||
Response getMateriel(@PathParam("id") String id);
|
||||
|
||||
// === ENDPOINTS STOCKS ===
|
||||
|
||||
/**
|
||||
* Récupère la liste des stocks.
|
||||
* Correspond à {@code StockResource.getAllStocks()} dans le serveur.
|
||||
*
|
||||
* @return Réponse HTTP contenant la liste des stocks.
|
||||
*/
|
||||
@GET
|
||||
@Path("/stocks")
|
||||
Response getStocks();
|
||||
|
||||
/**
|
||||
* Récupère un stock par son identifiant.
|
||||
*
|
||||
* @param id L'identifiant du stock.
|
||||
* @return Réponse HTTP contenant le stock.
|
||||
*/
|
||||
@GET
|
||||
@Path("/stocks/{id}")
|
||||
Response getStock(@PathParam("id") String id);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,9 +42,8 @@ public class ChantierService {
|
||||
LOG.debug("Récupération de la liste des chantiers depuis l'API backend.");
|
||||
Response response = apiClient.getChantiers();
|
||||
if (response.getStatus() == Response.Status.OK.getStatusCode()) {
|
||||
Map<String, Object> data = response.readEntity(Map.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> chantiers = (List<Map<String, Object>>) data.get("chantiers");
|
||||
List<Map<String, Object>> chantiers = response.readEntity(List.class);
|
||||
LOG.debug("Chantiers récupérés avec succès : {} élément(s)", chantiers != null ? chantiers.size() : 0);
|
||||
return chantiers != null ? chantiers : new ArrayList<>();
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package dev.lions.btpxpress.view;
|
||||
|
||||
import dev.lions.btpxpress.service.ChantierService;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.faces.view.ViewScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -13,6 +15,7 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Named("chantiersView")
|
||||
@@ -20,9 +23,12 @@ import java.util.function.Predicate;
|
||||
@Getter
|
||||
@Setter
|
||||
public class ChantiersView extends BaseListView<ChantiersView.Chantier, Long> implements Serializable {
|
||||
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ChantiersView.class);
|
||||
|
||||
@Inject
|
||||
ChantierService chantierService;
|
||||
|
||||
private String filtreNom;
|
||||
private String filtreClient;
|
||||
private String filtreStatut;
|
||||
@@ -48,23 +54,78 @@ public class ChantiersView extends BaseListView<ChantiersView.Chantier, Long> im
|
||||
loading = true;
|
||||
try {
|
||||
items = new ArrayList<>();
|
||||
for (int i = 1; i <= 20; i++) {
|
||||
|
||||
// Récupération depuis l'API backend
|
||||
List<Map<String, Object>> chantiersData = chantierService.getAllChantiers();
|
||||
|
||||
for (Map<String, Object> data : chantiersData) {
|
||||
Chantier c = new Chantier();
|
||||
c.setId((long) i);
|
||||
c.setNom("Chantier " + i);
|
||||
c.setClient("Client " + (i % 5 + 1));
|
||||
c.setAdresse("123 Rue Exemple " + i + ", 75001 Paris");
|
||||
c.setDateDebut(LocalDate.now().minusDays(i * 10));
|
||||
c.setDateFinPrevue(LocalDate.now().plusDays((20 - i) * 10));
|
||||
c.setStatut(i % 3 == 0 ? "TERMINE" : (i % 3 == 1 ? "EN_COURS" : "PLANIFIE"));
|
||||
c.setAvancement(i * 5);
|
||||
c.setBudget(i * 15000.0);
|
||||
c.setCoutReel(i * 12000.0);
|
||||
|
||||
// Mapping des données de l'API vers l'objet Chantier
|
||||
c.setId(data.get("id") != null ? Long.valueOf(data.get("id").toString().hashCode()) : null);
|
||||
c.setNom((String) data.get("nom"));
|
||||
|
||||
// Le client peut être un objet ou une chaîne
|
||||
Object clientObj = data.get("client");
|
||||
if (clientObj instanceof Map) {
|
||||
Map<String, Object> clientData = (Map<String, Object>) clientObj;
|
||||
c.setClient((String) clientData.get("raisonSociale"));
|
||||
} else if (clientObj instanceof String) {
|
||||
c.setClient((String) clientObj);
|
||||
} else {
|
||||
c.setClient("N/A");
|
||||
}
|
||||
|
||||
c.setAdresse((String) data.get("adresse"));
|
||||
|
||||
// Conversion des dates
|
||||
if (data.get("dateDebut") != null) {
|
||||
c.setDateDebut(LocalDate.parse(data.get("dateDebut").toString()));
|
||||
}
|
||||
if (data.get("dateFinPrevue") != null) {
|
||||
c.setDateFinPrevue(LocalDate.parse(data.get("dateFinPrevue").toString()));
|
||||
}
|
||||
|
||||
c.setStatut((String) data.get("statut"));
|
||||
|
||||
// Avancement en pourcentage
|
||||
Object avancementObj = data.get("avancement");
|
||||
if (avancementObj != null) {
|
||||
c.setAvancement(avancementObj instanceof Integer ?
|
||||
(Integer) avancementObj :
|
||||
Integer.parseInt(avancementObj.toString()));
|
||||
} else {
|
||||
c.setAvancement(0);
|
||||
}
|
||||
|
||||
// Budget et coût réel
|
||||
Object montantObj = data.get("montant");
|
||||
if (montantObj != null) {
|
||||
c.setBudget(montantObj instanceof Number ?
|
||||
((Number) montantObj).doubleValue() :
|
||||
Double.parseDouble(montantObj.toString()));
|
||||
} else {
|
||||
c.setBudget(0.0);
|
||||
}
|
||||
|
||||
Object coutReelObj = data.get("coutReel");
|
||||
if (coutReelObj != null) {
|
||||
c.setCoutReel(coutReelObj instanceof Number ?
|
||||
((Number) coutReelObj).doubleValue() :
|
||||
Double.parseDouble(coutReelObj.toString()));
|
||||
} else {
|
||||
c.setCoutReel(0.0);
|
||||
}
|
||||
|
||||
items.add(c);
|
||||
}
|
||||
|
||||
LOG.info("Chantiers chargés depuis l'API : {} élément(s)", items.size());
|
||||
applyFilters(items, buildFilters());
|
||||
} catch (Exception e) {
|
||||
LOG.error("Erreur chargement chantiers", e);
|
||||
LOG.error("Erreur chargement chantiers depuis l'API", e);
|
||||
// En cas d'erreur, on garde une liste vide
|
||||
items = new ArrayList<>();
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package dev.lions.btpxpress.view;
|
||||
|
||||
import dev.lions.btpxpress.service.ClientService;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.faces.view.ViewScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -12,6 +14,7 @@ import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Named("clientsView")
|
||||
@@ -19,9 +22,12 @@ import java.util.function.Predicate;
|
||||
@Getter
|
||||
@Setter
|
||||
public class ClientsView extends BaseListView<ClientsView.Client, Long> implements Serializable {
|
||||
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ClientsView.class);
|
||||
|
||||
@Inject
|
||||
ClientService clientService;
|
||||
|
||||
private String filtreNom;
|
||||
private String filtreEmail;
|
||||
private String filtreVille;
|
||||
@@ -37,27 +43,63 @@ public class ClientsView extends BaseListView<ClientsView.Client, Long> implemen
|
||||
loading = true;
|
||||
try {
|
||||
items = new ArrayList<>();
|
||||
for (int i = 1; i <= 25; i++) {
|
||||
|
||||
// Récupération depuis l'API backend
|
||||
List<Map<String, Object>> clientsData = clientService.getAllClients();
|
||||
|
||||
for (Map<String, Object> data : clientsData) {
|
||||
Client c = new Client();
|
||||
c.setId((long) i);
|
||||
c.setRaisonSociale("Entreprise " + i);
|
||||
c.setNomContact("Contact " + i);
|
||||
c.setEmail("contact" + i + "@example.com");
|
||||
c.setTelephone("+33 1 " + String.format("%02d", i) + " " +
|
||||
String.format("%02d", i * 2) + " " +
|
||||
String.format("%02d", i * 3) + " " +
|
||||
String.format("%02d", i * 4));
|
||||
c.setAdresse(i + " Rue Client, " + (75000 + i) + " Paris");
|
||||
c.setVille("Paris");
|
||||
c.setCodePostal(String.valueOf(75000 + i));
|
||||
c.setNombreChantiers(i % 5 + 1);
|
||||
c.setChiffreAffairesTotal(i * 25000.0);
|
||||
c.setDateCreation(LocalDateTime.now().minusDays(i * 30));
|
||||
|
||||
// Mapping des données de l'API vers l'objet Client
|
||||
c.setId(data.get("id") != null ? Long.valueOf(data.get("id").toString().hashCode()) : null);
|
||||
|
||||
// Raison sociale : entreprise ou "Particulier" si vide
|
||||
String entreprise = (String) data.get("entreprise");
|
||||
c.setRaisonSociale(entreprise != null && !entreprise.trim().isEmpty() ?
|
||||
entreprise : "Particulier");
|
||||
|
||||
// Nom complet du contact : prénom + nom
|
||||
String prenom = (String) data.get("prenom");
|
||||
String nom = (String) data.get("nom");
|
||||
c.setNomContact((prenom != null ? prenom + " " : "") + (nom != null ? nom : ""));
|
||||
|
||||
c.setEmail((String) data.get("email"));
|
||||
c.setTelephone((String) data.get("telephone"));
|
||||
c.setAdresse((String) data.get("adresse"));
|
||||
c.setVille((String) data.get("ville"));
|
||||
c.setCodePostal((String) data.get("codePostal"));
|
||||
|
||||
// Nombre de chantiers (relation)
|
||||
Object chantiersObj = data.get("chantiers");
|
||||
if (chantiersObj instanceof List) {
|
||||
c.setNombreChantiers(((List<?>) chantiersObj).size());
|
||||
} else {
|
||||
c.setNombreChantiers(0);
|
||||
}
|
||||
|
||||
// Chiffre d'affaires total (à calculer ou récupérer)
|
||||
// Pour l'instant, on met 0 car cette donnée n'est pas dans l'API
|
||||
c.setChiffreAffairesTotal(0.0);
|
||||
|
||||
// Date de création
|
||||
if (data.get("dateCreation") != null) {
|
||||
c.setDateCreation(LocalDateTime.parse(data.get("dateCreation").toString()));
|
||||
}
|
||||
|
||||
// Date de modification
|
||||
if (data.get("dateModification") != null) {
|
||||
c.setDateModification(LocalDateTime.parse(data.get("dateModification").toString()));
|
||||
}
|
||||
|
||||
items.add(c);
|
||||
}
|
||||
|
||||
LOG.info("Clients chargés depuis l'API : {} élément(s)", items.size());
|
||||
applyFilters(items, buildFilters());
|
||||
} catch (Exception e) {
|
||||
LOG.error("Erreur chargement clients", e);
|
||||
LOG.error("Erreur chargement clients depuis l'API", e);
|
||||
// En cas d'erreur, on garde une liste vide
|
||||
items = new ArrayList<>();
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -64,6 +64,10 @@ public class GuestPreferences implements Serializable {
|
||||
return this.inputStyle.equals("filled") ? "ui-input-filled" : "";
|
||||
}
|
||||
|
||||
public void setComponentTheme(String componentTheme) {
|
||||
this.componentTheme = componentTheme;
|
||||
}
|
||||
|
||||
public void onMenuTypeChange() {
|
||||
if ("layout-horizontal".equals(menuMode)) {
|
||||
menuTheme = topbarTheme;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<p:dataTable id="#{tableId}"
|
||||
value="#{viewBean.items}"
|
||||
var="#{var}"
|
||||
rowKey="id"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
rowsPerPageTemplate="10,20,50"
|
||||
|
||||
@@ -17,31 +17,62 @@
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<h6>Chantiers suspendus</h6>
|
||||
<p class="subtitle">Chantiers temporairement suspendus</p>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-between mb-3">
|
||||
<h1>Chantiers suspendus</h1>
|
||||
<p:commandButton value="Nouveau chantier" icon="pi pi-plus"
|
||||
action="#{chantiersView.createNew()}"
|
||||
styleClass="ui-button-primary"/>
|
||||
</div>
|
||||
<p:dataTable value="#{chantiersView.filteredItems}" var="chantier"
|
||||
emptyMessage="Aucun chantier suspendu"
|
||||
styleClass="p-datatable-sm">
|
||||
</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="#{chantiersView}"/>
|
||||
<ui:param name="tableId" value="chantiersTable"/>
|
||||
<ui:define name="filter-fields">
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<h:outputLabel for="filtreNom" value="Nom du chantier"/>
|
||||
<p:inputText id="filtreNom" value="#{chantiersView.filtreNom}"
|
||||
placeholder="Rechercher par nom..." style="width: 100%;"/>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<h:outputLabel for="filtreClient" value="Client"/>
|
||||
<p:inputText id="filtreClient" value="#{chantiersView.filtreClient}"
|
||||
placeholder="Rechercher par client..." style="width: 100%;"/>
|
||||
</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="chantiersForm"/>
|
||||
<ui:param name="tableId" value="chantiersTable"/>
|
||||
<ui:param name="viewBean" value="#{chantiersView}"/>
|
||||
<ui:param name="var" value="chantier"/>
|
||||
<ui:param name="title" value="Liste des chantiers suspendus"/>
|
||||
<ui:param name="createPath" value="/chantiers/nouveau"/>
|
||||
<ui:define name="columns">
|
||||
<p:column headerText="Nom" sortBy="#{chantier.nom}">
|
||||
<h:outputText value="#{chantier.nom}"/>
|
||||
</p:column>
|
||||
<p:column headerText="Client" sortBy="#{chantier.client}">
|
||||
<h:outputText value="#{chantier.client}"/>
|
||||
</p:column>
|
||||
<p:column headerText="Date début">
|
||||
<p:column headerText="Adresse">
|
||||
<h:outputText value="#{chantier.adresse}"/>
|
||||
</p:column>
|
||||
<p:column headerText="Date début" sortBy="#{chantier.dateDebut}">
|
||||
<h:outputText value="#{chantier.dateDebut}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy"/>
|
||||
</h:outputText>
|
||||
</p:column>
|
||||
<p:column headerText="Avancement">
|
||||
<p:progressBar value="#{chantier.avancement}"
|
||||
<p:progressBar value="#{chantier.avancement}"
|
||||
showValue="true"
|
||||
styleClass="ui-progressbar-warn"/>
|
||||
</p:column>
|
||||
@@ -51,13 +82,13 @@
|
||||
</h:outputText>
|
||||
<h:outputText value=" Fcfa"/>
|
||||
</p:column>
|
||||
<p:column headerText="Actions">
|
||||
<p:column headerText="Actions" style="width: 150px;">
|
||||
<p:commandButton icon="pi pi-eye" title="Voir les détails"
|
||||
styleClass="ui-button-text"
|
||||
action="#{chantiersView.viewDetails(chantier.id)}"/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
<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>
|
||||
|
||||
<!-- Configuration PrimeFaces -->
|
||||
<context-param>
|
||||
@@ -60,6 +64,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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user