'use client'; export const dynamic = 'force-dynamic'; import React, { useState, useEffect, useRef } from 'react'; import { Card } from 'primereact/card'; import { Chart } from 'primereact/chart'; import { Badge } from 'primereact/badge'; import { Tag } from 'primereact/tag'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { Button } from 'primereact/button'; import { ProgressBar } from 'primereact/progressbar'; import { Knob } from 'primereact/knob'; import { Timeline } from 'primereact/timeline'; import { Divider } from 'primereact/divider'; import { Toast } from 'primereact/toast'; /** * Dashboard Temps Réel BTP Express * Surveillance en temps réel des chantiers, équipes et performances */ const DashboardTempsReel = () => { const [donneesTR, setDonneesTR] = useState({}); const [derniereMiseAJour, setDerniereMiseAJour] = useState(new Date()); const [alertesActives, setAlertesActives] = useState([]); const [evolutionCA, setEvolutionCA] = useState({}); const [interventionsUrgentes, setInterventionsUrgentes] = useState([]); const toast = useRef(null); useEffect(() => { // Simulation données temps réel chargerDonneesTempsReel(); // Mise à jour automatique toutes les 30 secondes const interval = setInterval(() => { chargerDonneesTempsReel(); }, 30000); return () => clearInterval(interval); }, []); const chargerDonneesTempsReel = () => { // TODO: Remplacer par des appels API réels pour les données temps réel // const donnees = await dashboardService.getDonneesTempsReel(); // Initialisation avec des données vides plutôt que des données fictives const donnees = { chantiersEnCours: { total: 0, nouveauxAujourdhui: 0, terminesAujourdhui: 0, enRetard: 0 }, equipes: { totalActives: 0, surSite: 0, disponibles: 0, enDeplacementProchain: 0 }, materiel: { enUtilisation: 0, disponible: 0, enMaintenance: 0, alertesStock: 0 }, financier: { caJournalier: 0, objectifJour: 0, margeJour: 0, facturations: 0 }, securite: { accidentsJour: 0, joursDepuisDernierAccident: 0, controlsSecurite: 0, epiOk: 0 } }; setDonneesTR(donnees); setDerniereMiseAJour(new Date()); // Alertes vides jusqu'à ce que l'API fournisse les vraies données setAlertesActives([]); // Graphique avec données vides setEvolutionCA({ labels: ['08h', '10h', '12h', '14h', '16h', '18h'], datasets: [ { label: 'CA Réalisé', data: new Array(6).fill(0), borderColor: '#4BC0C0', backgroundColor: 'rgba(75, 192, 192, 0.1)', tension: 0.4, fill: true }, { label: 'Objectif', data: new Array(6).fill(0), borderColor: '#FF6B6B', backgroundColor: 'rgba(255, 107, 107, 0.1)', borderDash: [5, 5], tension: 0.4, fill: false } ] }); // Interventions vides jusqu'à ce que l'API fournisse les vraies données setInterventionsUrgentes([]); }; const chartOptions = { responsive: true, plugins: { legend: { position: 'top' as const, }, title: { display: true, text: 'Évolution CA Journalier' } }, scales: { y: { beginAtZero: true, ticks: { callback: (value: any) => `${value}€` } } } }; const getAlerteSeverityConfig = (severity: string) => { switch (severity) { case 'high': return { color: 'danger', icon: 'pi-exclamation-triangle' }; case 'medium': return { color: 'warning', icon: 'pi-info-circle' }; case 'low': return { color: 'info', icon: 'pi-check-circle' }; default: return { color: 'secondary', icon: 'pi-info' }; } }; const getUrgenceConfig = (urgence: string) => { switch (urgence) { case 'CRITIQUE': return { color: 'danger', label: 'CRITIQUE' }; case 'HAUTE': return { color: 'warning', label: 'HAUTE' }; case 'MOYENNE': return { color: 'info', label: 'MOYENNE' }; default: return { color: 'secondary', label: urgence }; } }; const actualiserDonnees = () => { chargerDonneesTempsReel(); toast.current?.show({ severity: 'success', summary: 'Données actualisées', detail: 'Mise à jour terminée', life: 3000 }); }; return (
{/* En-tête avec actualisation */}

Dashboard Temps Réel BTP

Dernière MAJ: {derniereMiseAJour.toLocaleTimeString('fr-FR')}
{/* KPIs Temps Réel */}
{donneesTR.chantiersEnCours?.total || 0}
Chantiers actifs
{donneesTR.equipes?.surSite || 0}
Personnes sur site
{new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', notation: 'compact' }).format(donneesTR.financier?.caJournalier || 0)}
CA Journalier
EPI Conformes
{/* Graphique évolution CA */}
{/* Alertes en cours */}
{alertesActives.map((alerte) => { const config = getAlerteSeverityConfig(alerte.severity); return (
{alerte.message}
{alerte.heure.toLocaleTimeString('fr-FR')}
); })} {alertesActives.length === 0 && (
Aucune alerte active
)}
{/* Interventions urgentes */}
( )} /> { const config = getUrgenceConfig(rowData.urgence); return ; }} /> ( )} /> (
)} />
{/* Matériel et ressources */}
{donneesTR.materiel?.enUtilisation || 0}
En utilisation
{donneesTR.materiel?.disponible || 0}
Disponible
{donneesTR.materiel?.enMaintenance || 0}
En maintenance
{donneesTR.materiel?.alertesStock || 0}
Alertes stock
{/* Performances financières */}
Objectif journalier {((donneesTR.financier?.caJournalier || 0) / (donneesTR.financier?.objectifJour || 1) * 100).toFixed(1)}%
{donneesTR.financier?.margeJour || 0}%
Marge journalière
{donneesTR.financier?.facturations || 0}
Facturations
); }; export default DashboardTempsReel;