Files
WebGIS-Project/webgis-v3/assets/js/dashboard.js
T
2026-06-10 19:48:00 +07:00

70 lines
4.5 KiB
JavaScript

const Dashboard = (() => {
async function load() {
try {
const d = await Api.get('/dashboard');
const s = d.statistik;
sv2('d-miskin', s.total_miskin); sv2('d-rentan', s.total_rentan);
sv2('d-mampu', s.total_mampu); sv2('d-kk', s.total_kk);
sv2('d-belum', d.belum_dibantu); sv2('d-darurat', s.laporan_pending);
sv2('hp-miskin-n', s.total_miskin); sv2('hp-rentan-n', s.total_rentan);
sv2('hp-mampu-n', s.total_mampu); sv2('hp-lap-n', s.laporan_pending);
ge('dash-updated').textContent = 'Update: ' + new Date().toLocaleTimeString('id-ID');
renderPrio(d.prioritas_darurat);
renderBar('d-kec-chart', d.sebaran_kecamatan, r => ({ label: r.kecamatan||'?', val: +r.miskin+ +r.rentan, color:'#ff4d6d', sub:`${r.miskin} miskin` }));
renderBar('d-ri-chart', d.beban_per_ri, r => ({ label: r.nama, val: +r.kk_miskin, color:'#4361ee', sub:`${r.jumlah_kk} KK` }));
renderBar('d-trend-chart', d.trend_bantuan, r => ({ label: r.bulan, val: +r.jumlah, color:'#06d6a0', sub:`${r.jumlah}x` }));
} catch { loadDemo(); }
}
function loadDemo() {
sv2('d-miskin',6); sv2('d-rentan',4); sv2('d-mampu',2);
sv2('d-kk',8); sv2('d-belum',4); sv2('d-darurat',2);
sv2('hp-miskin-n',6); sv2('hp-rentan-n',4); sv2('hp-mampu-n',2); sv2('hp-lap-n',2);
ge('dash-updated').textContent = 'Data demo (offline)';
renderPrio([
{ nama_lengkap:'Maria Magdalena', umur:54, kondisi_kesehatan:'sakit_berat', kecamatan:'Pontianak Selatan', jumlah_dibantu:1, level_prioritas:'SANGAT TINGGI', nik:'6171010101010006' },
{ nama_lengkap:'Tan Eng Huat', umur:65, kondisi_kesehatan:'disabilitas', kecamatan:'Pontianak Kota', jumlah_dibantu:1, level_prioritas:'SANGAT TINGGI', nik:'6171010101010014' },
{ nama_lengkap:'Lim Ah Kow', umur:59, kondisi_kesehatan:'sakit_berat', kecamatan:'Pontianak Kota', jumlah_dibantu:1, level_prioritas:'TINGGI', nik:'6171010101010010' },
]);
renderBar('d-kec-chart',[{kecamatan:'Pontianak Timur',miskin:2,rentan:1},{kecamatan:'Pontianak Selatan',miskin:2,rentan:2},{kecamatan:'Pontianak Kota',miskin:2,rentan:1}],
r=>({label:r.kecamatan,val:+r.miskin+ +r.rentan,color:'#ff4d6d',sub:`${r.miskin} miskin`}));
renderBar('d-ri-chart',[{nama:"Masjid Jami'",jumlah_kk:3,kk_miskin:2},{nama:'Katedral',jumlah_kk:2,kk_miskin:2},{nama:'Mujahidin',jumlah_kk:1,kk_miskin:1}],
r=>({label:r.nama,val:+r.kk_miskin,color:'#4361ee',sub:`${r.jumlah_kk} KK`}));
renderBar('d-trend-chart',[{bulan:'2025-01',jumlah:2},{bulan:'2025-02',jumlah:1},{bulan:'2025-03',jumlah:3},{bulan:'2025-04',jumlah:1}],
r=>({label:r.bulan,val:+r.jumlah,color:'#06d6a0',sub:`${r.jumlah}x`}));
}
function renderPrio(list) {
const el = ge('d-prio-list');
if (!list?.length) { el.innerHTML = '<div class="empty-state"><div class="es-icon">✅</div><p>Tidak ada kasus darurat</p></div>'; return; }
const cls = { 'SANGAT TINGGI':'pb-sangat-tinggi','TINGGI':'pb-tinggi','SEDANG':'pb-sedang','RENDAH':'pb-rendah' };
el.innerHTML = list.map(p => `
<div class="prio-item" onclick="Bantuan.quickSalur('${p.nik}','${p.nama_lengkap}')">
<span class="prio-badge ${cls[p.level_prioritas]||'pb-rendah'}">${p.level_prioritas}</span>
<div style="flex:1;min-width:0">
<div style="font-weight:700;font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${p.nama_lengkap}</div>
<div style="font-size:11px;color:var(--muted)">${cap(p.kondisi_kesehatan)} · ${p.kecamatan} · dibantu ${p.jumlah_dibantu}x</div>
</div>
<span style="font-size:18px;flex-shrink:0">→</span>
</div>`).join('');
}
function renderBar(elId, data, mapper) {
const el = ge(elId);
if (!data?.length) { el.innerHTML = '<p style="color:var(--muted);font-size:12px;padding:12px">Tidak ada data</p>'; return; }
const mapped = data.map(mapper);
const max = Math.max(...mapped.map(m => m.val), 1);
el.innerHTML = mapped.map(m => {
const pct = Math.round(m.val / max * 100);
return `<div class="bar-row">
<div class="bar-lbl" title="${m.label}">${m.label.slice(0,16)}${m.label.length>16?'…':''}</div>
<div class="bar-track"><div class="bar-fill" style="width:${pct}%;background:${m.color}"></div></div>
<div class="bar-val">${m.val}<span style="font-size:9px;color:var(--muted);margin-left:3px">${m.sub?.replace(/^\d+ /,'')}</span></div>
</div>`;
}).join('');
}
function sv2(id, val) { const el = ge(id); if (el) el.textContent = val ?? '—'; }
return { load };
})();