First commit / commit pertama
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/* =========================================================
|
||||
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);
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user