upp/web/index.html

194 lines
4.2 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link crossorigin rel="stylesheet" href="https://cdn.alemi.dev/web/alemi.css">
<title>uppe.rs</title>
<style>
span.cell {
2024-12-03 01:24:23 +01:00
position: relative;
display: inline-block;
2024-12-03 01:24:23 +01:00
width: .5rem;
height: 1.2rem;
border: 1px solid var(--secondary);
2024-12-03 01:24:23 +01:00
font-size: 8pt;
line-height: 1.2rem;
background-color: rgba(var(--secondary-rgb), 0.4);
2024-12-03 01:24:23 +01:00
margin-top: .3rem;
margin-bottom: .3rem;
padding-top: 0;
padding-bottom: 0;
transition: .1s;
text-align: center;
cursor: default;
2024-12-03 01:24:23 +01:00
border-radius: .3rem;
color: #ffffff00;
}
span.cell:hover {
2024-12-03 01:24:23 +01:00
padding-top: .3rem;
padding-bottom: .3rem;
width: 2rem;
font-size: 8pt;
margin-top: 0;
margin-bottom: 0;
2024-12-03 01:24:23 +01:00
margin-right: -0.75rem;
margin-left: -0.75rem;
color: var(--background);
background-color: rgba(var(--secondary-rgb), 1);
z-index: 1;
font-weight: bold;
}
2024-12-01 04:36:31 +01:00
span.cell.warning {
border-color: var(--accent);
}
span.cell.error {
border-color: var(--accent);
background-color: rgba(var(--accent-rgb), 0.4);
}
2024-12-03 01:24:23 +01:00
span.cell.error:hover {
background-color: rgba(var(--accent-rgb), 1);
}
2024-12-03 03:30:55 +01:00
span.sep {
color: var(--background-secondary);
margin-right: 1em;
margin-left: 1em;
}
hr.color {
color: var(--accent);
border-color: var(--accent);
}
2024-12-03 01:24:23 +01:00
div.card {
display: inline-block;
white-space: nowrap;
2024-12-03 01:24:23 +01:00
overflow-x: scroll;
max-width: 100%;
margin-top: 2em;
border-radius: 1em;
border: 1px solid var(--background-secondary);
padding: 1em;
box-sizing: border-box;
transition: .3s;
}
div.card:hover {
background-color: var(--background-dim);
}
2024-12-03 03:30:55 +01:00
body {
margin: 0;
}
footer {
width: 100%;
}
div.content {
min-height: calc(100vh - 3.5rem);
}
span.dots {
&:after {
animation: dots 1.5s linear infinite;
display: inline-block;
content: "\00a0\00a0\00a0";
}
}
@keyframes dots {
0% { content: "\00a0\00a0\00a0"; }
25% { content: ".\00a0\00a0"; }
50% { content: "..\00a0"; }
75% { content: "..."; }
100% { content: "\00a0\00a0\00a0"; }
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
}
</style>
</head>
<body>
2024-12-03 03:30:55 +01:00
<div class="content">
<div class="ml-1">
<h1 class="mt-0 pt-1">uppe.rs</h1>
<p>%%DESCRIPTION%%</p>
</div>
<hr class="color"/>
2024-12-03 03:30:55 +01:00
<main id="uppe-rs-content">
<h2 class="center mt-3">loading<span class="dots"></span></h2>
2024-12-03 03:30:55 +01:00
</main>
</div>
2024-12-03 03:30:55 +01:00
<footer>
<hr />
<p class="mt-s mb-s">
<span class="cell error">...</span> down <span class="sep">|</span>
<span class="cell warning">...</span> slow <span class="sep">|</span>
<span class="cell">...</span> up
</p>
</footer>
</body>
<script>
function cell(timestamp, rtt) {
let d = new Date(timestamp * 1000);
2024-12-01 04:36:31 +01:00
let warning = "";
2024-12-03 01:58:49 +01:00
if (rtt !== null && rtt >= %%THRESHOLD%%) {
2024-12-01 04:36:31 +01:00
warning = " warning";
}
if (rtt === null) {
2024-12-03 01:24:23 +01:00
return `<span class="cell error" title="${d}"></span>`;
} else {
2024-12-01 04:36:31 +01:00
return `<span class="cell${warning}" title="${rtt}ms -- ${d}">${rtt}</span>`;
}
}
2024-12-02 23:44:27 +01:00
function card(key, history, last_rtt) {
let bar = "";
2024-12-03 03:06:16 +01:00
let now = Math.floor(Date.now() / 1000);
let first = history[history.length - 1][0];
2024-12-03 03:06:16 +01:00
let hrs_ago = (now - first) / 3600;
for (let el of history) {
bar += cell(el[0], el[1]);
}
return `<div class="card">
2024-12-03 01:24:23 +01:00
<h3 class="mt-0">${key} <code class="color">${last_rtt ? last_rtt + 'ms' : 'DOWN'}</code></h3>
<table class="align">
<tr>
<td colspan="2">${bar}</td>
</tr>
<tr>
<td><small>^ now</small></td>
<td class="rev"><small>~${hrs_ago.toFixed(1)}h ago ^</small></td>
</tr>
</table>
2024-12-03 01:24:23 +01:00
</div>`;
}
let main = document.getElementById("uppe-rs-content");
async function updateStatus() {
let res = await fetch("/api/status")
let status = await res.json()
2024-12-03 01:24:23 +01:00
if (status.error) {
console.error("server error:", status);
return;
}
let keys = Object.keys(status);
keys.sort();
let out = "";
for (let key of keys) {
2024-12-03 20:13:05 +01:00
let res = await fetch(`/api/status/${key}?limit=%%BATCHSIZE%%`);
let history = await res.json();
2024-12-02 23:44:27 +01:00
out += card(key, history, status[key]);
2024-12-03 01:24:23 +01:00
out += "\n";
}
main.innerHTML = out;
}
setInterval(updateStatus, 60 * 1000)
updateStatus()
</script>
</html>