76 lines
4.8 KiB
JavaScript
76 lines
4.8 KiB
JavaScript
/* =========================================================
|
|
skpl-map.js — Peta SKPL (operator & pimpinan)
|
|
Warga miskin (POI) + fasilitas publik + choropleth + heatmap
|
|
(choropleth/heatmap/legenda/pencarian via attachSkplLayers).
|
|
Role ditentukan global SKPL_ROLE ('operator' | 'pimpinan').
|
|
========================================================= */
|
|
(function () {
|
|
const API = APP_BASE + '/api';
|
|
const ROLE = (typeof SKPL_ROLE !== 'undefined') ? SKPL_ROLE : 'pimpinan';
|
|
let map, wargaLayer, fasilitasLayer;
|
|
|
|
const FAS_ICON = { sekolah: '🏫', puskesmas: '🏥', pasar: '🏪', kantor_kelurahan: '🏛️', rumah_ibadah: '🕌', lainnya: '📍' };
|
|
|
|
function divIcon(emoji, bg, size = 30) {
|
|
return L.divIcon({
|
|
className: 'div-icon-wrap',
|
|
html: `<div style="background:${bg};width:${size}px;height:${size}px;border-radius:50% 50% 50% 0;transform:rotate(-45deg);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 5px rgba(0,0,0,.3);border:2px solid #fff;"><span style="transform:rotate(45deg);font-size:${size*0.45}px;">${emoji}</span></div>`,
|
|
iconSize: [size, size], iconAnchor: [size / 2, size], popupAnchor: [0, -size],
|
|
});
|
|
}
|
|
const wargaIcon = divIcon('👤', '#EF4444');
|
|
|
|
function wargaPopup(p) {
|
|
const vb = { terverifikasi: '#10B981', perlu_tinjauan: '#F59E0B', belum: '#9CA3AF' }[p.status_verifikasi] || '#9CA3AF';
|
|
let h = `<div style="min-width:200px;"><div style="font-weight:700;margin-bottom:4px;">${p.nama_kk}</div>`;
|
|
if (p.nik_kk) h += `<div style="font-size:.8rem;">NIK: ${p.nik_kk}</div>`;
|
|
if (p.alamat) h += `<div style="font-size:.8rem;">${p.alamat}</div>`;
|
|
h += `<div style="font-size:.8rem;">Penghasilan: Rp ${Number(p.penghasilan||0).toLocaleString('id-ID')}</div>`;
|
|
h += `<div style="font-size:.8rem;">Jiwa: ${p.jumlah_jiwa||'-'} · Tanggungan: ${p.jumlah_tanggungan||0}</div>`;
|
|
h += `<div style="font-size:.8rem;">Air: ${p.sumber_air||'-'} · Dinding: ${p.material_dinding||'-'}</div>`;
|
|
h += `<div style="font-size:.8rem;">Bantuan: <b>${p.bantuan_aktif||'Belum ada'}</b></div>`;
|
|
h += `<div style="font-size:.8rem;">Status: <b style="color:${vb}">${p.status_verifikasi||'belum'}</b>${p.jumlah_foto?' · 📷 '+p.jumlah_foto:''}</div>`;
|
|
if (ROLE === 'operator') {
|
|
h += `<div style="display:flex;gap:6px;margin-top:8px;">
|
|
<button onclick="window.location.href='${APP_BASE}/admin/data_warga.php'" style="flex:1;padding:6px;border:1px solid #2563EB;background:#2563EB;color:#fff;border-radius:6px;cursor:pointer;font-size:.78rem;">Kelola</button>
|
|
<button onclick="SKPLMAP_del(${p.id})" style="padding:6px 10px;border:1px solid #EF4444;background:#fff;color:#EF4444;border-radius:6px;cursor:pointer;font-size:.78rem;">Hapus</button>
|
|
</div>`;
|
|
}
|
|
return h + `</div>`;
|
|
}
|
|
|
|
async function loadWarga() {
|
|
const j = await (await fetch(`${API}/warga_miskin.php`)).json();
|
|
const data = j.status === 'success' ? j.data : { features: [] };
|
|
wargaLayer = L.geoJSON(data, {
|
|
pointToLayer: (f, ll) => L.marker(ll, { icon: wargaIcon }),
|
|
onEachFeature: (f, l) => l.bindPopup(wargaPopup(f.properties)),
|
|
}).addTo(map);
|
|
}
|
|
async function loadFasilitas() {
|
|
const j = await (await fetch(`${API}/fasilitas.php`)).json();
|
|
const data = j.status === 'success' ? j.data : { features: [] };
|
|
fasilitasLayer = L.geoJSON(data, {
|
|
pointToLayer: (f, ll) => L.marker(ll, { icon: divIcon(FAS_ICON[f.properties.jenis] || '📍', '#2563EB', 26) }),
|
|
onEachFeature: (f, l) => l.bindPopup(`<b>${f.properties.nama}</b><br><span style="font-size:.8rem;color:#6B7280;">${f.properties.jenis.replace('_',' ')}</span>`),
|
|
});
|
|
}
|
|
|
|
window.SKPLMAP_del = async function (id) {
|
|
if (!confirm('Hapus data warga ini?')) return;
|
|
const r = await (await fetch(`${API}/warga_miskin.php?id=${id}`, { method: 'DELETE' })).json();
|
|
if (r.status === 'success') { map.removeLayer(wargaLayer); loadWarga(); }
|
|
else alert(r.message || 'Gagal');
|
|
};
|
|
|
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
map = L.map('skpl-map').setView([-0.0500, 109.3450], 13);
|
|
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', { subdomains: 'abcd', maxZoom: 19, attribution: '© OpenStreetMap, © CARTO' }).addTo(map);
|
|
await loadWarga();
|
|
await loadFasilitas();
|
|
if (window.attachSkplLayers) await window.attachSkplLayers(map);
|
|
// tambahkan toggle warga & fasilitas
|
|
L.control.layers(null, { '👤 Warga Miskin': wargaLayer, '🏢 Fasilitas Publik': fasilitasLayer }, { collapsed: true, position: 'topright' }).addTo(map);
|
|
});
|
|
})();
|