Admin: move the bonus panel inside the admin view and collapse it

It was sitting between the login panel and #adminView — outside the admin
view entirely, so it rendered above the page header and showed on the login
screen to anyone who loaded /admin.

Now it sits after the Coaching Radar, which is the panel that tells you who
needs a nudge; this is the lever for nudging them. Collapsed by default and
the log is capped at a scrollable 240px, because awarding is occasional and
the log grows every month.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-08-30 06:11:41 -05:00
parent 77dcda6a1a
commit ee87408dec
+1 -23
View File
@@ -1,34 +1,12 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="robots" content="noindex,nofollow"><title>RM Circle Team Build Admin</title><link rel="icon" type="image/png" href="/favicon.png"><link rel="stylesheet" href="/styles.css"></head><body class="admin-bg">
<section id="loginView" class="login-panel"><div class="brand" style="margin-bottom:22px"><img class="brand-mark" src="/logo.jpg" alt="The RM Circle" width="42" height="42"><span>RM Circle<small>Sponsor Router Admin</small></span></div><h1>Team Admin</h1><p>Manage the current sponsor, qualification queue, and onboarding settings.</p><form id="loginForm"><div class="field"><label for="password">Admin password</label><input id="password" class="input" type="password" autocomplete="current-password" required></div><button class="btn btn-primary" style="width:100%">Sign in</button><div id="loginError" class="micro" style="color:var(--danger)"></div></form></section>
<section class="card" style="margin-bottom:18px">
<h2 style="margin:0">Award Suite Capacity</h2>
<p class="muted" style="margin:6px 0 12px;font-size:13.5px">
Give any registered position extra Suite capacity as a team bonus. It sits on top of whatever their level
already allows, expires with the month like every other allowance, and shows on their side as coming from
&ldquo;the team&rdquo;. Nothing is deducted from anyone &mdash; this is issued, not transferred.
</p>
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end">
<label style="font-size:12px">Position<br><input id="agTo" type="number" min="1" placeholder="46" style="width:110px"></label>
<label style="font-size:12px">What<br><select id="agTool" style="min-width:180px"></select></label>
<label style="font-size:12px">How much<br><input id="agN" type="number" min="1" step="500" value="5000" style="width:130px"></label>
<label style="font-size:12px;flex:1;min-width:200px">Reason (shown in the log)<br><input id="agNote" type="text" maxlength="80" placeholder="Launch bonus" style="width:100%"></label>
<button id="agGo" class="btn btn-primary">Award it</button>
</div>
<div id="agMsg" style="margin-top:10px;font-size:14px"></div>
<div style="margin-top:14px">
<div class="muted" style="font-size:12px;text-transform:uppercase;letter-spacing:1px">Bonuses awarded this month</div>
<div class="table-wrap"><table style="width:100%;border-collapse:collapse;font-size:13.5px" id="agLogTbl">
<thead><tr><th style="text-align:left">To</th><th style="text-align:left">What</th><th style="text-align:left">Amount</th><th style="text-align:left">Reason</th><th style="text-align:left">When</th></tr></thead>
<tbody id="agLog"></tbody></table></div>
</div>
</section>
<section id="adminView" class="admin hidden"><div class="admin-top"><div><div class="eyebrow">Sponsor router</div><h1>RM Circle Team Build Admin</h1></div><div class="nav-actions"><a class="btn btn-secondary" href="/start" target="_blank">View Live Page ↗</a><button id="logoutBtn" class="btn btn-secondary">Log out</button></div></div>
<div class="admin-grid"><div class="stack"><div class="table-card"><div style="display:flex;justify-content:space-between;gap:12px;align-items:center;margin-bottom:12px"><div><h2 style="margin:0">Sponsor Queue</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">Mark a sponsor qualified to automatically activate the next waiting position.</p></div></div><div class="table-wrap"><table class="table"><thead><tr><th>Order</th><th>Sponsor</th><th>Parent</th><th>Directs</th><th>Level</th><th>Status</th><th>Clicks</th><th>Actions</th></tr></thead><tbody id="sponsorRows"></tbody></table></div></div>
<div class="table-card"><div style="margin-bottom:12px"><h2 style="margin:0">Traffic &amp; Conversions</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">First-touch source per visitor session (referring domain or utm_source). Funnel: bridge page → start page → join click.</p></div><div id="funnelStats" class="funnel"></div><div class="table-wrap"><table class="table"><thead><tr><th>Source</th><th>Bridge views</th><th>Start views</th><th>Training views</th><th>Invite views</th><th>Join-now views</th><th>Join clicks</th><th>Confirmed</th><th>Start → Join</th></tr></thead><tbody id="trafficRows"></tbody></table></div></div>
<div class="table-card"><div style="margin-bottom:12px"><h2 style="margin:0">Member ID Submissions</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">New members who confirmed their purchase on the start page. Each one was posted to your Hermes Telegram chat — add them to the rotation.</p></div><div class="table-wrap"><table class="table"><thead><tr><th>When</th><th>Name / Handle</th><th>New ID</th><th>Joined under</th><th>Source</th><th>On-chain</th></tr></thead><tbody id="submissionRows"></tbody></table></div></div>
<div class="table-card"><div style="display:flex;justify-content:space-between;gap:12px;align-items:center;margin-bottom:12px;flex-wrap:wrap"><div><h2 style="margin:0">Your Organization vs. the Network</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">How your team — rooted at your top ID — stacks up against the entire RM Circle smart contract. Live on-chain.</p></div><form id="orgShareForm" style="display:flex;gap:8px"><input id="orgRoot" class="input" style="max-width:110px" placeholder="21" inputmode="numeric"><button class="btn btn-secondary btn-sm">Refresh</button></form></div><div id="orgShare"><div class="empty">Reading the blockchain…</div></div></div>
<div class="table-card"><div style="display:flex;justify-content:space-between;gap:12px;align-items:center;margin-bottom:12px;flex-wrap:wrap"><div><h2 style="margin:0">Coaching Radar</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">Live triage of your whole org: who to nudge, what to tell them, and how much POL is on the line. Computed fresh from the chain index on every refresh.</p></div><button id="coachRefresh" class="btn btn-secondary btn-sm">Refresh</button></div><div id="coachOut"><div class="empty">Loading…</div></div></div>
<details class="table-card" id="grantCard"><summary style="cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:12px"><span><h2 style="margin:0;display:inline">Award Suite Capacity</h2><span style="color:var(--muted);font-size:13px;display:block;margin-top:4px">Give any position extra Suite allowance as a team bonus — issued by the team, not taken from anyone.</span></span><span class="btn btn-secondary btn-sm" style="flex:none;pointer-events:none">Open</span></summary><div style="margin-top:14px"><div style="display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end"><label style="font-size:12px">Position<br><input id="agTo" class="input" type="number" min="1" placeholder="46" style="width:110px"></label><label style="font-size:12px">What<br><select id="agTool" class="select" style="min-width:180px"></select></label><label style="font-size:12px">How much<br><input id="agN" class="input" type="number" min="1" step="500" value="5000" style="width:130px"></label><label style="font-size:12px;flex:1;min-width:180px">Reason (shown in the log)<br><input id="agNote" class="input" type="text" maxlength="80" placeholder="Launch bonus"></label><button id="agGo" class="btn btn-primary">Award it</button></div><div id="agMsg" style="margin-top:10px;font-size:14px"></div><div style="margin-top:14px"><div style="color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:1px;margin-bottom:6px">Bonuses awarded this month</div><div class="table-wrap" style="max-height:240px"><table class="table" style="min-width:520px"><thead><tr><th>To</th><th>What</th><th>Amount</th><th>Reason</th><th>When</th></tr></thead><tbody id="agLog"></tbody></table></div></div></div></details>
<div class="table-card"><div style="display:flex;justify-content:space-between;gap:12px;align-items:center;margin-bottom:12px;flex-wrap:wrap"><div><h2 style="margin:0">Member Messages</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">Wallet-verified member-to-member messages, newest first. Admin can review for abuse — members are told this in the UI.</p></div><button id="msgRefresh" class="btn btn-secondary btn-sm">Refresh</button></div><div class="table-wrap"><table class="table"><thead><tr><th>When</th><th>From</th><th>To</th><th>Message</th><th>Read by</th></tr></thead><tbody id="msgRows"><tr><td colspan="5" class="empty">Loading…</td></tr></tbody></table></div></div>
<div class="table-card"><div style="margin-bottom:12px"><h2 style="margin:0">My Positions — Income</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">Every payment received by your own positions, live from the contract. Comma-separated IDs — saved for next time.</p></div><form id="incomeForm" style="display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap"><input id="incomeIds" class="input" style="max-width:260px" placeholder="21,24,25" inputmode="numeric"><button class="btn btn-teal">Load</button></form><div id="incomeAlert"></div><div id="incomeRouting" style="margin-bottom:14px"></div><div id="incomeSummary" class="facts" style="grid-template-columns:repeat(4,1fr);margin-bottom:12px"></div><div id="incomeResult"></div></div>
<div class="table-card"><div style="margin-bottom:12px"><h2 style="margin:0">On-Chain Member Lookup</h2><p style="color:var(--muted);margin:4px 0 0;font-size:13px">Enter an RM Circle ID to read its registration, lineage, and every payment it has received — live from the smart contract.</p></div><form id="lookupForm" style="display:flex;gap:10px;margin-bottom:14px"><input id="lookupId" class="input" style="max-width:220px" placeholder="Member ID e.g. 46" inputmode="numeric"><button class="btn btn-teal">Look Up</button></form><div id="lookupResult"></div></div>