Add a maintenance pause/resume switch and a proper user navbar
RoundConfig gets a paused flag toggled via new POST /admin/pause and /admin/resume endpoints (audit-logged, surfaced as a "Manutenzione" card in the admin Parametri view). Pausing only stops the *next* round from opening once the current one closes — rounds/service.py:open_new_round_if_needed still lets an in-progress round finish, draw, and pay out its winner normally. GET /rounds/current exposes lottery_paused so the user page shows a maintenance banner (even while logged out) instead of silently going idle. Also replaces the user dashboard's stacked account-bar card + bento-grid menu with a single sticky navbar (identity row + Deposito/Bet/Prelievo tabs), and moves the page content into a dedicated .app-shell container so the navbar itself can span full width.
This commit is contained in:
@@ -77,6 +77,12 @@
|
||||
}
|
||||
.chain-block { color: var(--color-muted-foreground); font-size: 0.82rem; white-space: nowrap; }
|
||||
|
||||
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
||||
#maintenance-btn.btn-stop {
|
||||
background: var(--color-destructive-bg); color: var(--color-destructive); border-color: var(--color-destructive);
|
||||
}
|
||||
.status-dot.status-paused { background: var(--color-destructive); }
|
||||
|
||||
main { max-width: 960px; margin: 0 auto; padding: 24px 20px 80px; }
|
||||
|
||||
.view { display: none; }
|
||||
@@ -221,6 +227,21 @@
|
||||
<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>
|
||||
@@ -460,11 +481,53 @@ async function adminLoadConfig() {
|
||||
document.getElementById('admin-min-amount').value = data.min_amount_sats / SATS_PER_PLM;
|
||||
document.getElementById('admin-fee-rate').value = data.fee_rate_sat_vb;
|
||||
document.getElementById('admin-rbf-timeout').value = data.rbf_timeout_seconds;
|
||||
renderMaintenanceState(data.paused);
|
||||
} catch (e) {
|
||||
toast('Errore nel caricamento configurazione: ' + e.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function renderMaintenanceState(paused) {
|
||||
const dot = document.getElementById('maintenance-dot');
|
||||
const label = document.getElementById('maintenance-status-label');
|
||||
const btn = document.getElementById('maintenance-btn');
|
||||
btn.dataset.paused = paused ? '1' : '0';
|
||||
if (paused) {
|
||||
dot.className = 'status-dot status-paused';
|
||||
label.textContent = 'In pausa: nessun nuovo round verrà aperto';
|
||||
btn.textContent = 'Riprendi lotteria';
|
||||
btn.classList.remove('btn-stop');
|
||||
} else {
|
||||
dot.className = 'status-dot status-open';
|
||||
label.textContent = 'Attiva: i round si susseguono normalmente';
|
||||
btn.textContent = 'Interrompi dopo questo round';
|
||||
btn.classList.add('btn-stop');
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleMaintenance() {
|
||||
const btn = document.getElementById('maintenance-btn');
|
||||
const isPaused = btn.dataset.paused === '1';
|
||||
const path = isPaused ? '/admin/resume' : '/admin/pause';
|
||||
if (!isPaused && !window.confirm(
|
||||
"Nessun nuovo round verrà aperto dopo quello in corso, fino a quando non riprendi la lotteria. " +
|
||||
"Il round attuale (se presente) verrà comunque completato e il vincitore pagato. Continuare?"
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
btn.disabled = true;
|
||||
try {
|
||||
const data = await callAdmin('POST', path, {});
|
||||
renderMaintenanceState(data.paused);
|
||||
toast(data.paused ? 'Lotteria in pausa.' : 'Lotteria ripresa.', 'success');
|
||||
refreshChainStatus();
|
||||
} catch (e) {
|
||||
toast('Errore: ' + e.message, 'error');
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function adminSave() {
|
||||
const btn = document.getElementById('save-btn');
|
||||
const feeAddress = document.getElementById('admin-fee-address').value;
|
||||
|
||||
Reference in New Issue
Block a user