diff --git a/mcp-server/search.html b/mcp-server/search.html index 9c4bcb6..9517d28 100644 --- a/mcp-server/search.html +++ b/mcp-server/search.html @@ -619,11 +619,51 @@ function showProfile(workerData){ 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 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'; + 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'; - 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); }