#3: Worker profile modal shows past playbook history
Click any worker card → modal now includes a 'Past Playbooks' section that queries successful_playbooks_live for any row where this worker's name appears in the result field. Shows up to 8 most recent with operation, timestamp, approach, and context. When empty: 'No prior playbooks for NAME yet. First placement builds the first entry.' — makes the institutional-memory claim visible to the recruiter: the system is tracking everyone, not just the ones that sealed this session. Also added Call / SMS / No-show buttons to the modal action row (matching the card-level buttons from #1). Every worker-card path now trains the system. Closes the user-visible side of Phase 19 — patterns surface during search (Pass A), boosts fire in ranking (Phase 19 core), and now the worker's own profile shows the full history that informs those boosts. Institutional memory legibility, per J's ask.
This commit is contained in:
parent
cdd12a1438
commit
1f56630d5d
@ -619,11 +619,51 @@ function showProfile(workerData){
|
|||||||
body.appendChild(srcBox);
|
body.appendChild(srcBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Past playbook history — Phase 19 institutional memory surfaced on
|
||||||
|
// the worker's own profile. Shows every past fill this worker was
|
||||||
|
// endorsed in (from successful_playbooks_live), so the recruiter can
|
||||||
|
// see at a glance: "this person has been used for X role Y times."
|
||||||
|
addSection(body,'Past Playbooks','Where this worker has been endorsed before');
|
||||||
|
var histBox=document.createElement('div');histBox.id='hist-'+(workerData.nm||'anon').replace(/\s/g,'-');
|
||||||
|
histBox.style.cssText='background:#0d1117;border-radius:8px;padding:14px;margin-bottom:20px;font-size:12px;color:#8b949e;line-height:1.6';
|
||||||
|
histBox.textContent='Loading history...';body.appendChild(histBox);
|
||||||
|
var city=(workerData.loc||'').split(',')[0].trim();
|
||||||
|
var state=(workerData.loc||'').split(',').pop().trim();
|
||||||
|
var nameLit=(workerData.nm||'').replace(/'/g,"''");
|
||||||
|
var sqlQ="SELECT operation, approach, context, timestamp FROM successful_playbooks_live "
|
||||||
|
+"WHERE result LIKE '%"+nameLit+"%' ORDER BY timestamp DESC LIMIT 8";
|
||||||
|
api('/sql',{sql:sqlQ}).then(function(r){
|
||||||
|
histBox.textContent='';
|
||||||
|
var rows=(r&&r.rows)||[];
|
||||||
|
if(rows.length===0){
|
||||||
|
histBox.textContent='No prior playbooks for '+(workerData.nm||'this worker')+' yet. First placement builds the first entry.';
|
||||||
|
histBox.style.color='#484f58';return;
|
||||||
|
}
|
||||||
|
var hdr2=document.createElement('div');hdr2.style.cssText='color:#3fb950;font-weight:600;margin-bottom:8px;font-size:11px';
|
||||||
|
hdr2.textContent=rows.length+' past endorsement'+(rows.length!==1?'s':'');
|
||||||
|
histBox.appendChild(hdr2);
|
||||||
|
rows.forEach(function(pb){
|
||||||
|
var row=document.createElement('div');row.style.cssText='padding:6px 10px;background:#161b22;border-radius:6px;margin-bottom:4px;border-left:2px solid #2ea043';
|
||||||
|
var op=document.createElement('div');op.style.cssText='color:#e6edf3;font-weight:500;font-size:12px';
|
||||||
|
op.textContent=pb.operation||'(unknown op)';row.appendChild(op);
|
||||||
|
var meta=document.createElement('div');meta.style.cssText='color:#8b949e;font-size:10px;margin-top:2px';
|
||||||
|
var ts=(pb.timestamp||'').substring(0,10);
|
||||||
|
meta.textContent=ts+' · '+(pb.approach||'').slice(0,40)+(pb.context?' · '+pb.context.slice(0,30):'');
|
||||||
|
row.appendChild(meta);histBox.appendChild(row);
|
||||||
|
});
|
||||||
|
}).catch(function(){
|
||||||
|
histBox.textContent='(history unavailable)';histBox.style.color='#484f58';
|
||||||
|
});
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
var acts=document.createElement('div');acts.style.cssText='display:flex;gap:8px;padding-top:16px;border-top:1px solid #21262d';
|
var acts=document.createElement('div');acts.style.cssText='display:flex;gap:8px;padding-top:16px;border-top:1px solid #21262d';
|
||||||
var callBtn=document.createElement('button');callBtn.style.cssText='flex:1;padding:12px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;border:none;background:#1f3d68;color:#58a6ff';callBtn.textContent='Call';
|
var callBtn=document.createElement('button');callBtn.style.cssText='flex:1;padding:12px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;border:none;background:#1f3d68;color:#58a6ff';callBtn.textContent='Call';
|
||||||
|
callBtn.onclick=function(){logAction(workerData,'call',callBtn)};
|
||||||
var smsBtn=document.createElement('button');smsBtn.style.cssText='flex:1;padding:12px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;border:none;background:#0d261a;color:#3fb950';smsBtn.textContent='Send SMS';
|
var smsBtn=document.createElement('button');smsBtn.style.cssText='flex:1;padding:12px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;border:none;background:#0d261a;color:#3fb950';smsBtn.textContent='Send SMS';
|
||||||
acts.appendChild(callBtn);acts.appendChild(smsBtn);body.appendChild(acts);
|
smsBtn.onclick=function(){logAction(workerData,'sms',smsBtn)};
|
||||||
|
var noshowBtn=document.createElement('button');noshowBtn.style.cssText='flex:1;padding:12px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;border:none;background:#3a1a1a;color:#f85149';noshowBtn.textContent='No-show';
|
||||||
|
noshowBtn.onclick=function(){logAction(workerData,'failure',noshowBtn)};
|
||||||
|
acts.appendChild(callBtn);acts.appendChild(smsBtn);acts.appendChild(noshowBtn);body.appendChild(acts);
|
||||||
|
|
||||||
modal.appendChild(body);overlay.appendChild(modal);document.body.appendChild(overlay);
|
modal.appendChild(body);overlay.appendChild(modal);document.body.appendChild(overlay);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user