forked from bitcoinafterlife/bal-welist-website
Server page restyled in the site's look
- Header with back button, server card with status badge, Listing card (expiry, days left, renewal window), Activity tiles, WeTime table in the home style - Inline CSS only; qrcode.min.js dropped (unused); bal.js pager renders prev / page / next buttons
This commit is contained in:
21
bal.js
21
bal.js
@@ -76,18 +76,19 @@ async function fetchDataAndPopulateTable(url,params,fnPopulateTable,downloadOpt,
|
|||||||
function make_paginator(){
|
function make_paginator(){
|
||||||
document.getElementById("chainth").innerHTML = chain;
|
document.getElementById("chainth").innerHTML = chain;
|
||||||
const pag = document.getElementById("paginator");
|
const pag = document.getElementById("paginator");
|
||||||
|
pag.innerHTML = "";
|
||||||
pag.appendChild(document.createTextNode("_"));
|
// prev (a plain, dimmed arrow on the first page), "page N", next
|
||||||
if (page > 0) {
|
if (page > 0) {
|
||||||
pag.appendChild(createlink("<","?page="+paginator.prev));
|
pag.appendChild(createlink("‹","?page="+paginator.prev));
|
||||||
|
} else {
|
||||||
|
const off = document.createElement("span");
|
||||||
|
off.className = "pg-off"; off.innerHTML = "‹";
|
||||||
|
pag.appendChild(off);
|
||||||
}
|
}
|
||||||
else{
|
const lbl = document.createElement("span");
|
||||||
pag.appendChild(document.createTextNode("<"));
|
lbl.className = "pg-label"; lbl.textContent = "page " + page;
|
||||||
}
|
pag.appendChild(lbl);
|
||||||
pag.appendChild(document.createTextNode("_"));
|
pag.appendChild(createlink("›","?page="+paginator.next));
|
||||||
pag.appendChild(document.createTextNode(page));
|
|
||||||
pag.appendChild(document.createTextNode("_"));
|
|
||||||
pag.appendChild(createlink(">","?page="+paginator.next));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
325
weinfo.html
325
weinfo.html
@@ -1,82 +1,206 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Bal Server List</title>
|
<title>Will Executor — Server page</title>
|
||||||
<link rel="icon" href="Logo_nero.ico" type="image/x-icon">
|
<meta name="robots" content="noindex">
|
||||||
<script src="/qrcode.min.js"></script>
|
<link rel="icon" href="/Logo_nero.ico" type="image/x-icon">
|
||||||
<script src="/purify.min.js"></script>
|
<script src="/purify.min.js"></script>
|
||||||
<script src="/bal.js"></script>
|
<script src="/bal.js"></script>
|
||||||
</head>
|
<!--
|
||||||
|
Server detail page, restyled 2026-11-06 in the look of index.html (same colour
|
||||||
|
variables and type). Deliberately light: inline CSS only, no new script
|
||||||
|
(qrcode.min.js was loaded and never used, so it is gone). The data flow is
|
||||||
|
unchanged: fetchDataAndPopulateTable (bal.js) reads /weinfodata/<chain>/<id>
|
||||||
|
with ?page/?limit and draws the prev/next links into #paginator; the payment
|
||||||
|
banner polls the same endpoint until the deposit is credited.
|
||||||
|
-->
|
||||||
<style>
|
<style>
|
||||||
table {
|
:root{
|
||||||
border-collapse: collapse;
|
--maxw:1120px;--radius:10px;
|
||||||
width: 100%;
|
--bg:#eef1f4;--panel:#ffffff;--ink:#1a2027;--muted:#5b6672;
|
||||||
margin-top: 20px;
|
--line:#dfe4ea;--line-strong:#cbd2da;
|
||||||
|
--accent:#2d6cdf;--accent-soft:#e6eefc;
|
||||||
|
--ok:#1f9d57;--ok-soft:#e3f4ea;--off:#9aa4b0;--off-soft:#eceff3;
|
||||||
|
--display:"Inter","Segoe UI",system-ui,-apple-system,sans-serif;
|
||||||
|
--body:"Inter","Segoe UI",system-ui,-apple-system,sans-serif;
|
||||||
|
--mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
|
||||||
|
--shadow:0 1px 2px rgba(20,30,50,.05);
|
||||||
}
|
}
|
||||||
th, td {
|
*{box-sizing:border-box}
|
||||||
border: 1px solid #ddd;
|
html,body{margin:0}
|
||||||
padding: 8px;
|
body{background:var(--bg);color:var(--ink);font-family:var(--body);font-size:15px;line-height:1.5}
|
||||||
text-align: left;
|
a{color:var(--accent)}
|
||||||
}
|
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px}
|
||||||
th {
|
.mono{font-family:var(--mono)}
|
||||||
background-color: #f2f2f2;
|
|
||||||
}
|
header.hero{padding:28px 0 22px;border-bottom:1px solid var(--line);background:var(--panel)}
|
||||||
tr:nth-child(even) {
|
.hero .wrap{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap}
|
||||||
background-color: #f9f9f9;
|
.brand{display:flex;align-items:center;gap:14px;text-decoration:none;color:inherit}
|
||||||
}
|
.brand .mark{width:44px;height:44px;border-radius:12px;border:1px solid var(--line);display:flex;align-items:center;justify-content:center;background:#fff}
|
||||||
span {
|
.brand .mark img{width:30px;height:30px;display:block}
|
||||||
margin-left:10px;
|
.brand h1{font-family:var(--display);font-size:18px;font-weight:600;margin:0;letter-spacing:-.01em}
|
||||||
|
.brand .sub{color:var(--muted);font-size:13px}
|
||||||
|
.back-btn{display:inline-flex;align-items:center;gap:8px;padding:9px 14px;border-radius:10px;border:1px solid var(--line-strong);
|
||||||
|
background:var(--panel);color:var(--accent);font-weight:600;font-size:14px;text-decoration:none;box-shadow:var(--shadow)}
|
||||||
|
.back-btn:hover{border-color:var(--accent)}
|
||||||
|
.back-btn svg{width:18px;height:18px}
|
||||||
|
|
||||||
|
main{padding:28px 0 40px}
|
||||||
|
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:22px 24px}
|
||||||
|
.server .url{font-family:var(--mono);font-size:22px;font-weight:600;word-break:break-all;margin:0 0 6px}
|
||||||
|
.server .info{color:var(--muted);margin:0 0 14px}
|
||||||
|
.badges{display:flex;flex-wrap:wrap;gap:8px}
|
||||||
|
.badge{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-family:var(--mono);padding:4px 10px;border-radius:999px;
|
||||||
|
background:var(--off-soft);color:var(--muted);border:1px solid var(--line)}
|
||||||
|
.badge.ok{background:var(--ok-soft);color:var(--ok);border-color:#bfe3cd}
|
||||||
|
.badge.ok::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--ok)}
|
||||||
|
.badge.bad{background:#fdecec;color:#b42318;border-color:#f5c2c0}
|
||||||
|
.badge.bad::before{content:"";width:8px;height:8px;border-radius:50%;background:#b42318}
|
||||||
|
|
||||||
|
#wepayment{display:none;margin:16px 0 0;padding:10px 14px;border-radius:8px;font-weight:600;font-size:14px}
|
||||||
|
|
||||||
|
.grid2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);gap:20px;margin-top:20px}
|
||||||
|
.sec-title{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);font-weight:600;margin:0 0 12px}
|
||||||
|
.expiry .big{font-family:var(--display);font-size:32px;font-weight:600;line-height:1.1;margin:0}
|
||||||
|
.expiry .days{color:var(--muted);font-size:13px;margin:2px 0 14px}
|
||||||
|
.kv{display:grid;grid-template-columns:1fr 1fr;gap:10px 18px;font-size:13px}
|
||||||
|
.kv div{display:flex;flex-direction:column;gap:2px;border-top:1px solid var(--line);padding-top:8px}
|
||||||
|
.kv span{color:var(--muted)}
|
||||||
|
.kv b{font-family:var(--mono);font-weight:600}
|
||||||
|
.open{color:var(--ok)}
|
||||||
|
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
|
||||||
|
.tile{border:1px solid var(--line);border-radius:8px;padding:12px 14px;background:var(--bg)}
|
||||||
|
.tile .n{font-family:var(--display);font-size:22px;font-weight:600;line-height:1.1}
|
||||||
|
.tile .l{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-top:4px}
|
||||||
|
.tile.wide{grid-column:1 / -1;display:flex;justify-content:space-between;align-items:center;gap:12px}
|
||||||
|
.tile.wide .n{font-size:13px;font-family:var(--mono)}
|
||||||
|
|
||||||
|
.rounds{margin-top:20px;padding:0;overflow:hidden}
|
||||||
|
.rounds .head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:16px 24px;border-bottom:1px solid var(--line)}
|
||||||
|
.rounds .head h2{font-family:var(--display);font-size:16px;margin:0}
|
||||||
|
.rounds .head .note{color:var(--muted);font-size:13px}
|
||||||
|
.pager{display:flex;align-items:center;gap:6px;font-family:var(--mono);font-size:13px;color:var(--muted)}
|
||||||
|
#paginator a{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:1px solid var(--line-strong);
|
||||||
|
border-radius:8px;background:var(--panel);color:var(--ink);text-decoration:none;font-weight:600}
|
||||||
|
#paginator a:hover{border-color:var(--accent);color:var(--accent)}
|
||||||
|
.pg-off{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:1px solid var(--line);border-radius:8px;color:var(--off)}
|
||||||
|
.pg-label{padding:0 4px}
|
||||||
|
.table-wrap{overflow-x:auto}
|
||||||
|
table{border-collapse:collapse;width:100%;font-size:13px}
|
||||||
|
th{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);text-align:left;
|
||||||
|
padding:10px 14px;border-bottom:1px solid var(--line);background:#fafbfc;white-space:nowrap}
|
||||||
|
td{padding:10px 14px;border-bottom:1px solid var(--line);white-space:nowrap;vertical-align:top}
|
||||||
|
tr:last-child td{border-bottom:0}
|
||||||
|
td.num,th.num{text-align:right;font-family:var(--mono)}
|
||||||
|
td.hash{font-family:var(--mono);color:var(--muted)}
|
||||||
|
.pos-1{color:var(--ok);font-weight:600}
|
||||||
|
.foot{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;padding:14px 24px;border-top:1px solid var(--line);font-size:13px;color:var(--muted)}
|
||||||
|
.btn-ghost{font:inherit;font-size:13px;text-decoration:none;padding:8px 12px;border-radius:8px;border:1px solid var(--line-strong);
|
||||||
|
background:var(--panel);color:var(--ink);display:inline-flex;gap:7px;align-items:center}
|
||||||
|
.btn-ghost:hover{border-color:var(--accent);color:var(--accent)}
|
||||||
|
|
||||||
|
footer{border-top:1px solid var(--line);margin-top:32px;padding:24px 0;color:var(--muted);font-size:13px}
|
||||||
|
footer .wrap{display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px}
|
||||||
|
footer a{color:var(--accent);text-decoration:none}
|
||||||
|
|
||||||
|
@media (max-width:760px){
|
||||||
|
.grid2{grid-template-columns:1fr}
|
||||||
|
.tiles{grid-template-columns:repeat(2,1fr)}
|
||||||
|
.server .url{font-size:18px}
|
||||||
|
.expiry .big{font-size:28px}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div align="center">
|
|
||||||
<a href="/"><img alt="BAL LOGO" src="/Logo_nero.png"></a>
|
<header class="hero">
|
||||||
<h2 id="wename"> </h2>
|
<div class="wrap">
|
||||||
<h3 id="weinfo"> </h3>
|
<a class="brand" href="/">
|
||||||
<h4 id="wechain"> </h4>
|
<span class="mark"><img alt="Bitcoin After Life" src="/Logo_nero.png"></span>
|
||||||
<div id="wepayment" style="display:none;max-width:640px;margin:10px auto 18px;padding:10px 14px;border-radius:8px;font-weight:600"></div>
|
<span><h1>Will Executor — Server List</h1><span class="sub">Bitcoin After Life · server page</span></span>
|
||||||
|
</a>
|
||||||
|
<a class="back-btn" href="/"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11 17l-5-5 5-5"/><path d="M6 12h6"/><path d="M15 6h4M15 12h4M15 18h4"/></svg>Back to the server list</a>
|
||||||
</div>
|
</div>
|
||||||
<div style="float:left;border:1;margin-right:50px;">
|
</header>
|
||||||
<div><span>Version:</span><span id="weversion"> </span></div>
|
|
||||||
<div><span>Fees:</span><span id="wefees"> </span></div>
|
<main class="wrap">
|
||||||
<div><span>Tld:</span><span id="wetld"> </span></div>
|
|
||||||
<div><span>Last Update:</span><span id="weupdate"> </span></div>
|
<section class="card server">
|
||||||
|
<p class="url" id="wename"> </p>
|
||||||
|
<p class="info" id="weinfo"> </p>
|
||||||
|
<div class="badges">
|
||||||
|
<span class="badge" id="wechain"> </span>
|
||||||
|
<span class="badge"><span>v</span><span id="weversion"> </span></span>
|
||||||
|
<span class="badge" id="westatus-badge"><span id="westatus"> </span></span>
|
||||||
</div>
|
</div>
|
||||||
<div style="float:left;border:1;margin-right:50px;">
|
<div id="wepayment"></div>
|
||||||
<div><span>Height:</span><span id="weheight"> </span></div>
|
</section>
|
||||||
<div><span>Points:</span><span id="wepoints"> </span></div>
|
|
||||||
<div><span>Win:</span><span id="wewin"> </span></div>
|
<div class="grid2">
|
||||||
|
<section class="card expiry">
|
||||||
|
<p class="sec-title">Listing</p>
|
||||||
|
<p class="big" id="weexpiry"> </p>
|
||||||
|
<p class="days" id="wedays"> </p>
|
||||||
|
<div class="kv">
|
||||||
|
<div><span>Renewal window</span><b id="wewindow">—</b></div>
|
||||||
|
<div><span>Balance</span><b id="webalance">—</b></div>
|
||||||
|
<div><span>Donations</span><b id="wedonations">—</b></div>
|
||||||
|
<div><span>Domain</span><b id="wetld">—</b></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="border:1;margin-right:50px;">
|
</section>
|
||||||
<div><span>Balance:</span><span id="webalance"> </span></div>
|
|
||||||
<div><span>Donations:</span><span id="wedonations"> </span></div>
|
<section class="card">
|
||||||
<div><span>Status:</span><span id="westatus"> </span></div>
|
<p class="sec-title">Activity</p>
|
||||||
<div><span>Expiry:</span><span id="weexpiry"> </span></div>
|
<div class="tiles">
|
||||||
|
<div class="tile"><div class="n" id="wepoints">—</div><div class="l">Points</div></div>
|
||||||
|
<div class="tile"><div class="n" id="wewin">—</div><div class="l">Wins</div></div>
|
||||||
|
<div class="tile"><div class="n" id="wefees">—</div><div class="l">Fee (sats)</div></div>
|
||||||
|
<div class="tile"><div class="n" id="weheight">—</div><div class="l">Height</div></div>
|
||||||
|
<div class="tile wide"><div class="l" style="margin:0">Last update</div><div class="n" id="weupdate">—</div></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="card rounds">
|
||||||
|
<div class="head">
|
||||||
|
<div><h2>WeTime rounds</h2><div class="note">Each round: the block hash sent by this server and how fast it was. Chain: <span class="mono" id="chainth"></span></div></div>
|
||||||
|
<div class="pager"><span id="paginator"></span></div>
|
||||||
|
</div>
|
||||||
|
<div class="table-wrap">
|
||||||
<table id="wetimes">
|
<table id="wetimes">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan=5><span id="chainth"><!-- --></span>: <span id="paginator"></span></th>
|
<th class="num">Height</th>
|
||||||
</tr>
|
<th>Block hash</th>
|
||||||
<tr>
|
<th>Time</th>
|
||||||
<th>height</th>
|
<th class="num">Delay</th>
|
||||||
<th>block hash</th>
|
<th class="num">Position</th>
|
||||||
<th>time</th>
|
<th class="num">Participants</th>
|
||||||
<th>diff</th>
|
<th class="num">Points</th>
|
||||||
<th>position</th>
|
|
||||||
<th>participants</th>
|
|
||||||
<th>points</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody><!-- rows from the script --></tbody>
|
||||||
<!-- -->
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<a href="" id="download">Download</a>
|
<div class="foot">
|
||||||
|
<span>Points reward fast answers within the same block; they only break ties in the list.</span>
|
||||||
|
<a class="btn-ghost" href="" id="download">↓ Download JSON</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<div class="wrap">
|
||||||
|
<span>Bitcoin After Life — Will Executor List</span>
|
||||||
|
<a href="/">← Server list</a>
|
||||||
|
<a href="/terms.html">Terms</a>
|
||||||
|
<a href="mailto:welist@bitcoin-after.life">welist@bitcoin-after.life</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// Payment banner: this page has a fixed address, so whoever paid can close the
|
// Payment banner: this page has a fixed address, so whoever paid can close the
|
||||||
// invoice and follow the deposit here. It asks the server data every 30 seconds
|
// invoice and follow the deposit here. It asks the server data every 30 seconds
|
||||||
@@ -87,6 +211,30 @@
|
|||||||
const paymentStarted = Date.now();
|
const paymentStarted = Date.now();
|
||||||
let paymentTimer = null, paymentSeen = false, paymentAmount = 0, firstExpiry;
|
let paymentTimer = null, paymentSeen = false, paymentAmount = 0, firstExpiry;
|
||||||
|
|
||||||
|
const fmt = n => (n != null ? Number(n).toLocaleString('en-US') : '—');
|
||||||
|
const pad = n => String(n).padStart(2, '0');
|
||||||
|
function fmtTime(d) {
|
||||||
|
return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + ' ' +
|
||||||
|
pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expiry card: the date big, the days left, the renewal window (from 6 months
|
||||||
|
// before expiry, Terms Section 1).
|
||||||
|
function showExpiry(expiryRaw) {
|
||||||
|
const expiry = (expiryRaw || '').slice(0, 10);
|
||||||
|
document.getElementById('weexpiry').textContent = expiry ? 'Expires ' + expiry : 'Not listed';
|
||||||
|
const daysEl = document.getElementById('wedays');
|
||||||
|
const winEl = document.getElementById('wewindow');
|
||||||
|
if (!expiry) { daysEl.textContent = 'No listing time: see the Terms to get listed.'; winEl.textContent = '—'; winEl.className = ''; return; }
|
||||||
|
const exp = new Date(expiry + 'T00:00:00Z');
|
||||||
|
const win = new Date(exp); win.setUTCMonth(win.getUTCMonth() - 6);
|
||||||
|
const days = Math.ceil((exp - Date.now()) / 86400000);
|
||||||
|
daysEl.textContent = days > 0 ? days + ' days of listing left' : 'Listing expired';
|
||||||
|
const open = Date.now() >= win.getTime() && days > 0;
|
||||||
|
winEl.textContent = open ? 'open now' : 'opens on ' + win.toISOString().slice(0, 10);
|
||||||
|
winEl.className = open ? 'open' : '';
|
||||||
|
}
|
||||||
|
|
||||||
function showPayment(text, ok) {
|
function showPayment(text, ok) {
|
||||||
const box = document.getElementById('wepayment');
|
const box = document.getElementById('wepayment');
|
||||||
box.textContent = text;
|
box.textContent = text;
|
||||||
@@ -116,12 +264,10 @@
|
|||||||
if (firstExpiry === undefined) firstExpiry = expiry;
|
if (firstExpiry === undefined) firstExpiry = expiry;
|
||||||
const unconfirmed = Number(data.unconfirmed_balance) > 0;
|
const unconfirmed = Number(data.unconfirmed_balance) > 0;
|
||||||
const active = expiry && new Date(expiry.replace(' ', 'T') + 'Z') > new Date();
|
const active = expiry && new Date(expiry.replace(' ', 'T') + 'Z') > new Date();
|
||||||
const bal = data.balance != null ? data.balance : null;
|
const bal = data.balance != null ? fmt(data.balance) : null;
|
||||||
const unc = data.unconfirmed_balance != null ? data.unconfirmed_balance : null;
|
const unc = data.unconfirmed_balance != null ? fmt(data.unconfirmed_balance) : null;
|
||||||
document.getElementById('webalance').textContent = bal ? (unc ? bal + ' (' + unc + ')' : bal) : '—';
|
document.getElementById('webalance').textContent = bal ? (unc ? bal + ' (' + unc + ')' : bal) : '—';
|
||||||
const expiryCell = document.createElement('b');
|
showExpiry(expiry);
|
||||||
expiryCell.textContent = expiry || '—';
|
|
||||||
document.getElementById('weexpiry').replaceChildren(expiryCell);
|
|
||||||
if (expiry && expiry !== firstExpiry) {
|
if (expiry && expiry !== firstExpiry) {
|
||||||
showPayment('✓ Payment confirmed: this server is now listed.', true);
|
showPayment('✓ Payment confirmed: this server is now listed.', true);
|
||||||
stopPayment();
|
stopPayment();
|
||||||
@@ -147,21 +293,22 @@
|
|||||||
const chain = path[1];
|
const chain = path[1];
|
||||||
const cdate=new Date().toISOString().replace(/[-:T.Z]/g, '').slice(0, 14);
|
const cdate=new Date().toISOString().replace(/[-:T.Z]/g, '').slice(0, 14);
|
||||||
fetchDataAndPopulateTable('/weinfodata/'+chain+"/"+we_id, new URLSearchParams(),(data) => {
|
fetchDataAndPopulateTable('/weinfodata/'+chain+"/"+we_id, new URLSearchParams(),(data) => {
|
||||||
document.getElementById('wename').innerHTML = DOMPurify.sanitize(data.url||'—');
|
document.getElementById('wename').textContent = data.url || '—';
|
||||||
document.getElementById('wechain').innerHTML = DOMPurify.sanitize(data.chain||'—');
|
document.title = (data.url || 'Server') + ' — Will Executor';
|
||||||
document.getElementById('weinfo').innerHTML = DOMPurify.sanitize(data.info||'—');
|
document.getElementById('wechain').textContent = data.chain || chain;
|
||||||
document.getElementById('wefees').innerHTML = data.base_fee != null ? data.base_fee : '—';
|
document.getElementById('weinfo').textContent = data.info || '';
|
||||||
document.getElementById('weheight').innerHTML = data.last_block != null ? data.last_block : '—';
|
document.getElementById('wefees').textContent = fmt(data.base_fee);
|
||||||
document.getElementById('wepoints').innerHTML = data.points != null ? data.points : '—';
|
document.getElementById('weheight').textContent = fmt(data.last_block);
|
||||||
document.getElementById('wewin').innerHTML = data.count_win != null ? data.count_win : '—';
|
document.getElementById('wepoints').textContent = fmt(data.points);
|
||||||
document.getElementById('wetld').innerHTML = DOMPurify.sanitize(data.tld||'—');
|
document.getElementById('wewin').textContent = fmt(data.count_win);
|
||||||
const bal = data.balance != null ? data.balance : null;
|
document.getElementById('wetld').textContent = data.tld || '—';
|
||||||
const unc = data.unconfirmed_balance != null ? data.unconfirmed_balance : null;
|
const bal = data.balance != null ? fmt(data.balance) : null;
|
||||||
document.getElementById('webalance').innerHTML = bal ? (unc ? bal + ' (' + unc + ')' : bal) : '—';
|
const unc = data.unconfirmed_balance != null ? fmt(data.unconfirmed_balance) : null;
|
||||||
document.getElementById('wedonations').innerHTML = data.donation != null ? data.donation : '—';
|
document.getElementById('webalance').textContent = bal ? (unc ? bal + ' (' + unc + ')' : bal) : '—';
|
||||||
document.getElementById('weversion').innerHTML = data.version||'—';
|
document.getElementById('wedonations').textContent = fmt(data.donation);
|
||||||
document.getElementById('weexpiry').innerHTML = '<b>' + (data.expiry_date || '—') + '</b>';
|
document.getElementById('weversion').textContent = data.version || '—';
|
||||||
document.getElementById('weupdate').innerHTML = data.last_update || '—';
|
document.getElementById('weupdate').textContent = data.last_update || '—';
|
||||||
|
showExpiry(data.expiry_date);
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
'OK': 'Health check passed',
|
'OK': 'Health check passed',
|
||||||
'TIMEOUT': 'Connection timeout',
|
'TIMEOUT': 'Connection timeout',
|
||||||
@@ -174,7 +321,8 @@
|
|||||||
'KO': 'Generic error'
|
'KO': 'Generic error'
|
||||||
};
|
};
|
||||||
const st = (data.status||'').split(':')[0];
|
const st = (data.status||'').split(':')[0];
|
||||||
document.getElementById('westatus').innerHTML = statusMap[st] || '—';
|
document.getElementById('westatus').textContent = statusMap[st] || (data.status ? 'Unknown status' : '—');
|
||||||
|
document.getElementById('westatus-badge').className = 'badge ' + (st === 'OK' ? 'ok' : (st ? 'bad' : ''));
|
||||||
|
|
||||||
const tableBody = document.querySelector('#wetimes tbody');
|
const tableBody = document.querySelector('#wetimes tbody');
|
||||||
tableBody.innerHTML ='';
|
tableBody.innerHTML ='';
|
||||||
@@ -182,19 +330,22 @@
|
|||||||
Object.entries(data.times).forEach(([key,wetime]) => {
|
Object.entries(data.times).forEach(([key,wetime]) => {
|
||||||
const row = document.createElement('tr');
|
const row = document.createElement('tr');
|
||||||
const d = new Date(wetime.time/1000);
|
const d = new Date(wetime.time/1000);
|
||||||
|
const hash = DOMPurify.sanitize(wetime.blockHash||'');
|
||||||
|
const short = hash.length > 20 ? hash.slice(0, 10) + '…' + hash.slice(-8) : (hash || '—');
|
||||||
|
const pos = wetime.position != null ? wetime.position + 1 : null;
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${wetime.blockHeight != null ? wetime.blockHeight : '—'}</td>
|
<td class="num">${wetime.blockHeight != null ? fmt(wetime.blockHeight) : '—'}</td>
|
||||||
<td>${DOMPurify.sanitize(wetime.blockHash||'—')}</td>
|
<td class="hash" title="${hash}">${short}</td>
|
||||||
<td>${d}</td>
|
<td>${fmtTime(d)}</td>
|
||||||
<td>${wetime.diff != null ? wetime.diff/1000000 + ' s' : '—'}</td>
|
<td class="num">${wetime.diff != null ? (wetime.diff/1000000).toFixed(3) + ' s' : '—'}</td>
|
||||||
<td>${wetime.position != null ? wetime.position+1 : '—'}</td>
|
<td class="num ${pos === 1 ? 'pos-1' : ''}">${pos != null ? '#' + pos : '—'}</td>
|
||||||
<td>${wetime.participants != null ? wetime.participants : '—'}</td>
|
<td class="num">${wetime.participants != null ? wetime.participants : '—'}</td>
|
||||||
<td>${wetime.points != null ? wetime.points : '—'}</td>
|
<td class="num">${wetime.points != null ? wetime.points : '—'}</td>
|
||||||
`;
|
`;
|
||||||
tableBody.appendChild(row);
|
tableBody.appendChild(row);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
tableBody.innerHTML = '<tr><td colspan="7" style="padding:20px;text-align:center;color:#999">No rounds yet.</td></tr>';
|
tableBody.innerHTML = '<tr><td colspan="7" style="padding:24px;text-align:center;color:var(--muted)">No rounds yet.</td></tr>';
|
||||||
}
|
}
|
||||||
var prev=0;
|
var prev=0;
|
||||||
var next=0;
|
var next=0;
|
||||||
|
|||||||
Reference in New Issue
Block a user