/* ═══════════════════════════════════════════════════════════ 12. DASHBOARD ANALITIK ═══════════════════════════════════════════════════════════ */ const Dashboard = { toggle(){ document.getElementById('dash-panel').classList.toggle('hidden'); if(!document.getElementById('dash-panel').classList.contains('hidden')) this.render(); }, render(){ const db=Store.allDb(); const warga=db.warga||[], ri=db.rumahIbadah||[], jalan=db.jalan||[], parsil=db.parsil||[]; const totalWarga=warga.reduce((s,r)=>s+(parseInt(r.jml_anggota)||1),0); const miskinBerat=warga.filter(r=>r.tingkat_kemiskinan==='Sangat Miskin'||r.tingkat_kemiskinan==='Miskin').length; const blmBansos=warga.filter(r=>r.bansos==='Belum Ada').length; const blmSertif=parsil.filter(r=>r.status==='Belum Bersertifikat').length; const jalanRusak=jalan.filter(r=>r.kondisi==='Rusak Berat'||r.kondisi==='Rusak Ringan').length; const totalRI=ri.length; // Radius coverage for Warga layer let coveredKK=0, uncoveredKK=0; const coverageHubs = ri.map(hub=>({ ...hub, count:0 })); warga.forEach(b => { if(!b.lat) return; let nearestDist=Infinity, nearestHub=null; ri.forEach(hub=>{ if(!hub.lat) return; const d=L.latLng(b.lat,b.lng).distanceTo(L.latLng(hub.lat,hub.lng)); if(dh.id===nearestHub.id); if(h) h.count++; } else { uncoveredKK++; } }); // tingkat kemiskinan breakdown const tkBreak={}; CFG.warga.tingkat.forEach(t=>{ tkBreak[t]=warga.filter(r=>r.tingkat_kemiskinan===t).length; }); const maxTK=Math.max(...Object.values(tkBreak),1); // bansos breakdown const bansosBreak={}; CFG.warga.bantuan.forEach(b=>{ const c=warga.filter(r=>r.bansos===b).length; if(c>0) bansosBreak[b]=c; }); // jalan status breakdown const jalanBreak={}; CFG.jalan.statuses.forEach(s=>{ jalanBreak[s]=jalan.filter(r=>r.status===s).length; }); document.getElementById('dash-body').innerHTML=`
Ringkasan Utama
Distribusi Bansos
${H.fmNum(warga.length)}
KK Warga Miskin Terdata
${H.fmNum(totalWarga)} jiwa total
${H.fmNum(miskinBerat)}
Miskin & Sangat Miskin
${warga.length?Math.round(miskinBerat/warga.length*100):0}% dari total KK
${H.fmNum(blmBansos)}
KK Belum Terima Bansos
Perlu intervensi segera
${H.fmNum(totalRI)}
Rumah Ibadah Aktif
Agen lapangan terdaftar
${H.fmNum(blmSertif)}
Parsil Belum Bersertifikat
Kandidat program PTSL
${H.fmNum(jalanRusak)}
Ruas Jalan Rusak
Dari ${H.fmNum(jalan.length)} ruas terdata
Sebaran Tingkat Kemiskinan
${CFG.warga.tingkat.map(t=>{ const n=tkBreak[t]||0, pct=warga.length?Math.round(n/warga.length*100):0; const clr={'Sangat Miskin':'#f05c5c','Miskin':'#f0a030','Hampir Miskin':'#f0c040','Rentan':'#5b9cf6'}[t]; return \`\`; }).join('')}
KategoriJumlah KKProporsi
\${t}\${H.fmNum(n)} KK
\${pct}%
Penerima Program Bantuan Sosial
${Object.entries(bansosBreak).length?Object.entries(bansosBreak).sort((a,b)=>b[1]-a[1]).map(([b,n])=>`
${b}${n} KK
`).join('') :'
Belum ada data warga tercatat.
'}
Status Ruas Jalan
${CFG.jalan.statuses.map(s=>{ const ruas=jalan.filter(r=>r.status===s); const pj=ruas.reduce((t,r)=>t+(r.panjang||0),0); return \`\`; }).join('')}
StatusJumlah RuasTotal Panjang
\${s}\${ruas.length} ruas\${H.fmDist(pj)}
Rekomendasi Intervensi Kebijakan
🏠 Prioritas Bansos
${H.fmNum(blmBansos)} KK
Warga belum menerima bantuan apapun
📜 Prioritas PTSL
${H.fmNum(blmSertif)} Parsil
Lahan tanpa sertifikat, akses kredit terbatas
🛣️ Prioritas Perbaikan Jalan
${H.fmNum(jalanRusak)} Ruas
Jalan rusak ringan-berat perlu perbaikan
🕌 Coverage Rumah Ibadah
${H.fmNum(totalRI)} RI Aktif
Total dana sosial: Rp ${H.fmNum(ri.reduce((t,r)=>t+(parseInt(r.dana_sosial)||0),0))}
`; }, switchTab(tabId){ document.querySelectorAll('.dash-tab').forEach(t=>t.classList.remove('active')); document.querySelectorAll('[id^="dash-panel-"]').forEach(p=>p.style.display='none'); if(tabId === 'ringkasan'){ document.querySelectorAll('.dash-tab')[0].classList.add('active'); document.getElementById('dash-panel-ringkasan').style.display='block'; } else { document.querySelectorAll('.dash-tab')[1].classList.add('active'); document.getElementById('dash-panel-distribusi').style.display='block'; } } };