'use client'; import React, { useState, useEffect, useRef } from 'react'; import { Card } from 'primereact/card'; import { Chart } from 'primereact/chart'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { Button } from 'primereact/button'; import { Tag } from 'primereact/tag'; import { Divider } from 'primereact/divider'; import { Toast } from 'primereact/toast'; import { ProgressBar } from 'primereact/progressbar'; import { materielService, maintenanceService } from '../../../../services/api'; import { Materiel, MaintenanceMateriel, TypeMateriel, StatutMateriel } from '../../../../types/btp'; import { formatCurrency } from '../../../../utils/formatters'; const MaterielsStatsPage = () => { const [materiels, setMateriels] = useState([]); const [maintenances, setMaintenances] = useState([]); const [stats, setStats] = useState(null); const [valeurTotale, setValeurTotale] = useState(0); const [loading, setLoading] = useState(true); const toast = useRef(null); // Options des graphiques const chartOptions = { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom' } } }; useEffect(() => { loadData(); }, []); const loadData = async () => { try { setLoading(true); const [materielsData, maintenancesData, statsData, valeurData] = await Promise.all([ materielService.getAll(), maintenanceService.getAll(), materielService.getStats(), materielService.getValeurTotale() ]); setMateriels(materielsData); setMaintenances(maintenancesData); setStats(statsData); setValeurTotale(valeurData); } catch (error) { console.error('Erreur lors du chargement:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de charger les statistiques', life: 3000 }); } finally { setLoading(false); } }; // Calculs des statistiques const getStatutStats = () => { const statutCounts = materiels.reduce((acc, materiel) => { acc[materiel.statut] = (acc[materiel.statut] || 0) + 1; return acc; }, {} as Record); return { labels: Object.keys(statutCounts).map(s => s.replace('_', ' ')), datasets: [{ label: 'Matériels par statut', data: Object.values(statutCounts), backgroundColor: [ '#4CAF50', // DISPONIBLE '#FF9800', // EN_UTILISATION '#2196F3', // EN_MAINTENANCE '#f44336' // HORS_SERVICE ] }] }; }; const getTypeStats = () => { const typeCounts = materiels.reduce((acc, materiel) => { acc[materiel.type] = (acc[materiel.type] || 0) + 1; return acc; }, {} as Record); return { labels: Object.keys(typeCounts).map(t => t.replace('_', ' ')), datasets: [{ label: 'Matériels par type', data: Object.values(typeCounts), backgroundColor: [ '#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#FF9F40' ] }] }; }; const getValeurStats = () => { const valeurParType = materiels.reduce((acc, materiel) => { const valeur = materiel.valeurActuelle || materiel.valeurAchat || 0; acc[materiel.type] = (acc[materiel.type] || 0) + valeur; return acc; }, {} as Record); return { labels: Object.keys(valeurParType).map(t => t.replace('_', ' ')), datasets: [{ label: 'Valeur par type (€)', data: Object.values(valeurParType), backgroundColor: '#42A5F5', borderColor: '#1976D2', borderWidth: 1 }] }; }; const getMaintenanceStats = () => { const monthlyMaintenance = new Array(12).fill(0); const currentYear = new Date().getFullYear(); maintenances.forEach(maintenance => { const date = new Date(maintenance.dateRealisation || maintenance.datePrevue); if (date.getFullYear() === currentYear) { monthlyMaintenance[date.getMonth()]++; } }); return { labels: [ 'Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun', 'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc' ], datasets: [{ label: 'Maintenances par mois', data: monthlyMaintenance, backgroundColor: 'rgba(255, 193, 7, 0.2)', borderColor: '#FFC107', borderWidth: 2, fill: true }] }; }; // Template pour les matériels les plus coûteux const valeurBodyTemplate = (rowData: Materiel) => { return formatCurrency(rowData.valeurActuelle || rowData.valeurAchat); }; const typeBodyTemplate = (rowData: Materiel) => { return ( ); }; const getTypeSeverity = (type?: TypeMateriel) => { switch (type) { case TypeMateriel.ENGIN_CHANTIER: return 'danger'; case TypeMateriel.OUTILLAGE: return 'warning'; case TypeMateriel.EQUIPEMENT_SECURITE: return 'success'; case TypeMateriel.VEHICULE: return 'info'; default: return undefined; } }; // Matériels triés par valeur décroissante const materielsCouteux = [...materiels] .sort((a, b) => (b.valeurActuelle || b.valeurAchat || 0) - (a.valeurActuelle || a.valeurAchat || 0)) .slice(0, 5); // Calcul des KPI const tauxDisponibilite = materiels.length > 0 ? (materiels.filter(m => m.statut === StatutMateriel.DISPONIBLE).length / materiels.length) * 100 : 0; const tauxMaintenance = materiels.length > 0 ? (materiels.filter(m => m.statut === StatutMateriel.EN_MAINTENANCE).length / materiels.length) * 100 : 0; const tauxUtilisation = materiels.length > 0 ? (materiels.filter(m => m.statut === StatutMateriel.EN_UTILISATION).length / materiels.length) * 100 : 0; return (

Statistiques du Parc Matériel

{/* KPI Cards */}
{materiels.length}
Total matériels
{formatCurrency(valeurTotale)}
Valeur totale
{tauxDisponibilite.toFixed(1)}%
Disponibilité
{maintenances.length}
Maintenances
{/* Indicateurs de performance */}
{tauxDisponibilite.toFixed(0)}%
{materiels.filter(m => m.statut === StatutMateriel.DISPONIBLE).length} / {materiels.length} disponibles
{tauxUtilisation.toFixed(0)}%
{materiels.filter(m => m.statut === StatutMateriel.EN_UTILISATION).length} / {materiels.length} en utilisation
{tauxMaintenance.toFixed(0)}%
{materiels.filter(m => m.statut === StatutMateriel.EN_MAINTENANCE).length} / {materiels.length} en maintenance
{/* Graphiques */}
{/* Top matériels les plus coûteux */}
); }; export default MaterielsStatsPage;