Merge pull request 'Add Prometheus-backed home server status' (#10) from feature/home-server-status-prometheus into main

Reviewed-on: #10
This commit was merged in pull request #10.
This commit is contained in:
2026-06-14 01:06:28 -04:00
5 changed files with 263 additions and 38 deletions
+1 -1
View File
@@ -65,7 +65,7 @@
return;
}
const top = rows.slice(0, 5);
const top = rows.slice(0, 10);
if (!top.length) {
list.innerHTML = `<li><span class="rank">1.</span><span>—</span></li>`;
+45 -37
View File
@@ -8,8 +8,9 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css?v=home-hardcore-preline-20260610-1">
<link rel="stylesheet" href="style.css?v=home-status-two-boxes-2">
<script src="app.js?v=account-status-label-20260609" defer></script>
<script src="server-status.js?v=home-status-prometheus-2" defer></script>
</head>
<body>
<div class="site-shell">
@@ -52,30 +53,48 @@
<h1 id="server-status-heading" class="section-title">Server Status</h1>
<div class="status-list" role="list" aria-label="Current server player counts">
<div class="status-row status-parent" role="listitem"><span>US Server</span><span></span></div>
<div class="status-list status-list--regions" role="list" aria-label="Current server player counts" data-server-status="loading">
<div class="status-region" role="group" aria-label="US Server player counts">
<div class="status-region-header">
<span>US Server</span><span>Loading…</span>
</div>
<div class="status-ship">
<div class="status-ship-name">Alis</div>
<div class="status-row"><span>V2</span><span></span></div>
<div class="status-row"><span>V3</span><span></span></div>
<div class="status-row"><span>BB</span><span></span></div>
</div>
<div class="status-ship">
<div class="status-ship-name">Abion</div>
<div class="status-row"><span>HC/BB</span><span></span></div>
</div>
<div class="status-ship">
<div class="status-ship-name">AdHoc-US</div>
<div class="status-row"><span>PSP1</span><span></span></div>
<div class="status-row"><span>PSP2i</span><span></span></div>
</div>
</div>
<div class="status-row status-parent" role="listitem"><span>Alis</span><span>0 Players</span></div>
<div class="status-row status-child" role="listitem"><span>V2</span><span>0 Players</span></div>
<div class="status-row status-child" role="listitem"><span>V3</span><span>0 Players</span></div>
<div class="status-row status-child" role="listitem"><span>BB</span><span>0 Players</span></div>
<div class="status-row status-parent" role="listitem"><span>Abion</span><span></span></div>
<div class="status-row status-child" role="listitem"><span>HC</span><span>0 Players</span></div>
<div class="status-row status-parent" role="listitem"><span>EU Server</span><span></span></div>
<div class="status-row status-parent" role="listitem"><span>Palma</span><span>0 Players</span></div>
<div class="status-row status-child" role="listitem"><span>V2</span><span>0 Players</span></div>
<div class="status-row status-child" role="listitem"><span>V3</span><span>0 Players</span></div>
<div class="status-row status-child" role="listitem"><span>BB</span><span>0 Players</span></div>
<div class="status-row status-parent" role="listitem"><span>Aiedo</span><span></span></div>
<div class="status-row status-child" role="listitem"><span>HC</span><span>0 Players</span></div>
<div class="status-row status-parent" role="listitem"><span>PSP Ship</span><span></span></div>
<div class="status-row status-child" role="listitem"><span>PSP1</span><span>0 Players</span></div>
<div class="status-row status-child" role="listitem"><span>PSP2i</span><span>0 Players</span></div>
<div class="status-region" role="group" aria-label="EU Server player counts">
<div class="status-region-header">
<span>EU Server</span><span>Loading…</span>
</div>
<div class="status-ship">
<div class="status-ship-name">Palma</div>
<div class="status-row"><span>V2</span><span></span></div>
<div class="status-row"><span>V3</span><span></span></div>
<div class="status-row"><span>BB</span><span></span></div>
</div>
<div class="status-ship">
<div class="status-ship-name">Aiedo</div>
<div class="status-row"><span>HC/BB</span><span></span></div>
</div>
<div class="status-ship">
<div class="status-ship-name">AdHoc-EU</div>
<div class="status-row"><span>PSP1</span><span></span></div>
<div class="status-row"><span>PSP2i</span><span></span></div>
</div>
</div>
</div>
</section>
@@ -90,22 +109,11 @@
<section class="card leaderboard-card" aria-labelledby="hardcore-heading">
<h2 id="hardcore-heading" class="section-title">Hardcore Leaderboard</h2>
<ol class="leaderboard-list leaderboard-list--home-hardcore" id="home-hardcore-leaderboard-body" aria-label="Top five hardcore players">
<ol class="leaderboard-list leaderboard-list--home-hardcore" id="home-hardcore-leaderboard-body" aria-label="Top ten hardcore players">
<li><span class="rank">1.</span><span>Loading...</span></li>
</ol>
<a class="small-link home-leaderboard-more" href="leaderboards.html">more</a>
</section>
<section class="card leaderboard-card" aria-labelledby="crank-heading">
<h2 id="crank-heading" class="section-title">C Rank Points</h2>
<ol class="leaderboard-list" aria-label="Top five C Rank point totals">
<li><span class="rank">1.</span><span></span></li>
<li><span class="rank">2.</span><span></span></li>
<li><span class="rank">3.</span><span></span></li>
<li><span class="rank">4.</span><span></span></li>
<li><span class="rank">5.</span><span></span></li>
</ol>
</section>
</aside>
</main>
@@ -139,6 +147,6 @@
</footer>
</div>
<script src="hero-cycle.js?v=force-cycle-3" defer></script>
<script src="home-leaderboard.js?v=home-hardcore-preline-20260610-1" defer></script>
<script src="home-leaderboard.js?v=home-hardcore-top10-1" defer></script>
</body>
</html>
+46
View File
@@ -0,0 +1,46 @@
(() => {
const list = document.querySelector(".status-list");
if (!list) return;
const esc = (value) => String(value ?? "").replace(/[&<>"']/g, (ch) => ({
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
"\"": "&quot;",
"'": "&#39;",
}[ch]));
const players = (value) => {
const n = Number(value || 0);
return `${n.toLocaleString()} ${n === 1 ? "Player" : "Players"}`;
};
const render = (data) => {
const servers = Array.isArray(data?.servers) ? data.servers : [];
if (!servers.length) return;
list.classList.add("status-list--regions");
list.innerHTML = servers.map((server) => `
<div class="status-region" role="group" aria-label="${esc(server.label)} player counts">
<div class="status-row status-parent status-server" role="listitem">
<span>${esc(server.label)}</span><span>${players(server.players)}</span>
</div>
${(server.ships || []).map((ship) => `
<div class="status-row status-parent status-ship" role="listitem">
<span>${esc(ship.label)}</span><span></span>
</div>
${(ship.rows || []).map((row) => `
<div class="status-row status-child" role="listitem">
<span>${esc(row.label)}</span><span>${players(row.players)}</span>
</div>
`).join("")}
`).join("")}
</div>
`).join("");
};
fetch("/api/server-status", { cache: "no-store" })
.then((res) => res.ok ? res.json() : null)
.then((data) => data && render(data))
.catch(() => {});
})();
+57
View File
@@ -1857,4 +1857,61 @@ button.inline-link,
overflow-x: auto;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
}\n\n
/* Home right column: stretch Hardcore leaderboard after C Rank removal */
.right-stack {
display: flex;
flex-direction: column;
}
.right-stack .leaderboard-card {
flex: 1;
}
\n
/* Home layout: stretch right column to match server status card */
.home-grid {
align-items: stretch;
}
.right-stack {
display: flex;
flex-direction: column;
height: 100%;
}
.right-stack .leaderboard-card {
flex: 1 1 auto;
}
/* Home server status: split US/EU into two inner boxes */
.server-card .status-list.status-list--regions {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
background: transparent;
border: 0;
padding: 0;
}
.server-card .status-region {
display: grid;
gap: 0.35rem;
padding: 1rem;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 0.45rem;
background: rgba(0, 0, 0, 0.35);
}
.server-card .status-region .status-row {
grid-template-columns: minmax(0, 1fr) max-content;
}
@media (max-width: 720px) {
.server-card .status-list.status-list--regions {
grid-template-columns: 1fr;
}
}