git / moonbite-network / templates/leaderboard.html · raw
{% extends "base.html" %} {% block body_class %}mb-v2{% endblock %} {% block title %}Mining Leaderboard - MoonBite{% endblock %} {% block nav_active %}mining{% endblock %} {% block content %} <div class="main-content"> <section class="hero"> <h2> Mining Leaderboard</h2> <p>Top miners earning MoonBite blocks</p> </section> <!-- Period Selector --> <div class="cards-grid"> <button class="mb-period-btn active" data-period="week"> This Week </button> <button class="mb-period-btn" data-period="all"> All Time </button> </div> <!-- Leaderboard Table --> <div class="card card-full"> <div class="card-header">Top Miners</div> <div class="card-body"> <table class="mb-leaderboard-table"> <thead> <tr> <th>Rank</th> <th>Miner Address</th> <th>Blocks Mined</th> <th>MBITE Earned</th> </tr> </thead> <tbody id="leaderboardBody"> <tr><td colspan="4" style="text-align: center; padding: 2rem;">Loading...</td></tr> </tbody> </table> </div> </div> <!-- Your Rank --> <div class="card card-full hidden" id="yourRankCard"> <div class="card-header">Your Mining Stats</div> <div class="card-body"> <div class="mb-stats-grid"> <div> <div class="mb-stats-label">Your Rank</div> <div class="mb-stats-value" id="yourRank">--</div> </div> <div> <div class="mb-stats-label">Blocks Mined</div> <div class="mb-stats-value" id="yourBlocks">0</div> </div> <div> <div class="mb-stats-label">MBITE Earned</div> <div class="mb-stats-value" id="yourMBITE">0</div> </div> </div> </div> </div> <!-- Info --> <div class="card card-full"> <div class="card-header">How It Works</div> <div class="card-body"> <ul class="info-list"> <li>Every block mined earns 10 MBITE for the miner</li> <li>Leaderboard updates in real-time as blocks are mined</li> <li>Top miners compete for prestige and rewards</li> <li>Difficulty adjusts every 60 blocks to keep the 2-min block time</li> </ul> </div> </div> </div> {% endblock %} {% block scripts_extra %} <script nonce="{{ csp_nonce }}"> async function loadLeaderboard(period) { try { // Update active button document.querySelectorAll('.mb-period-btn').forEach(btn => { btn.classList.remove('active'); }); event.target.classList.add('active'); // Fetch leaderboard from extended mining/status endpoint const response = await fetch(`/api/mining/status?include=leaderboard`); const data = await response.json(); if (data.status === 'success') { const tbody = document.getElementById('leaderboardBody'); tbody.innerHTML = ''; data.leaderboard.forEach((miner, index) => { const mbite = miner.blocks * 50; const row = document.createElement('tr'); row.innerHTML = ` <td class="mb-rank">${index + 1}</td> <td class="mb-address" title="${miner.address}"> ${miner.address.substring(0, 20)}... </td> <td class="mb-blocks">${miner.blocks}</td> <td class="mb-mbite">${mbite.toLocaleString()}</td> `; tbody.appendChild(row); }); // Check if current user is in leaderboard (mock for now) // In production, would compare with user's mining address } } catch (error) { console.error('Error loading leaderboard:', error); document.getElementById('leaderboardBody').innerHTML = '<tr><td colspan="4" style="text-align: center; color: var(--text-secondary);">Error loading leaderboard</td></tr>'; } } // Load on page load document.addEventListener('DOMContentLoaded', () => { loadLeaderboard('week'); }); document.addEventListener('click', function (e) { var el = e.target.closest && e.target.closest('[data-period]'); if (el) loadLeaderboard(el.getAttribute('data-period')); }); </script> {% endblock %}