Back-office polish: Overview command center, quick actions, pane motion
Overview gains a recent-activity mini-feed (chain events + line joins) and a quick-actions card jumping straight to buy/earn/campaigns plus one-tap invite copy. Panes fade in (reduced-motion safe). First slice of the back-office polish pass. Assets v=20260905f. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,28 @@
|
||||
+ '<td><span class="badge' + (r.status === 'joined free' ? ' amber' : '') + '">' + r.status + '</span></td></tr>').join('');
|
||||
wrap.appendChild(t);
|
||||
}
|
||||
// overview recent-activity widget: chain events + line joins, newest first
|
||||
try {
|
||||
const c = await IAP.getConfig();
|
||||
const ov = $('ovFeed');
|
||||
const rows = [];
|
||||
if (d.memberId) {
|
||||
const a = await (await fetch('/api/my/activity')).json();
|
||||
for (const ev of [...(a.earnings || []), ...(a.purchases || [])]
|
||||
.sort((x, y) => y.block - x.block).slice(0, 5)) rows.push(IAP.feedRow(ev, c));
|
||||
}
|
||||
for (const r of (d.referrals || []).slice(0, 3)) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'row';
|
||||
div.innerHTML = '<span>🤝 ' + r.email + ' joined your line</span><span class="tx muted small">'
|
||||
+ new Date(r.joined).toLocaleDateString() + '</span>';
|
||||
rows.push(div);
|
||||
}
|
||||
if (rows.length) {
|
||||
ov.innerHTML = '';
|
||||
rows.slice(0, 6).forEach(r => ov.appendChild(r));
|
||||
}
|
||||
} catch (e) {}
|
||||
// ready-to-send share message
|
||||
const link = location.origin + '/join/' + (d.refCode || d.memberId || '');
|
||||
if (d.refCode || d.memberId) {
|
||||
@@ -85,6 +107,15 @@
|
||||
}
|
||||
document.querySelectorAll('.bo-menu [data-pane]').forEach(b =>
|
||||
b.addEventListener('click', () => setPane(b.dataset.pane)));
|
||||
document.querySelectorAll('.qa [data-goto]').forEach(b =>
|
||||
b.addEventListener('click', () => setPane(b.dataset.goto)));
|
||||
const qaCopy = document.getElementById('qaCopyInvite');
|
||||
if (qaCopy) qaCopy.addEventListener('click', async () => {
|
||||
const link = document.getElementById('inviteLine').textContent;
|
||||
if (!link || !link.startsWith('http')) { setPane('line'); return; }
|
||||
try { await navigator.clipboard.writeText(link); IAP.status('Invite link copied.', 'ok'); }
|
||||
catch (e) { setPane('line'); }
|
||||
});
|
||||
window.addEventListener('hashchange', () => setPane(location.hash.slice(1)));
|
||||
if ($('boBurger')) $('boBurger').addEventListener('click', () =>
|
||||
document.getElementById('memberArea').classList.toggle('side-open'));
|
||||
|
||||
@@ -257,6 +257,16 @@ input:focus,select:focus{border-color:var(--mint)}
|
||||
#boBurger{display:block}
|
||||
.bo-content{padding:18px}
|
||||
}
|
||||
/* back-office polish: pane transitions, quick actions */
|
||||
@media(prefers-reduced-motion:no-preference){
|
||||
.pane:not([hidden]){animation:panein .25s ease}
|
||||
@keyframes panein{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
|
||||
}
|
||||
.qa{display:flex;flex-direction:column;gap:8px}
|
||||
.qa button{display:flex;align-items:center;gap:10px;background:rgba(67,232,195,.05);border:1px solid var(--line);
|
||||
color:var(--ink);font:600 14px var(--disp);padding:11px 14px;border-radius:11px;cursor:pointer;text-align:left;
|
||||
transition:border-color .15s ease,background .15s ease}
|
||||
.qa button:hover{border-color:var(--mint);background:rgba(67,232,195,.1)}
|
||||
/* member sub-navigation */
|
||||
.subnav{display:flex;gap:6px;flex-wrap:wrap;background:rgba(16,28,24,.7);border:1px solid var(--line);
|
||||
border-radius:999px;padding:6px 8px;width:fit-content;margin:0 0 22px}
|
||||
|
||||
Reference in New Issue
Block a user