From 2f067d678c50c2ecc7eff38d9efc796bfd26b69e Mon Sep 17 00:00:00 2001 From: Heidi Date: Thu, 14 May 2026 20:54:13 +0100 Subject: [PATCH] feat:/ added uptime page --- src/App.jsx | 77 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index cb34d5b..65d3e29 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -120,7 +120,7 @@ function App() { const [route, setRoute] = useState(() => parseRoute()) const [leaderboard, setLeaderboard] = useState({ status: 'idle', data: null, error: null }) const [live, setLive] = useState({ status: 'idle', data: null, error: null }) - const [uptime, setUptime] = useState({ status: 'idle', checks: [], updatedAt: null }) + const [uptime, setUptime] = useState({ status: 'idle', checks: [], history: [], updatedAt: null }) const [teamQuery, setTeamQuery] = useState('') const [searchHint, setSearchHint] = useState({ status: 'idle', name: '' }) const [profile, setProfile] = useState({ @@ -326,6 +326,7 @@ function App() { setUptime((current) => ({ status: current.status === 'ready' ? 'refreshing' : 'loading', checks: current.checks, + history: current.history, updatedAt: current.updatedAt, })) @@ -343,10 +344,8 @@ function App() { if (controller.signal.aborted) return - setUptime({ - status: 'ready', - updatedAt: Date.now(), - checks: [ + setUptime((current) => { + const checks = [ { name: 'Website', detail: 'App shell and static assets', @@ -368,7 +367,23 @@ function App() { label: apiResult.label, latency: Math.round(performance.now() - startedAt), }, - ], + ] + const onlineChecks = checks.filter((check) => check.ok).length + + return { + status: 'ready', + updatedAt: Date.now(), + checks, + history: [ + ...current.history, + { + timestamp: Date.now(), + onlineChecks, + totalChecks: checks.length, + ok: onlineChecks === checks.length, + }, + ].slice(-48), + } }) } @@ -1059,9 +1074,12 @@ function BattleLogsPage({ live, matches }) { function UptimePage({ uptime }) { const checks = uptime.checks + const history = uptime.history const operationalCount = checks.filter((check) => check.ok).length const allOperational = checks.length > 0 && operationalCount === checks.length const updatedAt = uptime.updatedAt ? dateFormat.format(new Date(uptime.updatedAt)) : 'Not checked yet' + const onlineSamples = history.filter((sample) => sample.ok).length + const availability = history.length ? (onlineSamples / history.length) * 100 : 0 return (
@@ -1089,6 +1107,53 @@ function UptimePage({ uptime }) { +
+
+
+

Availability timeline

+

+ Last {formatNumber(history.length)} checks from this browser session +

+
+

+ {history.length ? `${availability.toFixed(1)}% uptime` : 'Waiting for first sample'} +

+
+ +
+ {history.map((sample) => { + const height = `${Math.max(12, (sample.onlineChecks / sample.totalChecks) * 100)}%` + + return ( +
+ ) + })} + + {!history.length ? ( +
+ Checking website status +
+ ) : null} +
+ +
+ + + Uptime + + + + Downtime or degraded + +
+
+
{checks.map((check) => (