33 lines
1.2 KiB
TypeScript
33 lines
1.2 KiB
TypeScript
import { useEffect, useState } from 'react';
|
||
import PageHeader from '../../components/PageHeader';
|
||
import SlaHeatmap from '../../components/charts/SlaHeatmap';
|
||
import { getSla } from '../../services/analytics.service';
|
||
import type { SlaMetric } from '../../types/analytics.types';
|
||
import styles from './SlaKpi.module.scss';
|
||
|
||
export default function SlaKpi({ refreshKey }: { refreshKey: number }) {
|
||
const [metrics, setMetrics] = useState<SlaMetric[] | null>(null);
|
||
const [error, setError] = useState(false);
|
||
|
||
useEffect(() => {
|
||
let alive = true;
|
||
setError(false);
|
||
getSla()
|
||
.then(r => { if (alive) setMetrics(r.metrics); })
|
||
.catch(() => { if (alive) setError(true); });
|
||
return () => { alive = false; };
|
||
}, [refreshKey]);
|
||
|
||
if (error) return <div className={styles.stateError}>Failed to load SLA metrics.</div>;
|
||
if (!metrics) return <div className={styles.state}>Loading SLA metrics…</div>;
|
||
|
||
return (
|
||
<div className={styles.page}>
|
||
<PageHeader title="PM KPIs — SLA" subtitle="Per-PM × ticket-size averages vs configured norms (green = on target, red = over)" />
|
||
<div className={styles.grid}>
|
||
{metrics.map(m => <SlaHeatmap key={m.key} metric={m} />)}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|