init projet

This commit is contained in:
2026-05-20 10:43:18 +02:00
parent 51f27903bb
commit 9a402b0b34
57 changed files with 5622 additions and 0 deletions
@@ -0,0 +1,110 @@
// src/pages/VueConso/VueConso.jsx
// Page Vue consolidée : graphique barres + tableau avec export CSV
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { Download } from 'lucide-react';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import { getDashboard, exportToCSV } from '../../services/api';
import DataTable from '../../components/common/DataTable';
import LoadingSpinner from '../../components/common/LoadingSpinner';
import ErrorMessage from '../../components/common/ErrorMessage';
import Button from '../../components/common/Button';
import styles from './VueConso.module.css';
/* Détermine la couleur selon le statut */
function getStatusColor(nbErreurs) {
if (nbErreurs === 0) return 'var(--color-ok)';
if (nbErreurs < 10) return 'var(--color-warning)';
return 'var(--color-primary)';
}
export default function VueConso() {
const navigate = useNavigate();
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [erreur, setErreur] = useState('');
useEffect(() => {
async function loadData() {
setLoading(true);
setErreur('');
try {
const result = await getDashboard();
setData(Array.isArray(result) ? result : []);
} catch (e) {
setErreur(e.message || 'Erreur lors du chargement de la vue consolidée.');
} finally {
setLoading(false);
}
}
loadData();
}, []);
if (loading) return <LoadingSpinner message="Chargement de la vue consolidée..." />;
if (erreur) return <ErrorMessage message={erreur} />;
/* Préparation des données pour le graphique */
const chartData = data.map(item => ({
name: item.nom || item.nom_monito || item.libelle || 'Monitoring',
erreurs: item.nb_erreurs ?? item.count ?? 0,
fill: getStatusColor(item.nb_erreurs ?? item.count ?? 0)
}));
/* Colonnes du tableau */
const columns = [
{ key: 'nom', label: 'Monitoring' },
{ key: 'service', label: 'Service' },
{ key: 'categorie', label: 'Catégorie' },
{ key: 'bdd_source', label: 'Source' },
{ key: 'nb_erreurs', label: 'Erreurs', render: (val) => val ?? 0 },
{
key: 'actions',
label: 'Actions',
render: (val, row) => (
<Button variant="link" onClick={() => navigate(`/monitoring/${row.id || row.id_monito}`)}>
Voir détail
</Button>
)
}
];
return (
<div className={styles.page}>
<div className={styles.header}>
<h1 className={styles.title}>Vue consolidée</h1>
<Button variant="secondary" onClick={() => exportToCSV(data, `vue_consolidee_${new Date().toISOString().split('T')[0]}.csv`)}>
<Download size={14} />
Exporter tout ({data.length} lignes)
</Button>
</div>
{/* Graphique */}
<div className={styles.chartContainer}>
<ResponsiveContainer width="100%" height={400}>
<BarChart data={chartData} margin={{ top: 20, right: 30, left: 20, bottom: 60 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" angle={-45} textAnchor="end" height={80} />
<YAxis />
<Tooltip
contentStyle={{
backgroundColor: 'var(--color-black)',
color: 'var(--color-white)',
border: 'none',
borderRadius: 'var(--radius)'
}}
/>
<Bar dataKey="erreurs" fill="var(--color-primary)" />
</BarChart>
</ResponsiveContainer>
</div>
{/* Tableau */}
<DataTable
columns={columns}
data={data}
pageSize={50}
emptyMessage="Aucune donnée disponible."
/>
</div>
);
}