deviant/scripts/dashboard.html

81 lines
4.2 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang="en"><head>
<meta charset="utf-8" /><title>Deviant · chipnet dashboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
:root { color-scheme: dark; --bg:#0c0e12; --fg:#dfe7ee; --muted:#7d8a98; --acid:#a5f050; --row:#161a22; --row2:#1c2230; --bord:#2a3346; }
body { margin:0; padding:24px; background:var(--bg); color:var(--fg); font:14px/1.4 ui-sans-serif,system-ui,sans-serif; }
h1 { font-size:18px; font-weight:600; margin:0 0 4px; }
.sub { color:var(--muted); font-size:12px; margin-bottom:18px; }
.sub .acid { color:var(--acid); }
table { border-collapse:collapse; width:100%; max-width:980px; background:var(--row); border:1px solid var(--bord); }
th, td { padding:9px 12px; border-bottom:1px solid var(--bord); text-align:left; }
tr:last-child td { border-bottom:none; }
tr:nth-child(even) td { background:var(--row2); }
th { font-weight:600; color:var(--muted); font-size:11px; text-transform:uppercase; letter-spacing:.06em; }
td.num { font-variant-numeric:tabular-nums; text-align:right; font-family:ui-monospace,monospace; }
td.addr { font-family:ui-monospace,monospace; font-size:12px; color:#bcc4cf; }
.lbl { display:inline-block; padding:2px 8px; border-radius:11px; background:rgba(165,240,80,.12); border:1px solid rgba(165,240,80,.35); color:var(--acid); font-weight:600; font-size:11px; }
.err { color:#ff8079; font-style:italic; }
.total { background:#10141a !important; font-weight:600; }
.footer { color:var(--muted); font-size:11px; margin-top:14px; }
</style></head>
<body>
<h1>Deviant · chipnet wallet dashboard</h1>
<div class="sub">Auto-refreshing every <span class="acid">__INTERVAL__s</span> · last update <span id="ts">—</span></div>
<table>
<thead><tr>
<th>Wallet</th><th>Address</th>
<th style="text-align:right">Plain BCH (sats)</th>
<th style="text-align:right">Plain BCH</th>
<th style="text-align:right">BCH UTXOs</th>
<th style="text-align:right">Tok UTXOs</th>
<th style="text-align:right">Locked (sats)</th>
<th style="text-align:right">Cats</th>
</tr></thead>
<tbody id="rows"><tr><td colspan="8" style="color:#7d8a98;text-align:center">Loading…</td></tr></tbody>
</table>
<div class="footer">Served by <code>scripts/dashboard-serve.mjs</code>. Template: <code>scripts/dashboard.html</code>. Source of truth: chipnet electrum (<code>ElectrumNetworkProvider</code>).</div>
<script>
const fmtBch = (sats) => (Number(sats) / 1e8).toFixed(8);
const shortAddr = (a) => a ? a.slice(0, 14) + '…' + a.slice(-8) : '';
async function tick() {
try {
const r = await fetch('/api/balances', { cache: 'no-store' });
const { ts, rows } = await r.json();
document.getElementById('ts').textContent = new Date(ts).toLocaleString();
let totalBch = 0n, totalLocked = 0n;
let html = '';
for (const row of rows) {
if (row.error) {
html += '<tr><td><span class="lbl">' + row.label + '</span></td><td colspan="7" class="err">' + row.error + '</td></tr>';
continue;
}
totalBch += BigInt(row.bchSats);
totalLocked += BigInt(row.lockedSats);
html += '<tr>'
+ '<td><span class="lbl">' + row.label + '</span></td>'
+ '<td class="addr" title="' + row.cashaddr + '">' + shortAddr(row.cashaddr) + '</td>'
+ '<td class="num">' + Number(row.bchSats).toLocaleString() + '</td>'
+ '<td class="num">' + fmtBch(row.bchSats) + '</td>'
+ '<td class="num">' + row.bchUtxos + '</td>'
+ '<td class="num">' + row.tokUtxos + '</td>'
+ '<td class="num">' + Number(row.lockedSats).toLocaleString() + '</td>'
+ '<td class="num">' + row.cats + '</td>'
+ '</tr>';
}
html += '<tr class="total"><td colspan="2">Σ all wallets</td>'
+ '<td class="num">' + Number(totalBch).toLocaleString() + '</td>'
+ '<td class="num">' + fmtBch(totalBch) + '</td>'
+ '<td class="num">—</td><td class="num">—</td>'
+ '<td class="num">' + Number(totalLocked).toLocaleString() + '</td>'
+ '<td class="num">—</td></tr>';
document.getElementById('rows').innerHTML = html;
} catch (e) { console.error(e); }
}
tick();
setInterval(tick, __INTERVAL__ * 1000);
</script>
</body></html>