diff --git a/src/client/components/StatusHistoryBar.tsx b/src/client/components/StatusHistoryBar.tsx index f3b5eb5..299712e 100644 --- a/src/client/components/StatusHistoryBar.tsx +++ b/src/client/components/StatusHistoryBar.tsx @@ -1,14 +1,17 @@ import type { PublicService } from '../api/status'; +import { useMediaQuery } from '../lib/useMediaQuery'; const DAY_MS = 24 * 60 * 60 * 1000; +// Desktop mirrors the API's full 90-day history. Compact screens use the most +// recent 45 days so each daily bar remains legible. const HISTORY_DAYS = 90; -const DAYS_PER_SEGMENT = 2; -const HISTORY_SEGMENTS = HISTORY_DAYS / DAYS_PER_SEGMENT; +const HISTORY_DAYS_COMPACT = 45; +const COMPACT_QUERY = '(max-width: 520px)'; type HistoryEntry = PublicService['history'][number]; -function dayClass(uptimePct: number | null) { - if (uptimePct === null) return 'is-empty'; +function dayClass(uptimePct: number | null | undefined) { + if (uptimePct === null || uptimePct === undefined) return 'is-empty'; if (uptimePct === 100) return 'is-up'; if (uptimePct === 0) return 'is-down'; return 'is-partial'; @@ -23,34 +26,31 @@ function formatDay(day: number) { }).format(new Date(day)); } -function segmentTitle(startDay: number, endDay: number, uptimePct: number | null) { - const dateRange = `${formatDay(startDay)} – ${formatDay(endDay)}`; - return `${dateRange}: ${uptimePct === null ? 'No data' : `${uptimePct.toFixed(1)}% uptime`}`; +function dayTitle(day: number, uptimePct: number | null | undefined) { + const detail = uptimePct === null || uptimePct === undefined ? 'No data' : `${uptimePct.toFixed(1)}% uptime`; + return `${formatDay(day)}: ${detail}`; } export function StatusHistoryBar({ history }: { history: HistoryEntry[] }) { + const compact = useMediaQuery(COMPACT_QUERY); + const windowDays = compact ? HISTORY_DAYS_COMPACT : HISTORY_DAYS; const historyByDay = new Map(history.map((entry) => [entry.day, entry.uptimePct])); const now = new Date(); const today = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()); - const segments = Array.from({ length: HISTORY_SEGMENTS }, (_segment, index) => { - const startDay = today - (HISTORY_DAYS - index * DAYS_PER_SEGMENT - 1) * DAY_MS; - const endDay = startDay + (DAYS_PER_SEGMENT - 1) * DAY_MS; - const values = Array.from({ length: DAYS_PER_SEGMENT }, (_day, dayIndex) => historyByDay.get(startDay + dayIndex * DAY_MS)).filter( - (value): value is number => value !== undefined && value !== null, - ); - const uptimePct = values.length === 0 ? null : Math.round((values.reduce((sum, value) => sum + value, 0) / values.length) * 10) / 10; - return { startDay, endDay, uptimePct }; + const days = Array.from({ length: windowDays }, (_day, index) => { + const day = today - (windowDays - 1 - index) * DAY_MS; + return { day, uptimePct: historyByDay.get(day) }; }); return (