'use client'; export const dynamic = 'force-dynamic'; import React, { useState, useRef, useEffect } from 'react'; import { Card } from 'primereact/card'; import { Button } from 'primereact/button'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { InputText } from 'primereact/inputtext'; import { Dropdown } from 'primereact/dropdown'; import { Chart } from 'primereact/chart'; import { Tag } from 'primereact/tag'; import { Toast } from 'primereact/toast'; import { TabView, TabPanel } from 'primereact/tabview'; import { Badge } from 'primereact/badge'; import { Divider } from 'primereact/divider'; import { ProgressBar } from 'primereact/progressbar'; import { Chip } from 'primereact/chip'; interface PrixElement { id: string; designation: string; categorie: string; typeElement: string; prixUnitaire: number; unite: string; region: string; variationMensuelle: number; variationAnnuelle: number; tendance: string; fiabilite: string; dateMiseAJour: string; nombreSources: number; } interface AnalyseTendance { id: string; titre: string; resume: string; typeAnalyse: string; variationMoyenne: number; nombreElementsAnalyses: number; tendancePrevue: string; datePublication: string; situationExceptionnelle: boolean; niveauAlerte: string; } const ObservatoirePrix = () => { const [activeIndex, setActiveIndex] = useState(0); const [prix, setPrix] = useState([]); const [analyses, setAnalyses] = useState([]); const [loading, setLoading] = useState(false); const [globalFilter, setGlobalFilter] = useState(''); const [selectedRegion, setSelectedRegion] = useState(''); const [selectedCategorie, setSelectedCategorie] = useState(''); const toast = useRef(null); const regions = [ { label: 'Toutes les régions', value: '' }, { label: 'Île-de-France', value: 'IDF' }, { label: 'Auvergne-Rhône-Alpes', value: 'ARA' }, { label: 'Nouvelle-Aquitaine', value: 'NA' }, { label: 'Occitanie', value: 'OCC' }, { label: 'PACA', value: 'PACA' } ]; const categories = [ { label: 'Toutes catégories', value: '' }, { label: 'Matériaux gros œuvre', value: 'MATERIAUX_GROS_OEUVRE' }, { label: 'Matériaux second œuvre', value: 'MATERIAUX_SECOND_OEUVRE' }, { label: 'Main d\'œuvre', value: 'MAIN_OEUVRE' }, { label: 'Location matériel', value: 'LOCATION_MATERIEL' } ]; useEffect(() => { loadData(); }, []); const loadData = async () => { setLoading(true); try { // TODO: Remplacer par des appels API réels quand les endpoints seront disponibles // const prixData = await observatoireService.getPrix(); // const analysesData = await observatoireService.getAnalyses(); // Pour l'instant, afficher des listes vides plutôt que des données fictives const prixData: PrixElement[] = []; const analysesData: AnalyseTendance[] = []; setPrix(prixData); setAnalyses(analysesData); } catch (error) { toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de charger les données', life: 3000 }); } finally { setLoading(false); } }; const getTendanceSeverity = (tendance: string) => { switch (tendance) { case 'FORTE_HAUSSE': return 'danger'; case 'HAUSSE': return 'warning'; case 'STABLE': return 'success'; case 'BAISSE': return 'info'; case 'FORTE_BAISSE': return 'danger'; default: return 'secondary'; } }; const getTendanceIcon = (tendance: string) => { switch (tendance) { case 'FORTE_HAUSSE': return 'pi-angle-double-up'; case 'HAUSSE': return 'pi-angle-up'; case 'STABLE': return 'pi-minus'; case 'BAISSE': return 'pi-angle-down'; case 'FORTE_BAISSE': return 'pi-angle-double-down'; default: return 'pi-question'; } }; const getFiabiliteSeverity = (fiabilite: string) => { switch (fiabilite) { case 'EXCELLENTE': return 'success'; case 'BONNE': return 'info'; case 'MOYENNE': return 'warning'; default: return 'danger'; } }; const getAlerteSeverity = (niveau: string) => { switch (niveau) { case 'CRITIQUE': return 'danger'; case 'ELEVEE': return 'warning'; case 'MODEREE': return 'info'; default: return 'success'; } }; const formatPrix = (value: number) => { return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', minimumFractionDigits: 2 }).format(value); }; const formatVariation = (value: number) => { return `${value > 0 ? '+' : ''}${value}%`; }; // Templates pour DataTable const prixTemplate = (rowData: PrixElement) => { return {formatPrix(rowData.prixUnitaire)}; }; const variationTemplate = (rowData: PrixElement, field: string) => { const value = rowData[field as keyof PrixElement] as number; const isPositive = value > 0; return ( {formatVariation(value)} ); }; const tendanceTemplate = (rowData: PrixElement) => { return ( ); }; const fiabiliteTemplate = (rowData: PrixElement) => { return ( ); }; // Configuration du graphique des tendances // Données du graphique basées sur les vraies données de l'API const chartData = { labels: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin'], datasets: [ { label: 'Matériaux', data: new Array(6).fill(0), // Vide jusqu'à ce que l'API fournisse les données borderColor: '#42A5F5', backgroundColor: 'rgba(66, 165, 245, 0.1)', tension: 0.4 }, { label: 'Main d\'œuvre', data: new Array(6).fill(0), // Vide jusqu'à ce que l'API fournisse les données borderColor: '#FFA726', backgroundColor: 'rgba(255, 167, 38, 0.1)', tension: 0.4 } ] }; const chartOptions = { maintainAspectRatio: false, aspectRatio: 0.6, plugins: { legend: { labels: { color: '#495057' } } }, scales: { x: { ticks: { color: '#495057' }, grid: { color: '#ebedef' } }, y: { ticks: { color: '#495057' }, grid: { color: '#ebedef' } } } }; const filteredPrix = prix.filter(item => { return ( (!globalFilter || item.designation.toLowerCase().includes(globalFilter.toLowerCase())) && (!selectedRegion || item.region === selectedRegion) && (!selectedCategorie || item.categorie === selectedCategorie) ); }); return (

Observatoire des Prix BTP

Suivez l'évolution des prix des matériaux, main d'œuvre et services BTP en temps réel

setActiveIndex(e.index)}> {/* Dashboard principal */}
{/* Indicateurs clés */}
Variation mensuelle moyenne
+4.2%
Alertes actives
3
Éléments surveillés
1,247
Dernière mise à jour
Aujourd'hui
{/* Graphique des tendances */}
{/* Alertes récentes */}
Béton C25/30
+12.3% en 3 semaines
Acier d'armature
+8.7% ce mois
Main d'œuvre IDF
+5.2% ce trimestre
{/* Prix en temps réel */}
setGlobalFilter(e.target.value)} className="w-full" />
setSelectedRegion(e.value)} placeholder="Sélectionner une région" className="w-full" />
setSelectedCategorie(e.value)} placeholder="Sélectionner une catégorie" className="w-full" />
variationTemplate(data, 'variationMensuelle')} sortable /> variationTemplate(data, 'variationAnnuelle')} sortable />
{/* Analyses et rapports */}
{analyses.map(analyse => (

{analyse.titre}

{analyse.situationExceptionnelle && ( )}

{analyse.resume}

Publié le {new Date(analyse.datePublication).toLocaleDateString('fr-FR')}
))}
{/* Alertes et notifications */}

Configurez vos alertes pour être notifié des variations importantes de prix.

Fonctionnalité en cours de développement

); }; export default ObservatoirePrix;