diff --git a/app/main.py b/app/main.py index a8223fb..a12a3f4 100644 --- a/app/main.py +++ b/app/main.py @@ -292,7 +292,8 @@ PAGE_HTML = """
—
members
—
active
-
—
total spend
+
—
sp since reset
+
—
all-time spend
@@ -318,7 +319,7 @@ PAGE_HTML = """ Source Allowance Credits - Spend + Spend (since reset) Remaining Reset Adjust @@ -376,7 +377,8 @@ async function load() { const d = await r.json(); $('tot-members').textContent = d.totals.members; $('tot-active').textContent = d.totals.active; - $('tot-spend').textContent = fmt(d.totals.total_spend); + $('tot-spend-cycle').textContent = fmt(d.totals.total_spend); + $('tot-spend-all').textContent = fmt(d.totals.total_all_time_spend ?? d.totals.total_spend); membersData = d.members || []; if (currentView === 'members') renderMembers(); } catch (e) { @@ -391,6 +393,7 @@ let currentView = 'members'; let memberSort = { key: 'email', dir: 1 }; let modelSort = { key: 'spend', dir: -1 }; let rangeDays = 0; // 0 = all time +let spendMode = 'cycle'; // 'cycle' | 'all' — Spend column in Members view (cycle = since the member's own reset) function arrowFor(key, sortState) { if (sortState.key !== key) return ''; @@ -427,11 +430,21 @@ function setRange(days) { } function sortMembers(key) { + // Clicking the Spend header toggles the value shown (since-reset ↔ all-time) + // before sorting; other headers just sort. + if (key === 'spend') { + spendMode = spendMode === 'cycle' ? 'all' : 'cycle'; + $('spend-mode-label').textContent = spendMode === 'cycle' ? 'since reset' : 'all-time'; + } memberSort = { key, dir: memberSort.key === key ? -memberSort.dir : 1 }; clearArrows('members', memberSort); render(); } +function memberSpend(m) { + return spendMode === 'all' ? (m.all_time_spend ?? m.spend ?? 0) : (m.spend ?? 0); +} + function sortModels(key) { modelSort = { key, dir: modelSort.key === key ? -modelSort.dir : -1 }; clearArrows('models', modelSort); @@ -446,6 +459,7 @@ function render() { function renderMembers() { const rows = [...membersData].sort((a, b) => { let va = a[memberSort.key], vb = b[memberSort.key]; + if (memberSort.key === 'spend') { va = memberSpend(a); vb = memberSpend(b); } if (memberSort.key === 'active' || memberSort.key === 'activated') { va = va ? 1 : 0; vb = vb ? 1 : 0; } if (typeof va === 'string' || typeof vb === 'string') { return String(va ?? '').localeCompare(String(vb ?? '')) * memberSort.dir; @@ -472,7 +486,7 @@ function renderMembers() { '' + src + '' + '' + fmt(m.balance) + '' + '' + creditsPill + '' + - '' + fmt(m.spend) + '' + + '' + fmt(memberSpend(m)) + '' + '' + fmt(m.remaining) + '' + '' + esc(reset) + '' + '
' +