{error && (
Помилка завантаження.
)}
{loading && !data ? (
⟳
Завантаження…
) : (
<>
{/* KPI row (live) */}
{[
{ label: "Доступність мережі", value: kpi.availability_pct != null ? `${kpi.availability_pct}%` : "—",
color: kpi.availability_pct >= 95 ? "var(--ok)" : kpi.availability_pct >= 85 ? "var(--warn)" : "var(--bad)" },
{ label: "ТЗ онлайн", value: kpi.vehicles_total ? `${kpi.vehicles_online}/${kpi.vehicles_total}` : "—",
color: "var(--text-1)" },
{ label: "Алертів у мережі", value: kpi.alerts_total ?? "—",
color: (kpi.alerts_total || 0) > 0 ? "var(--bad)" : "var(--ok)" },
{ label: "Інциденти (відкр.)", value: kpi.incidents_open ?? "—",
color: (kpi.incidents_open || 0) > 0 ? "var(--warn)" : "var(--ok)" },
].map((k, i) => (
))}
{/* Tabs */}
{[["overview","Огляд"],["activity","Активність"],["incidents","Інциденти"]].map(([id, label]) => (
))}
{tab === "overview" && (
{/* Donut */}
Статус маршрутів
{donutSegments.map(s => (
))}
{/* SLA / breached */}
Інциденти за період
Відкритих
0 ? "var(--bad)" : "var(--ok)" }}>{kpi.incidents_open ?? 0}
Вирішені
{kpi.incidents_resolved ?? 0}
SLA breached
0 ? "var(--bad)" : "var(--text-1)" }}>{kpi.incidents_sla_breached ?? 0}
Алертів total
{kpi.alerts_total ?? 0}
{tsUnavailable && (
📊
Часові ряди — недоступні
Trend-графіки (доступність, рейси по днях) з'являться, коли буде підключений metrics-collector. Дані зараз — поточний snapshot.
)}
)}
{tab === "activity" && (
Активність за 7 днів (passenger_audit_log)
{Object.keys(activity).length === 0 ? (
—
Жодних подій за останні 7 днів
) : (
| Дія | Кількість |
{Object.entries(activity).sort((a, b) => b[1] - a[1]).map(([action, n]) => (
{ActionLabel(action)} {action} |
{n} |
))}
)}
)}
{tab === "incidents" && (
Останні інциденти (admin/fleet)
{incidents.length === 0 ? (
Немає інцидентів
) : (
| Узел | Код | Серйозність | Статус | Перший |
{incidents.map((inc, i) => (
| {inc.central_id || "—"} |
{inc.code} |
{inc.severity === "bad"
? ⚠ Критично
: inc.severity === "warn"
? ⚡ Уваги
: ✓ OK}
|
{inc.status === "active"
? ● Активний
: ✓ {inc.status || "—"}}
|
{inc.first_ts ? new Date(inc.first_ts).toLocaleString("uk-UA") : "—"}
|
))}
)}
)}
>
)}
>
);
}
Object.assign(window, { Analytics });