67f43b68ca
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
72 lines
5.7 KiB
HTML
72 lines
5.7 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Leaderboard · PolHunter</title>
|
||
<meta name="description" content="The hunters with the most finds this week, this month and all time. Every drip is on Polygon.">
|
||
<link rel="stylesheet" href="/style.css?v=11">
|
||
</head>
|
||
<body>
|
||
<div class="wrap">
|
||
<header class="top">
|
||
<a class="mark" href="/"><span class="coin"></span>PolHunter</a>
|
||
<nav class="nav">
|
||
<a class="btn ghost sm" href="/promo">Promo tools</a>
|
||
<a class="btn ghost sm" href="/#how">How it works</a>
|
||
<a class="btn sm" href="https://instantadpay.com/api/my/polhunter">Open my board</a>
|
||
</nav>
|
||
</header>
|
||
|
||
<section class="section" style="padding-top:14px">
|
||
<h2>Leaderboard</h2>
|
||
<div class="sub">Most finds wins. Ties go to the most POL, then to whoever got there first.</div>
|
||
<div class="notice" id="prizes" style="margin:12px 0"></div>
|
||
<div class="tabs" id="tabs"><button class="tab on" data-p="week">This week</button><button class="tab" data-p="month">This month</button><button class="tab" data-p="all">All time</button></div>
|
||
<div class="notice" id="mine" style="display:none;margin:12px 0"></div>
|
||
<div class="ledger" id="rows"><div class="row"><span class="site">Loading…</span></div></div>
|
||
<p class="small" style="margin-top:14px">Weeks run Monday to Sunday, Central time. The company account is not listed.</p>
|
||
</section>
|
||
|
||
<section class="section" id="winners" style="display:none">
|
||
<h2>Last week’s winners</h2>
|
||
<div class="sub" id="winsub"></div>
|
||
<div class="ledger" id="winrows"></div>
|
||
</section>
|
||
|
||
<section class="section">
|
||
<h2>Badges</h2>
|
||
<div class="sub">Earned automatically from your finds. They show next to your name up there and on your board.</div>
|
||
<div class="badge-strip" id="badges"></div>
|
||
</section>
|
||
|
||
<div class="adslot" data-ad="leaders"><!-- nas: 468x60 on phones, 728x90 on wider screens --><script>(function(){var m=window.innerWidth<600;document.write('<scr'+'ipt src="https://www.networkadspace.com/showadss.php?'+(m?'w=468&h=60&n=1&bw=468&bh=60':'w=728&h=90&n=1&bw=728&bh=90')+'&c=999"></scr'+'ipt>');})();</script></div>
|
||
|
||
<footer class="foot">PolHunter rewards completed missions. Rewards are not income and are not guaranteed. Cryptocurrency involves risk of loss. <br><a href="https://instantadpay.com">InstantAdPay</a></footer>
|
||
</div>
|
||
<script>
|
||
(async () => {
|
||
const esc = s => String(s == null ? '' : s).replace(/[&<>"]/g, c => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c]));
|
||
const medal = r => r === 1 ? '\u{1F947}' : r === 2 ? '\u{1F948}' : r === 3 ? '\u{1F949}' : '#' + r;
|
||
let me = null; try { const r = await fetch('/api/my/board'); if (r.ok) me = await r.json(); } catch (e) {}
|
||
async function show(period) {
|
||
document.querySelectorAll('.tab').forEach(t => t.classList.toggle('on', t.dataset.p === period));
|
||
const r = await (await fetch('/api/leaders?period=' + period)).json();
|
||
document.getElementById('rows').innerHTML = r.rows.length ? r.rows.map(x => '<div class="row lb' + (me && me.me && x.memberId === me.me.memberId ? ' me' : '') + '"><span><b class="num">' + medal(x.rank) + '</b> ' + esc(x.who) + ' <span class="badges">' + x.badges.join(' ') + '</span></span><span class="site">' + x.finds + ' find' + (x.finds === 1 ? '' : 's') + '</span><span class="pol">' + x.pol + ' POL</span></div>').join('')
|
||
: '<div class="row"><span class="site">No finds yet in this period. The first hunter gets the top line.</span></div>';
|
||
if (me && me.rank && me.rank[period]) { const k = me.rank[period]; document.getElementById('mine').style.display = 'block'; document.getElementById('mine').innerHTML = '<b>You are #' + k.rank + ' of ' + k.of + '</b> ' + (period === 'all' ? 'all time' : period === 'month' ? 'this month' : 'this week') + ' with ' + k.finds + ' find' + (k.finds === 1 ? '' : 's') + ' and ' + k.pol + ' POL.'; }
|
||
else if (me) { document.getElementById('mine').style.display = 'block'; document.getElementById('mine').innerHTML = 'You are not on this board yet. One find puts you on it. <a href="/app">Open your board</a>.'; }
|
||
}
|
||
document.querySelectorAll('.tab').forEach(t => t.addEventListener('click', () => show(t.dataset.p)));
|
||
try { const pz = await (await fetch('/api/prizes')).json(); const pol = pz.rules.pol;
|
||
document.getElementById('prizes').innerHTML = '<b>Weekly prizes:</b> ' + pol.map((v, i) => medal(i + 1) + ' ' + v + ' POL').join(' \u00b7 ') + ' for the top ' + pol.length + ' with ' + pz.rules.minFinds + '+ finds. Paid to your wallet Monday after midnight Central. Weekly #1 also earns the Top Hunter badge.';
|
||
if (pz.last && pz.last.winners.length) { document.getElementById('winners').style.display = 'block'; document.getElementById('winsub').textContent = 'Week of ' + pz.last.week + '.'; document.getElementById('winrows').innerHTML = pz.last.winners.map(w => '<div class="row lb"><span><b class="num">' + medal(w.rank) + '</b> ' + esc(w.who) + '</span><span class="site">' + w.finds + ' finds</span><span class="pol">+' + w.prizePol + ' POL prize</span></div>').join(''); }
|
||
} catch (e) {}
|
||
const b = await (await fetch('/api/badges')).json();
|
||
document.getElementById('badges').innerHTML = b.badges.map(x => { const got = me && me.badges && me.badges.some(y => y.id === x.id); return '<div class="badge-a' + (got ? '' : ' locked') + '"><img src="' + x.art + '" alt="' + esc(x.name) + '" loading="lazy"><div class="bl">' + x.icon + ' ' + esc(x.name) + '</div><div class="bs">' + esc(x.why) + '</div>' + (got ? '<p style="margin-top:8px"><span class="tag done">Earned</span></p>' : '') + '</div>'; }).join('');
|
||
show('week');
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|