nikeshn commited on
Commit
bbeb85a
Β·
verified Β·
1 Parent(s): 8b74ef8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +2 -10
app.py CHANGED
@@ -1234,7 +1234,7 @@ textarea:focus,input:focus,select:focus{{outline:none;border-color:#003366}}
1234
  <div class="tab" onclick="st(this,'system')">βš™οΈ System</div>
1235
  </div>
1236
 
1237
- <div class="tc active" id="t-analytics"><div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px"><button class="btn bp" onclick="downloadAnalytics()">⬇️ Download Excel (CSV)</button><button class="btn" style="background:#dc2626;color:#fff" onclick="clearOldData()">πŸ—‘οΈ Delete old data</button></div><div id="loading">Loading analytics from Cloudflare D1…</div></div>
1238
 
1239
  <div class="tc" id="t-behavior">
1240
  <div class="card"><h2>πŸ€– Bot Behavior</h2><p style="font-size:.8rem;color:#6b7280;margin-bottom:12px">Changes apply immediately.</p>
@@ -1281,7 +1281,6 @@ function st(el,t){{document.querySelectorAll('.tab').forEach(e=>e.classList.remo
1281
  // Fetch analytics from Cloudflare D1
1282
  fetch(W+'/analytics').then(r=>r.json()).then(d=>{{
1283
  const el=document.getElementById('t-analytics');
1284
- const fb=(d.feedback||[]); const up=(fb.find(x=>x.feedback==='up')||{{}}).c||0; const down=(fb.find(x=>x.feedback==='down')||{{}}).c||0;
1285
  el.innerHTML=`
1286
  <div class="grid">
1287
  <div class="stat"><div class="n">${{d.total}}</div><div class="l">Total</div></div>
@@ -1289,9 +1288,6 @@ fetch(W+'/analytics').then(r=>r.json()).then(d=>{{
1289
  <div class="stat"><div class="n">${{d.week}}</div><div class="l">This Week</div></div>
1290
  <div class="stat"><div class="n">${{(d.avg_time||0).toFixed(1)}}s</div><div class="l">Avg Time</div></div>
1291
  <div class="stat"><div class="n">${{d.errors}}</div><div class="l">Errors</div></div>
1292
- <div class="stat"><div class="n">${{up}}</div><div class="l">πŸ‘ Helpful</div></div>
1293
- <div class="stat"><div class="n">${{down}}</div><div class="l">πŸ‘Ž Not helpful</div></div>
1294
- <div class="stat"><div class="n">${{d.click_total||0}}</div><div class="l">Link Clicks</div></div>
1295
  </div>
1296
  <div class="two">
1297
  <div class="card"><h2>Tool Usage</h2><table><tr><th>Tool</th><th>Count</th></tr>${{d.tools.map(t=>`<tr><td>${{t.tool_used}}</td><td>${{t.c}}</td></tr>`).join('')}}</table></div>
@@ -1301,11 +1297,10 @@ fetch(W+'/analytics').then(r=>r.json()).then(d=>{{
1301
  <div class="card"><h2>Hourly</h2><canvas id="hc"></canvas></div>
1302
  <div class="card"><h2>Daily (14d)</h2><canvas id="dc"></canvas></div>
1303
  </div>
1304
- <div class="card"><h2>Popular (Top 20)</h2><table><tr><th>Question</th><th>Count</th></tr>${{d.popular.map(p=>`<tr><td>${{(p.question||'').substring(0,70)}}</td><td>${{p.c}}</td></tr>`).join('')}}</table></div><div id="feedback-panel"></div>`;
1305
  if(d.hourly.length)new Chart(document.getElementById('hc'),{{type:'bar',data:{{labels:d.hourly.map(h=>h.hour+':00'),datasets:[{{label:'Q',data:d.hourly.map(h=>h.c),backgroundColor:'#003366'}}]}},options:{{responsive:true,plugins:{{legend:{{display:false}}}}}}}});
1306
  if(d.daily.length)new Chart(document.getElementById('dc'),{{type:'line',data:{{labels:d.daily.map(x=>(x.day||'').slice(5)),datasets:[{{label:'Q',data:d.daily.map(x=>x.c),borderColor:'#003366',backgroundColor:'rgba(0,51,102,0.1)',fill:true,tension:.3}}]}},options:{{responsive:true,plugins:{{legend:{{display:false}}}}}}}});
1307
  }}).catch(e=>{{document.getElementById('t-analytics').innerHTML='<div class="card" style="color:#dc2626">Failed to load analytics: '+e.message+'<br>Make sure D1 is initialized: <a href="'+W+'/analytics/init" target="_blank">Click here to init DB</a></div>';}});
1308
- fetch(W+'/analytics/feedback').then(r=>r.json()).then(d=>{{ const el=document.getElementById('feedback-panel'); if(!el) return; el.innerHTML='<div class="two"><div class="card"><h2>πŸ‘Ž Top weak questions</h2><table><tr><th>Question</th><th>Count</th></tr>'+((d.low||[]).map(x=>`<tr><td>${{(x.question||'').substring(0,80)}}</td><td>${{x.c}}</td></tr>`).join('')||'<tr><td colspan="2">No negative feedback yet</td></tr>')+'</table></div><div class="card"><h2>πŸ”— Top clicks</h2><table><tr><th>Type</th><th>Label</th><th>Count</th></tr>'+((d.clicks||[]).slice(0,15).map(x=>`<tr><td>${{x.kind||''}}</td><td>${{(x.label||'').substring(0,60)}}</td><td>${{x.c}}</td></tr>`).join('')||'<tr><td colspan="3">No click data yet</td></tr>')+'</table></div></div><div class="card"><h2>Recent feedback</h2><table><tr><th>Time</th><th>Feedback</th><th>Question</th><th>Tool</th></tr>'+((d.recent||[]).slice(0,20).map(x=>`<tr><td>${{(x.timestamp||'').substring(0,19)}}</td><td>${{x.feedback==='up'?'πŸ‘':'πŸ‘Ž'}}</td><td>${{(x.question||'').substring(0,80)}}</td><td>${{x.tool_used||''}}</td></tr>`).join('')||'<tr><td colspan="4">No feedback yet</td></tr>')+'</table></div>'; }}).catch(()=>{{}});
1309
 
1310
  // Fetch recent queries
1311
  fetch(W+'/analytics/recent').then(r=>r.json()).then(d=>{{
@@ -1331,9 +1326,6 @@ async function rebuildIdx(){{
1331
  loadStatus(); // refresh status after rebuild
1332
  }}
1333
 
1334
- function downloadAnalytics(){{ window.open(W+'/analytics/export.csv','_blank'); }}
1335
- async function clearOldData(){{ const days=prompt('Delete records older than how many days?', '90'); if(!days) return; if(!confirm('Delete analytics, feedback, and clicks older than '+days+' days?')) return; const r=await fetch(W+'/analytics/clear-old',{{method:'POST',headers:{{'Content-Type':'application/json'}},body:JSON.stringify({{days:Number(days)}})}}); const res=await r.json(); const s=document.getElementById('sys')||document.getElementById('sv'); s.className=res.status==='ok'?'st ok':'st er'; s.style.display='block'; s.textContent=res.status==='ok' ? `βœ… Deleted old data: Q ${{res.deleted.queries}}, F ${{res.deleted.feedback}}, C ${{res.deleted.clicks}}` : '❌ '+(res.error?.message||JSON.stringify(res)); setTimeout(()=>location.reload(),1200); }}
1336
-
1337
  async function restartSpace(){{
1338
  if(!confirm('Restart the HF Space? The service will be unavailable for ~30-60 seconds.')) return;
1339
  const s=document.getElementById('sys');s.className='st ok';s.textContent='♻️ Restarting...';s.style.display='block';
 
1234
  <div class="tab" onclick="st(this,'system')">βš™οΈ System</div>
1235
  </div>
1236
 
1237
+ <div class="tc active" id="t-analytics"><div id="loading">Loading analytics from Cloudflare D1…</div></div>
1238
 
1239
  <div class="tc" id="t-behavior">
1240
  <div class="card"><h2>πŸ€– Bot Behavior</h2><p style="font-size:.8rem;color:#6b7280;margin-bottom:12px">Changes apply immediately.</p>
 
1281
  // Fetch analytics from Cloudflare D1
1282
  fetch(W+'/analytics').then(r=>r.json()).then(d=>{{
1283
  const el=document.getElementById('t-analytics');
 
1284
  el.innerHTML=`
1285
  <div class="grid">
1286
  <div class="stat"><div class="n">${{d.total}}</div><div class="l">Total</div></div>
 
1288
  <div class="stat"><div class="n">${{d.week}}</div><div class="l">This Week</div></div>
1289
  <div class="stat"><div class="n">${{(d.avg_time||0).toFixed(1)}}s</div><div class="l">Avg Time</div></div>
1290
  <div class="stat"><div class="n">${{d.errors}}</div><div class="l">Errors</div></div>
 
 
 
1291
  </div>
1292
  <div class="two">
1293
  <div class="card"><h2>Tool Usage</h2><table><tr><th>Tool</th><th>Count</th></tr>${{d.tools.map(t=>`<tr><td>${{t.tool_used}}</td><td>${{t.c}}</td></tr>`).join('')}}</table></div>
 
1297
  <div class="card"><h2>Hourly</h2><canvas id="hc"></canvas></div>
1298
  <div class="card"><h2>Daily (14d)</h2><canvas id="dc"></canvas></div>
1299
  </div>
1300
+ <div class="card"><h2>Popular (Top 20)</h2><table><tr><th>Question</th><th>Count</th></tr>${{d.popular.map(p=>`<tr><td>${{(p.question||'').substring(0,70)}}</td><td>${{p.c}}</td></tr>`).join('')}}</table></div>`;
1301
  if(d.hourly.length)new Chart(document.getElementById('hc'),{{type:'bar',data:{{labels:d.hourly.map(h=>h.hour+':00'),datasets:[{{label:'Q',data:d.hourly.map(h=>h.c),backgroundColor:'#003366'}}]}},options:{{responsive:true,plugins:{{legend:{{display:false}}}}}}}});
1302
  if(d.daily.length)new Chart(document.getElementById('dc'),{{type:'line',data:{{labels:d.daily.map(x=>(x.day||'').slice(5)),datasets:[{{label:'Q',data:d.daily.map(x=>x.c),borderColor:'#003366',backgroundColor:'rgba(0,51,102,0.1)',fill:true,tension:.3}}]}},options:{{responsive:true,plugins:{{legend:{{display:false}}}}}}}});
1303
  }}).catch(e=>{{document.getElementById('t-analytics').innerHTML='<div class="card" style="color:#dc2626">Failed to load analytics: '+e.message+'<br>Make sure D1 is initialized: <a href="'+W+'/analytics/init" target="_blank">Click here to init DB</a></div>';}});
 
1304
 
1305
  // Fetch recent queries
1306
  fetch(W+'/analytics/recent').then(r=>r.json()).then(d=>{{
 
1326
  loadStatus(); // refresh status after rebuild
1327
  }}
1328
 
 
 
 
1329
  async function restartSpace(){{
1330
  if(!confirm('Restart the HF Space? The service will be unavailable for ~30-60 seconds.')) return;
1331
  const s=document.getElementById('sys');s.className='st ok';s.textContent='♻️ Restarting...';s.style.display='block';