Files
plm-lottery/app/static/admin.html
T

165 lines
6.7 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>PLM Lottery — Admin</title>
<link rel="icon" type="image/svg+xml" href="/logo.svg">
<link rel="stylesheet" href="/admin.css">
</head>
<body>
<section id="login-section">
<header>
<h1>PLM Lottery — Admin</h1>
<p>Accesso riservato</p>
</header>
<div class="card">
<label for="admin-token">Admin token</label>
<input id="admin-token" type="password" placeholder="valore di ADMIN_TOKEN" autofocus>
<button onclick="adminLogin()" id="login-btn">Accedi</button>
</div>
</section>
<div id="dashboard-section" class="hidden">
<nav class="navbar">
<span class="brand">PLM Lottery — Admin</span>
<span class="nav-tab active" id="nav-parametri" onclick="switchView('parametri')">Parametri</span>
<span class="nav-tab" id="nav-utenti" onclick="switchView('utenti')">Utenti</span>
<span class="nav-tab" id="nav-round" onclick="switchView('round')">Round</span>
<span class="nav-tab" id="nav-pending" onclick="switchView('pending')">Transazioni pendenti</span>
<span class="nav-tab" id="nav-audit" onclick="switchView('audit')">Audit log</span>
<span class="spacer"></span>
<span class="chain-status-pill">
<span class="status-dot" id="chain-status-dot"></span>
<span id="chain-status-label">Connessione…</span>
</span>
<span class="chain-block mono" id="chain-block">Blocco —</span>
<button class="secondary" style="margin:8px 0 8px 14px" onclick="adminLogout()">Esci</button>
</nav>
<main>
<div class="view active" id="view-parametri">
<h2 class="section-title">Parametri</h2>
<p class="hint">Configurazione operativa, salvata nel database — modificabile in qualsiasi momento senza riavviare il server.</p>
<div class="card" id="maintenance-card">
<h2>Manutenzione</h2>
<p class="hint" id="maintenance-hint">
Interrompe l'apertura di nuovi round dopo quello in corso, senza troncare il round attuale — chiusura,
estrazione e pagamento del vincitore avvengono normalmente. Gli utenti vedono un avviso di manutenzione.
</p>
<div class="row-between">
<span class="chain-status-pill">
<span class="status-dot" id="maintenance-dot"></span>
<span id="maintenance-status-label"></span>
</span>
<button id="maintenance-btn" class="secondary" style="width:auto;margin-top:0" onclick="toggleMaintenance()"></button>
</div>
</div>
<div class="card">
<div class="grid-2">
<div>
<label for="admin-fee-address">Fee address (dove finisce il 30% di ogni round)</label>
<input id="admin-fee-address" class="mono" placeholder="plm1q...">
<label for="admin-bet-amount">Bet amount (PLM)</label>
<input id="admin-bet-amount" inputmode="decimal" placeholder="es. 10">
</div>
<div>
<label for="admin-round-duration">Durata round (secondi)</label>
<input id="admin-round-duration" inputmode="numeric" placeholder="es. 600">
<label for="admin-round-cooldown">Pausa tra un round e il successivo (secondi)</label>
<input id="admin-round-cooldown" inputmode="numeric" placeholder="es. 30">
<label for="admin-draw-animation">Durata animazione estrazione (secondi)</label>
<input id="admin-draw-animation" inputmode="numeric" placeholder="es. 20">
<label for="admin-fee-rate">Fee rate di rete (sat/vB)</label>
<input id="admin-fee-rate" inputmode="numeric" placeholder="es. 1">
<label for="admin-rbf-timeout">Timeout prima del fee-bump RBF (secondi)</label>
<input id="admin-rbf-timeout" inputmode="numeric" placeholder="es. 900">
</div>
</div>
<button onclick="adminSave()" id="save-btn">Salva</button>
</div>
</div>
<div class="view" id="view-utenti">
<h2 class="section-title">Utenti</h2>
<p class="hint">Elenco utenti registrati, con saldo interno, accesso alla chiave privata per interventi manuali (es. restituire fondi bloccati) e reset password per chi resta bloccato fuori dall'account.</p>
<div class="warning-banner">
⚠ La chiave privata dà accesso completo ai fondi dell'utente: ogni visualizzazione viene registrata nell'audit log, non condividerla né salvarla altrove. La password esistente di un utente non è mai recuperabile (è salvata solo come hash Argon2) — "Reset" ne genera una nuova al posto della vecchia, anche questo audit-loggato.
</div>
<div class="card">
<div class="table-wrap">
<table>
<thead>
<tr><th>ID</th><th>Username</th><th>Indirizzo</th><th>Saldo (PLM)</th><th>Registrato</th><th>Chiave</th><th>Password</th></tr>
</thead>
<tbody id="users-tbody"></tbody>
</table>
</div>
</div>
</div>
<div class="view" id="view-round">
<h2 class="section-title">Round</h2>
<p class="hint">Ultimi round: stato, vincitore, importi e transazione di payout.</p>
<div class="card">
<div class="table-wrap">
<table>
<thead>
<tr><th>ID</th><th>Stato</th><th>Apertura</th><th>Vincitore</th><th>Pool (PLM)</th><th>Vincita (PLM)</th><th>Fee (PLM)</th><th>Payout txid</th></tr>
</thead>
<tbody id="rounds-tbody"></tbody>
</table>
</div>
</div>
</div>
<div class="view" id="view-pending">
<h2 class="section-title">Transazioni pendenti</h2>
<p class="hint">Bet, payout e prelievi non ancora confermati — candidati al fee-bump RBF se scade il timeout.</p>
<div class="card">
<div class="table-wrap">
<table>
<thead>
<tr><th>ID</th><th>Tipo</th><th>Stato</th><th>Txid</th><th>Fee rate</th><th>Tentativi</th><th>Trasmessa</th></tr>
</thead>
<tbody id="pending-tbody"></tbody>
</table>
</div>
</div>
</div>
<div class="view" id="view-audit">
<h2 class="section-title">Audit log</h2>
<p class="hint">Ultimi eventi registrati dal sistema (config, bet, payout, accessi a chiavi private, ecc.).</p>
<div class="card">
<div class="table-wrap">
<table>
<thead>
<tr><th>ID</th><th>Evento</th><th>Dettagli</th><th>Utente</th><th>Round</th><th>Quando</th></tr>
</thead>
<tbody id="audit-tbody"></tbody>
</table>
</div>
</div>
</div>
</main>
</div>
<div id="toast-container" aria-live="polite"></div>
<script src="/admin.js"></script>
</body>
</html>