Forked from stevekrouse/status
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/** @jsxImportSource https://esm.sh/react */
import { sqlite } from "https://esm.town/v/std/sqlite?v=6";
import { html } from "https://esm.town/v/stevekrouse/html";
import { SparklineSVG } from "https://esm.town/v/stevekrouse/sparklineSVGReact";
import { renderToString } from "npm:react-dom/server";
function StatusRow({ rows }) {
return (
<div className="w-full flex flex-col space-y-2">
<div className="w-full h-16 flex flex-row">
{rows.map(row => (
<div
className={`flex-grow flex-shrink ${row[1] ? "bg-green-500" : "bg-red-500"} border border-white rounded p-`}
/>
))}
</div>
<h3 className="font-bold text-slate-700">Response times</h3>
<SparklineSVG
strokeWidth={1.5}
data={rows.map(row => row[2])}
height={70}
width={800}
fill="white"
stroke="rgba(0, 10, 150, 0.5)" // blue
/>
</div>
);
}
function StatusSection({ url, rows }) {
const sectionRows = rows.filter(row => row[0] === url);
const percentUp = Math.round((sectionRows.filter(row => row[1]).length / sectionRows.length) * 100);
return (
<div className="w-full">
<div className="w-full flex flex-row justify-between">
<h2 className="text-xl font-bold">{url.replace(/\/$/, "").replace(/^https?:\/\//, "")}</h2>
<p className="text-green-700">{percentUp}% uptime</p>
</div>
<div className="w-full">
<StatusRow rows={sectionRows} />
</div>
</div>
);
}
export default async function(req: Request): Promise<Response> {
const { rows } = await sqlite.execute(
"select url, ok, duration, timestamp from uptime order by timestamp desc limit 200",
);
const urls = [...new Set(rows.map(r => r[0]))];
return html(renderToString(
<html>
<head>
<title>Smallweb Status</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div className="max-w-4xl mx-auto p-10 flex flex-col space-y-10 items-center">
<div className="flex flex-col space-y-2 items-center">
<h1 className="text-3xl font-bold">Smallweb Status</h1>
<a href="https://val.town/v/stevekrouse/status" className="text-blue-500">view code</a>
</div>
{urls.map(url => <StatusSection url={url} rows={rows} />)}
</div>
</body>
</html>,
));
}
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
July 11, 2024