From 153be2879935e7aa4671f696a7d4b5b20e0670e9 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Thu, 20 Aug 2026 12:44:17 +0700 Subject: [PATCH] =?UTF-8?q?fix(health):=20=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7?= =?UTF-8?q?=D1=8B=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BF=D0=B8=D0=BD=D0=B3=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D0=BD=D0=B0=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=BD=D0=B0=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=20uptime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .../src/components/reui-kit/uptime-chart.tsx | 61 ++++++++++++++----- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/apps/web/src/components/reui-kit/uptime-chart.tsx b/apps/web/src/components/reui-kit/uptime-chart.tsx index 6a8bef9..293b4cd 100644 --- a/apps/web/src/components/reui-kit/uptime-chart.tsx +++ b/apps/web/src/components/reui-kit/uptime-chart.tsx @@ -1,6 +1,6 @@ import { useId, useMemo, useState } from 'react' import { ActivityIcon, InfoIcon, TrendingDownIcon, TrendingUpIcon } from 'lucide-react' -import { Area, ComposedChart, Line, XAxis } from 'recharts' +import { Area, ComposedChart, Line, XAxis, YAxis } from 'recharts' import { EmptyState } from '@/components/empty-state' import { Badge } from '@/components/reui/badge' @@ -226,14 +226,14 @@ export function UptimeChart({ }: UptimeChartProps) { const gradientId = useId().replace(/:/g, '') const [internalPeriod, setInternalPeriod] = useState('5D') - const [pinnedIndex, setPinnedIndex] = useState() + const [hovered, setHovered] = useState(null) const period = periodProp ?? internalPeriod const days = UPTIME_PERIODS.find((entry) => entry.key === period)?.days ?? 5 function handlePeriodChange(next: UptimePeriodKey) { onPeriodChange?.(next) if (periodProp == null) setInternalPeriod(next) - setPinnedIndex(undefined) + setHovered(null) } const { points, keys } = useMemo( @@ -246,9 +246,25 @@ export function UptimeChart({ const tileClass = lastOk ? 'text-success' : 'text-destructive' const single = keys.length <= 1 const areaKey = keys[0] ?? 'local' + const hoverPings = hovered + ? keys.map((key) => { + const ok = hovered[`${key}Ok`] + const label = chartConfig[key].label + return `${label} ${formatPing(hovered[key], ok)}` + }) + : [] + + function syncHover(state: { + activeTooltipIndex?: unknown + activeIndex?: unknown + }) { + const index = Number(state.activeTooltipIndex ?? state.activeIndex) + if (!Number.isFinite(index)) return + setHovered(points[index] ?? null) + } const panel = ( - + {hideHeader ? null : (
@@ -316,22 +332,33 @@ export function UptimeChart({
+ {hoverPings.length > 0 ? ( +

+ Пинг + {' · '} + {formatDate(hovered?.at)} + {' · '} + {hoverPings.join(' · ')} +

+ ) : ( +

+ Наведите на точку графика +

+ )} +
{ - const index = state.activeTooltipIndex ?? state.activeIndex - if (index == null) return - const next = Number(index) - if (Number.isFinite(next)) setPinnedIndex(next) - }} + onMouseMove={syncHover} + onMouseLeave={() => setHovered(null)} + onClick={syncHover} > @@ -347,13 +374,14 @@ export function UptimeChart({ /> - + +