Dashboard: let members see what a nudge actually says before and after sending
A member sent a nudge to #102, then went looking for what had gone out. The only feedback was a small "Delivered to their dashboard" note, so she checked her clipboard - which still held the unrelated "Copy plain-English summary" text describing her OWN position. She reasonably concluded the nudge had sent her position instead of the recipient's. It had not: the message log shows #34 -> #102 carrying #102's own numbers. The feature was right and the feedback was wrong, which is its own kind of bug - a member who cannot verify what they sent will assume the worst. Every nudge now has a Preview button that names the recipient and shows the exact text before sending, and on success the panel shows what was sent and to whom rather than a bare "Delivered". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+26
-5
@@ -399,7 +399,18 @@
|
||||
// One-tap nudges: pre-written message per coach recommendation, sent over
|
||||
// the wallet-verified Messages rails (and bridged to Telegram if linked).
|
||||
const nudgeTexts={};
|
||||
function nudgeBtn(key){return `<br><button class="btn btn-teal btn-sm coach-nudge" data-nkey="${key}" style="margin-top:7px">📨 Send this nudge</button><span class="micro coach-nudge-note" style="display:none;margin-left:8px"></span>`}
|
||||
// Nudges used to send silently with only a "Delivered" note, so nobody could
|
||||
// see WHAT went out or to whom. A member went hunting in her clipboard, found
|
||||
// the unrelated "copy my summary" text still sitting there, and reasonably
|
||||
// concluded the nudge had sent her own position instead of the recipient's.
|
||||
// Preview before, and the exact sent text after, removes the guesswork.
|
||||
function nudgeBtn(key){return `<div class="coach-nudge-wrap" style="margin-top:7px">`+
|
||||
`<button class="btn btn-teal btn-sm coach-nudge" data-nkey="${key}">📨 Send this nudge</button>`+
|
||||
`<button class="btn btn-secondary btn-sm coach-nudge-preview" data-nkey="${key}" style="margin-left:6px">👁 Preview</button>`+
|
||||
`<span class="micro coach-nudge-note" style="display:none;margin-left:8px"></span>`+
|
||||
`<div class="coach-nudge-prev" style="display:none;margin-top:8px;background:rgba(78,214,203,.06);`+
|
||||
`border:1px solid rgba(78,214,203,.28);border-radius:10px;padding:10px 12px;font-size:12.5px;`+
|
||||
`line-height:1.6;color:var(--muted);white-space:pre-wrap"></div></div>`}
|
||||
function regNudge(id,kind,text){const key=id+':'+kind;nudgeTexts[key]={to:id,text};return nudgeBtn(key)}
|
||||
function renderCoach(d){
|
||||
const card=document.getElementById('dCoachCard'),el=document.getElementById('dCoach');
|
||||
@@ -418,10 +429,20 @@
|
||||
if(!el.__nudgeBound){
|
||||
el.__nudgeBound=true;
|
||||
el.addEventListener('click',async ev=>{
|
||||
const pv=ev.target.closest&&ev.target.closest('button.coach-nudge-preview');
|
||||
const btn=ev.target.closest&&ev.target.closest('button.coach-nudge');
|
||||
if(!btn)return;
|
||||
const rec=nudgeTexts[btn.dataset.nkey];if(!rec)return;
|
||||
const note=btn.nextElementSibling;
|
||||
if(!pv&&!btn)return;
|
||||
const rec=nudgeTexts[(pv||btn).dataset.nkey];if(!rec)return;
|
||||
const wrap=(pv||btn).closest('.coach-nudge-wrap');
|
||||
const note=wrap&&wrap.querySelector('.coach-nudge-note');
|
||||
const prev=wrap&&wrap.querySelector('.coach-nudge-prev');
|
||||
const showPrev=(label)=>{if(!prev)return;prev.textContent=label+'\n\n'+rec.text;prev.style.display='';};
|
||||
// Preview: show exactly what will be sent, and to whom, before sending.
|
||||
if(pv){
|
||||
if(prev&&prev.style.display!=='none'){prev.style.display='none';pv.textContent='\u{1F441} Preview';}
|
||||
else{showPrev('This will be sent to #'+rec.to+':');pv.textContent='\u{1F441} Hide preview';}
|
||||
return;
|
||||
}
|
||||
const say=(t,color)=>{if(note){note.style.display='';note.style.color=color||'var(--muted)';note.textContent=t;}};
|
||||
btn.disabled=true;const old=btn.textContent;btn.textContent='Sending…';
|
||||
try{
|
||||
@@ -434,7 +455,7 @@
|
||||
}
|
||||
const r=await fetch('/api/public/msg-send',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({toId:rec.to,body:rec.text})});
|
||||
const dd=await r.json().catch(()=>({}));
|
||||
if(r.ok&&!dd.error){btn.textContent='Sent ✓';say('Delivered to their dashboard — and straight to their Telegram if they’ve linked it.');}
|
||||
if(r.ok&&!dd.error){btn.textContent='Sent ✓';showPrev('✅ Sent to #'+rec.to+' — this is exactly what they received:');const pb=wrap&&wrap.querySelector('.coach-nudge-preview');if(pb)pb.style.display='none';say('Delivered to #'+rec.to+'’s dashboard — and straight to their Telegram if they’ve linked it.');}
|
||||
else{btn.textContent=old;btn.disabled=false;say(dd.error||'Could not send — try again.','var(--danger)');}
|
||||
}catch(e){btn.textContent=old;btn.disabled=false;say('Network hiccup — try again.','var(--danger)');}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user