Files

40 lines
2.6 KiB
TypeScript

"use client"
import { Alert, AlertDescription, AlertTitle } from "@/components/reui/alert"
import { Button } from "@/components/ui/button"
import { DASHBOARD_SOURCES, type DashboardSource, type DashboardSources } from "@/lib/dashboard-source-state"
export function DashboardDataStatus({ sources, refreshing, onRefresh }: {
sources: DashboardSources
refreshing: boolean
onRefresh: () => void
}) {
const failed = Object.values(sources).filter(source => source.error)
const summary = failed.length ? `Не обновлены источники: ${failed.length}` : "Состояние источников"
return <div className="flex flex-col gap-2">
{failed.length > 0 && <Alert variant="destructive">
<AlertTitle>{summary}</AlertTitle>
<AlertDescription>Последние полученные данные сохранены. Если источник ещё не загрузился, его показатели неизвестны.</AlertDescription>
</Alert>}
<div className="flex flex-wrap items-start justify-between gap-2">
<details className="min-w-0 text-sm" open={failed.length > 0 || undefined}>
<summary className="cursor-pointer">Источники и время получения</summary>
<ul className="mt-2 flex flex-col gap-1 text-xs">
{(Object.keys(DASHBOARD_SOURCES) as DashboardSource[]).map(key => {
const source = sources[key]
return <li key={key} data-source={key} className={`break-words ${source?.error ? "text-destructive" : "text-muted-foreground"}`}>
{DASHBOARD_SOURCES[key]}: {source?.error ? `ошибка обновления — ${source.error}. ` : ""}
{source?.receivedAt != null ? <>Получено <time dateTime={new Date(source.receivedAt).toISOString()}>{new Date(source.receivedAt).toLocaleString("ru-RU")}</time>{source.error ? " · данные могут быть устаревшими" : ""}</> : "Успешных загрузок ещё нет"}
{source?.sampledAt && Number.isFinite(Date.parse(source.sampledAt)) && <> · замер <time dateTime={source.sampledAt}>{new Date(source.sampledAt).toLocaleString("ru-RU")}</time></>}
</li>
})}
</ul>
</details>
<div className="flex items-center gap-2">
<span role="status" className="text-xs text-muted-foreground">{refreshing ? "Обновление данных…" : "Обновление завершено"}</span>
<Button type="button" size="sm" variant="outline" onClick={onRefresh} disabled={refreshing}>Обновить данные</Button>
</div>
</div>
</div>
}