init projet
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
/* Page principale du dashboard : KPI cards + grille de monitorings */
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { RefreshCw } from 'lucide-react';
|
||||
import { getDashboard, getDashboardSummary, getServices, getCategories } from '../../services/api';
|
||||
import MonitoringCard from '../../components/common/MonitoringCard';
|
||||
import LoadingSpinner from '../../components/common/LoadingSpinner';
|
||||
import ErrorMessage from '../../components/common/ErrorMessage';
|
||||
import styles from './Dashboard.module.css';
|
||||
|
||||
/* Carte KPI affichant un indicateur clé */
|
||||
function KpiCard({ label, value, color }) {
|
||||
return (
|
||||
<div className={styles.kpiCard}>
|
||||
<span className={styles.kpiValue} style={{ color }}>{value}</span>
|
||||
<span className={styles.kpiLabel}>{label}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Dashboard() {
|
||||
const [summary, setSummary] = useState(null);
|
||||
const [monitorings, setMonitorings] = useState([]);
|
||||
const [services, setServices] = useState([]);
|
||||
const [categories, setCategories] = useState([]);
|
||||
const [filtreService, setFiltreService] = useState('');
|
||||
const [filtreCategorie, setFiltreCategorie] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [erreur, setErreur] = useState('');
|
||||
|
||||
/* Chargement initial des filtres */
|
||||
useEffect(() => {
|
||||
async function loadFiltres() {
|
||||
try {
|
||||
const [svcs, cats] = await Promise.all([getServices(), getCategories()]);
|
||||
setServices(svcs);
|
||||
setCategories(cats);
|
||||
} catch {
|
||||
/* Non bloquant, les filtres restent vides */
|
||||
}
|
||||
}
|
||||
loadFiltres();
|
||||
}, []);
|
||||
|
||||
/* Chargement des données dashboard */
|
||||
const loadData = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setErreur('');
|
||||
try {
|
||||
const [sum, data] = await Promise.all([
|
||||
getDashboardSummary(),
|
||||
getDashboard(filtreService, filtreCategorie),
|
||||
]);
|
||||
setSummary(sum);
|
||||
setMonitorings(Array.isArray(data) ? data : []);
|
||||
} catch (e) {
|
||||
setErreur(e.message || 'Erreur lors du chargement du dashboard.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [filtreService, filtreCategorie]);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, [loadData]);
|
||||
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<div className={styles.pageHeader}>
|
||||
<h1 className={styles.title}>Dashboard</h1>
|
||||
<button className={styles.refreshBtn} onClick={loadData} disabled={loading}>
|
||||
<RefreshCw size={14} className={loading ? styles.spinning : ''} />
|
||||
Actualiser
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* KPI Cards */}
|
||||
{summary && (
|
||||
<div className={styles.kpiGrid}>
|
||||
<KpiCard
|
||||
label="Total monitorings"
|
||||
value={summary.total ?? 0}
|
||||
color="var(--color-text)"
|
||||
/>
|
||||
<KpiCard
|
||||
label="Sans erreur"
|
||||
value={summary.ok ?? 0}
|
||||
color="var(--color-ok)"
|
||||
/>
|
||||
<KpiCard
|
||||
label="En erreur"
|
||||
value={summary.critical ?? 0}
|
||||
color="var(--color-primary)"
|
||||
/>
|
||||
<KpiCard
|
||||
label="Total erreurs"
|
||||
value={summary.total_erreurs ?? 0}
|
||||
color="var(--color-warning)"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Filtres */}
|
||||
<div className={styles.filtres}>
|
||||
<select
|
||||
className={styles.select}
|
||||
value={filtreService}
|
||||
onChange={e => setFiltreService(e.target.value)}
|
||||
>
|
||||
<option value="">Tous les services</option>
|
||||
{services.map(s => (
|
||||
<option key={s.id_service} value={s.nom_service}>{s.nom_service}</option>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
className={styles.select}
|
||||
value={filtreCategorie}
|
||||
onChange={e => setFiltreCategorie(e.target.value)}
|
||||
>
|
||||
<option value="">Toutes les catégories</option>
|
||||
{categories.map(c => (
|
||||
<option key={c.id_categorie} value={c.intitule_categorie}>{c.intitule_categorie}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Contenu principal */}
|
||||
{loading ? (
|
||||
<LoadingSpinner message="Chargement du dashboard..." />
|
||||
) : erreur ? (
|
||||
<ErrorMessage message={erreur} onRetry={loadData} />
|
||||
) : (
|
||||
<>
|
||||
{monitorings.length === 0 ? (
|
||||
<p className={styles.empty}>Aucun monitoring trouvé pour ces filtres.</p>
|
||||
) : (
|
||||
<div className={styles.grid}>
|
||||
{monitorings.map(m => (
|
||||
<MonitoringCard key={m.id} monitoring={m} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user