954 lines
45 KiB
JavaScript
954 lines
45 KiB
JavaScript
// --- INISIALISASI PETA (Koordinat Pontianak) ---
|
|
const map = L.map('map').setView([-0.055348, 109.349512], 13);
|
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' }).addTo(map);
|
|
|
|
const popup = L.popup();
|
|
const daftarMarker = {}, daftarPolyline = {}, daftarPolygon = {};
|
|
|
|
// 1. BUAT KERTAS TRANSPARAN (LAYER GROUPS)
|
|
const layerTercakup = L.layerGroup().addTo(map);
|
|
const layerTidakTercakup = L.layerGroup().addTo(map);
|
|
const layerIbadah = L.layerGroup().addTo(map);
|
|
const layerRadius = L.layerGroup().addTo(map);
|
|
|
|
function toggleLayer(namaLayer, checkbox) {
|
|
const layers = {
|
|
'tercakup': layerTercakup,
|
|
'tidakTercakup': layerTidakTercakup,
|
|
'ibadah': layerIbadah,
|
|
'radius': layerRadius,
|
|
};
|
|
|
|
if (checkbox.checked) {
|
|
layers[namaLayer].addTo(map);
|
|
} else {
|
|
map.removeLayer(layers[namaLayer]);
|
|
}
|
|
}
|
|
|
|
let legend = L.control({ position: 'topright' });
|
|
legend.onAdd = function() {
|
|
let div = L.DomUtil.create('div', 'map-legend');
|
|
div.innerHTML = `
|
|
<h4><i class="fa-solid fa-circle-info"></i> Legenda</h4>
|
|
<div class="legend-item">
|
|
<span class="legend-dot" style="background:#27ae60;"></span> Prasejahtera Tercakup
|
|
</div>
|
|
<div class="legend-item">
|
|
<span class="legend-dot" style="background:#e74c3c;"></span> Prasejahtera Tidak Tercakup
|
|
</div>
|
|
<hr style="margin:6px 0; border-color:#eee;">
|
|
<div class="legend-item"><span class="legend-dot" style="background:#1abc9c;"></span> Masjid</div>
|
|
<div class="legend-item"><span class="legend-dot" style="background:#3498db;"></span> Gereja</div>
|
|
<div class="legend-item"><span class="legend-dot" style="background:#e67e22;"></span> Vihara</div>
|
|
<div class="legend-item"><span class="legend-dot" style="background:#9b59b6;"></span> Pura</div>
|
|
<div class="legend-item"><span class="legend-dot" style="background:#e74c3c;"></span> Klenteng</div>
|
|
<hr style="margin:6px 0; border-color:#eee;">
|
|
<div class="legend-item"><span class="legend-radius"></span> Radius Jangkauan</div>
|
|
<div class="legend-item">
|
|
<span style="
|
|
width:40px; height:10px;
|
|
background: linear-gradient(to right, #3498db, #f1c40f, #e67e22, #e74c3c);
|
|
border-radius:4px; display:inline-block; flex-shrink:0;
|
|
"></span>
|
|
Heatmap Kemiskinan
|
|
</div>
|
|
`;
|
|
return div;
|
|
};
|
|
legend.addTo(map);
|
|
|
|
let currentMode = 'none';
|
|
let tempLatLngs = [], tempPolyline = null;
|
|
let tempPolygonLatLngs = [], tempPolygon = null;
|
|
let targetEditJalanId = null; // Menyimpan ID jalan yang sedang diedit
|
|
let targetEditKavlingId = null; // Menyimpan ID kavling yang sedang diedit
|
|
|
|
// Konfigurasi SweetAlert2 (Toast Pojok Kanan Atas)
|
|
const Toast = Swal.mixin({
|
|
toast: true, position: 'top-end', showConfirmButton: false, timer: 3000, timerProgressBar: true
|
|
});
|
|
|
|
// Definisi Ikon Kustom
|
|
const ikonHijau = new L.Icon({ iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png', shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] });
|
|
const ikonMerah = new L.Icon({ iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] });
|
|
|
|
// ikon rumah prasejahtera
|
|
const ikonPrasejahtera = L.divIcon({
|
|
html: `<div style="
|
|
background-color: #e74c3c;
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50% 50% 50% 0;
|
|
transform: rotate(-45deg);
|
|
border: 2px solid #c0392b;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
">
|
|
<i class="fa-solid fa-house-chimney-crack" style="
|
|
transform: rotate(45deg);
|
|
color: white;
|
|
font-size: 14px;
|
|
"></i>
|
|
</div>`,
|
|
iconSize: [32, 32],
|
|
iconAnchor: [16, 32],
|
|
popupAnchor: [0, -34],
|
|
className: ''
|
|
});
|
|
|
|
const ikonPrasejahteraTercakup = L.divIcon({
|
|
html: `<div style="
|
|
background-color: #27ae60;
|
|
width: 32px; height: 32px;
|
|
border-radius: 50% 50% 50% 0;
|
|
transform: rotate(-45deg);
|
|
border: 2px solid #1e8449;
|
|
display: flex; align-items: center; justify-content: center;">
|
|
<i class="fa-solid fa-house-chimney-crack" style="transform:rotate(45deg); color:white; font-size:14px;"></i>
|
|
</div>`,
|
|
iconSize: [32, 32], iconAnchor: [16, 32], popupAnchor: [0, -34], className: ''
|
|
});
|
|
|
|
function buatIkonIbadah(jenis) {
|
|
const config = {
|
|
'Masjid': { icon: 'fa-mosque', color: '#1abc9c' },
|
|
'Gereja': { icon: 'fa-church', color: '#3498db' },
|
|
'Vihara': { icon: 'fa-torii-gate', color: '#e67e22' },
|
|
'Pura': { icon: 'fa-om', color: '#9b59b6' },
|
|
'Klenteng': { icon: 'fa-yin-yang', color: '#e74c3c' },
|
|
};
|
|
const c = config[jenis] || { icon: 'fa-place-of-worship', color: '#7f8c8d' };
|
|
return L.divIcon({
|
|
html: `<div style="
|
|
background-color: ${c.color};
|
|
width: 32px; height: 32px;
|
|
border-radius: 50% 50% 50% 0;
|
|
transform: rotate(-45deg);
|
|
border: 2px solid rgba(0,0,0,0.3);
|
|
display: flex; align-items: center; justify-content: center;">
|
|
<i class="fa-solid ${c.icon}" style="transform:rotate(45deg); color:white; font-size:14px;"></i>
|
|
</div>`,
|
|
iconSize: [32, 32], iconAnchor: [16, 32], popupAnchor: [0, -34], className: ''
|
|
});
|
|
}
|
|
|
|
// Simpan data ibadah dan prasejahtera dalam memori untuk kalkulasi
|
|
const dataPrasejahtera = {}; // { id: {lat, lng, marker} }
|
|
const dataIbadah = {}; // { id: {lat, lng, radius_m, lingkaran} }
|
|
|
|
function perbaruiWarnaPrasejahtera() {
|
|
for (let pid in dataPrasejahtera) {
|
|
let p = dataPrasejahtera[pid];
|
|
let tercakup = false;
|
|
|
|
for (let iid in dataIbadah) {
|
|
let ib = dataIbadah[iid];
|
|
let jarak = map.distance([p.lat, p.lng], [ib.lat, ib.lng]);
|
|
if (jarak <= ib.radius_m) { tercakup = true; break; }
|
|
}
|
|
|
|
// Ganti ikon sesuai status
|
|
let ikonBaru = tercakup ? ikonPrasejahteraTercakup : ikonPrasejahtera;
|
|
p.marker.setIcon(ikonBaru);
|
|
|
|
layerTercakup.removeLayer(p.marker);
|
|
layerTidakTercakup.removeLayer(p.marker);
|
|
if (tercakup) {
|
|
p.marker.addTo(layerTercakup);
|
|
} else {
|
|
p.marker.addTo(layerTidakTercakup);
|
|
}
|
|
}
|
|
updateRingkasan();
|
|
}
|
|
|
|
// --- MANAJEMEN MODE UI ---
|
|
function ubahMode(mode) {
|
|
if (ROLE === 'viewer') return;
|
|
|
|
console.log('Mode diklik:', mode, '| Mode saat ini:', currentMode); // ← tambah ini
|
|
|
|
if (currentMode === mode) {
|
|
// Jika mode yang diklik sama dengan yang aktif, matikan semua
|
|
currentMode = 'none'; // Mode netral
|
|
|
|
map.pm.disableGlobalEditMode();
|
|
if (targetEditJalanId) batalkanEditJalan();
|
|
if (targetEditKavlingId) batalkanEditKavling();
|
|
|
|
// Matikan semua highlight tombol aktif
|
|
document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active'));
|
|
|
|
// Sembunyikan semua panel sidebar
|
|
document.getElementById('polyline-actions').style.display = 'none';
|
|
document.getElementById('polygon-actions').style.display = 'none';
|
|
document.getElementById('edit-jalan-actions').style.display = 'none';
|
|
document.getElementById('edit-kavling-actions').style.display = 'none';
|
|
|
|
map.closePopup();
|
|
batalPolyline();
|
|
batalPolygon();
|
|
return; // Hentikan eksekusi, tidak perlu lanjut ke bawah
|
|
}
|
|
currentMode = mode;
|
|
|
|
// Matikan mode edit Geoman global jika sedang aktif
|
|
map.pm.disableGlobalEditMode();
|
|
|
|
// Reset state edit
|
|
if (targetEditJalanId) batalkanEditJalan();
|
|
if (targetEditKavlingId) batalkanEditKavling();
|
|
|
|
// Atur tampilan tombol aktif
|
|
document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active'));
|
|
document.querySelector(`.mode-btn[data-mode="${mode}"]`).classList.add('active');
|
|
|
|
// Munculkan menu yang sesuai di sidebar
|
|
document.getElementById('polyline-actions').style.display = (mode === 'polyline') ? 'block' : 'none';
|
|
document.getElementById('polygon-actions').style.display = (mode === 'polygon') ? 'block' : 'none';
|
|
document.getElementById('edit-jalan-actions').style.display = (mode === 'edit_jalan') ? 'block' : 'none';
|
|
document.getElementById('edit-kavling-actions').style.display = (mode === 'edit_kavling') ? 'block' : 'none';
|
|
|
|
map.closePopup();
|
|
if (mode !== 'polyline') batalPolyline();
|
|
if (mode !== 'polygon') batalPolygon();
|
|
}
|
|
|
|
// --- LOAD DATA DARI DATABASE ---
|
|
function loadIbadah() {
|
|
fetch('api/rumahibadah/load_ibadah.php').then(res => res.json()).then(data => {
|
|
data.forEach(ib => {
|
|
let marker = L.marker([ib.lat, ib.lng], {
|
|
icon: buatIkonIbadah(ib.jenis),
|
|
draggable: ROLE === 'admin' || ROLE === 'operator'
|
|
})
|
|
.addTo(layerIbadah);
|
|
|
|
// Lingkaran radius
|
|
let lingkaran = L.circle([ib.lat, ib.lng], {
|
|
radius: ib.radius_m, color: '#8e44ad',
|
|
fillColor: '#8e44ad', fillOpacity: 0.1, weight: 1, dashArray: '5,5'
|
|
}).addTo(layerRadius);
|
|
|
|
const totalPrasejahtera = Object.keys(dataPrasejahtera).length;
|
|
const persen = totalPrasejahtera > 0
|
|
? Math.round((ib.jumlah_tercakup / totalPrasejahtera) * 100)
|
|
: 0;
|
|
|
|
marker.bindPopup(`
|
|
<div style="font-size:13px; min-width:200px;">
|
|
<b style="font-size:15px;">
|
|
<i class="fa-solid fa-place-of-worship"></i> ${ib.nama_ibadah}
|
|
</b>
|
|
<hr style="margin:6px 0;">
|
|
<b>Jenis:</b> ${ib.jenis}<br>
|
|
<b>Jangkauan Bantuan:</b> ${ib.radius_m} m<br>
|
|
<hr style="margin:6px 0;">
|
|
|
|
<div style="
|
|
background:#f0f4f8;
|
|
border-radius:8px;
|
|
padding:10px;
|
|
margin:6px 0;
|
|
text-align:center;
|
|
">
|
|
<div style="font-size:22px; font-weight:700; color:#1B2A4A;">
|
|
${ib.jumlah_tercakup}
|
|
</div>
|
|
<div style="font-size:11px; color:#666; margin-bottom:6px;">
|
|
rumah tercakup dari ${totalPrasejahtera} total
|
|
</div>
|
|
|
|
<!-- Progress bar -->
|
|
<div style="
|
|
background:#dde3ea;
|
|
border-radius:20px;
|
|
height:6px;
|
|
overflow:hidden;
|
|
">
|
|
<div style="
|
|
background: ${persen > 0 ? '#27ae60' : '#dde3ea'};
|
|
width:${persen}%;
|
|
height:100%;
|
|
border-radius:20px;
|
|
transition: width 0.3s;
|
|
"></div>
|
|
</div>
|
|
<div style="font-size:11px; color:#888; margin-top:4px;">
|
|
${persen}% dari total prasejahtera
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display:flex; gap:6px; margin-top:4px;">
|
|
${ROLE === 'admin' || ROLE === 'operator' ? `
|
|
<button onclick="editIbadah(${ib.id})"
|
|
style="flex:1; padding:6px; background:#2980b9; color:white;
|
|
border:none; border-radius:4px; cursor:pointer; font-size:12px;">
|
|
<i class="fa-solid fa-pen-to-square"></i> Edit
|
|
</button>
|
|
` : ''}
|
|
${ROLE === 'admin' ? `
|
|
<button onclick="hapusIbadah(${ib.id})"
|
|
style="flex:1; padding:6px; background:none; color:red;
|
|
border:1px solid red; border-radius:4px; cursor:pointer; font-size:12px;">
|
|
<i class="fa-solid fa-trash"></i> Hapus
|
|
</button>
|
|
` : ''}
|
|
</div>
|
|
</div>
|
|
`);
|
|
|
|
marker.on('dragend', function(e) {
|
|
let pos = e.target.getLatLng();
|
|
lingkaran.setLatLng(pos);
|
|
dataIbadah[ib.id] = { lat: pos.lat, lng: pos.lng, radius_m: ib.radius_m, lingkaran };
|
|
updateLokasiIbadah(ib.id, pos.lat, pos.lng);
|
|
perbaruiWarnaPrasejahtera();
|
|
});
|
|
|
|
dataIbadah[ib.id] = { lat: ib.lat, lng: ib.lng, radius_m: ib.radius_m, lingkaran };
|
|
daftarMarker['ib_' + ib.id] = marker;
|
|
});
|
|
|
|
// Setelah semua ibadah dimuat, perbarui warna prasejahtera
|
|
perbaruiWarnaPrasejahtera();
|
|
});
|
|
}
|
|
|
|
function formatRupiah(angka) {
|
|
return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR' }).format(angka);
|
|
}
|
|
|
|
function loadDB() {
|
|
fetch('api/prasejahtera/load_prasejahtera.php').then(res => res.json()).then(data => {
|
|
data.forEach(rumah => {
|
|
// PERBAIKAN: Gunakan 'rumah.', bukan 'data.'
|
|
let penghasilanTeks = formatRupiah(rumah.penghasilan);
|
|
let statusOrtuTeks = `<b>Status Ortu:</b> ${rumah.status_ortu}<br>`;
|
|
|
|
if (rumah.status_ortu === 'Bekerja') {
|
|
statusOrtuTeks += `<b>Penghasilan:</b> ${formatRupiah(rumah.penghasilan)}<br>`;
|
|
} else if (rumah.status_ortu === 'Pensiun') {
|
|
statusOrtuTeks += `<b>Uang Pensiun:</b> ${rumah.ada_pensiun === 'Ya' ? formatRupiah(rumah.nominal_pensiun) : 'Tidak Ada'}<br>`;
|
|
} else if (rumah.status_ortu === 'Meninggal') {
|
|
statusOrtuTeks += `<b>Uang Terusan:</b> ${rumah.ada_terusan === 'Ya' ? formatRupiah(rumah.nominal_terusan) : 'Tidak Ada'}<br>`;
|
|
}
|
|
|
|
let isiPopup = `
|
|
<div style="font-size:13px;">
|
|
<b style="font-size:15px;"><i class="fa-solid fa-users"></i> ${rumah.nama_kepala_keluarga}</b><hr style="margin:5px 0;">
|
|
<b>Anak:</b> ${rumah.jumlah_anak} orang (Umur: ${rumah.umur_anak || '-'})<br>
|
|
${statusOrtuTeks}
|
|
<b>Keterangan:</b> ${rumah.keterangan || '-'}<br>
|
|
<hr style="margin: 5px 0;">
|
|
<div style="display:flex; gap:6px;">
|
|
${ROLE === 'admin' || ROLE === 'operator' ? `
|
|
<button onclick="editPrasejahtera(${rumah.id})"
|
|
style="flex:1; padding:6px; background:#2980b9; color:white;
|
|
border:none; border-radius:4px; cursor:pointer; font-size:12px;">
|
|
<i class="fa-solid fa-pen-to-square"></i> Edit
|
|
</button>
|
|
` : ''}
|
|
${ROLE === 'admin' ? `
|
|
<button onclick="hapusPrasejahtera(${rumah.id})"
|
|
style="flex:1; padding:6px; background:none; color:red;
|
|
border:1px solid red; border-radius:4px; cursor:pointer; font-size:12px;">
|
|
<i class="fa-solid fa-trash"></i> Hapus
|
|
</button>
|
|
` : ''}
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
let marker = L.marker([rumah.lat, rumah.lng], {
|
|
icon: ikonPrasejahtera,
|
|
draggable: ROLE === 'admin' || ROLE === 'operator'
|
|
});
|
|
marker.bindPopup(isiPopup);
|
|
marker.on('dragend', function(e) {
|
|
let pos = e.target.getLatLng();
|
|
dataPrasejahtera[rumah.id].lat = pos.lat;
|
|
dataPrasejahtera[rumah.id].lng = pos.lng;
|
|
updateLokasiPrasejahtera(rumah.id, pos.lat, pos.lng);
|
|
perbaruiWarnaPrasejahtera();
|
|
});
|
|
dataPrasejahtera[rumah.id] = { lat: rumah.lat, lng: rumah.lng, marker };
|
|
daftarMarker['p_' + rumah.id] = marker;
|
|
marker.bindPopup(isiPopup);
|
|
marker.on('dragend', function(e) {
|
|
let pos = e.target.getLatLng();
|
|
dataPrasejahtera[rumah.id].lat = pos.lat;
|
|
dataPrasejahtera[rumah.id].lng = pos.lng;
|
|
updateLokasiPrasejahtera(rumah.id, pos.lat, pos.lng);
|
|
perbaruiWarnaPrasejahtera();
|
|
});
|
|
dataPrasejahtera[rumah.id] = { lat: rumah.lat, lng: rumah.lng, marker };
|
|
daftarMarker['p_' + rumah.id] = marker;
|
|
});
|
|
|
|
// Perbarui heatmap setelah data prasejahtera termuat
|
|
if (document.getElementById('checkbox-heatmap')?.checked) {
|
|
buatHeatmap();
|
|
heatmapAktif = true;
|
|
}
|
|
|
|
// Muat ibadah SETELAH prasejahtera selesai
|
|
loadIbadah();
|
|
});
|
|
}
|
|
loadDB();
|
|
|
|
// --- FUNGSI UNTUK ME-REFRESH PETA SECARA OTOMATIS (SOFT REFRESH) ---
|
|
function refreshPeta() {
|
|
layerTercakup.clearLayers();
|
|
layerTidakTercakup.clearLayers();
|
|
layerIbadah.clearLayers();
|
|
layerRadius.clearLayers();
|
|
|
|
// 2. Bersihkan memori agar ID tidak menumpuk/ganda
|
|
for (let id in dataIbadah) delete dataIbadah[id];
|
|
for (let id in dataPrasejahtera) delete dataPrasejahtera[id];
|
|
|
|
// 3. Panggil ulang data terbaru dari database
|
|
loadDB();
|
|
|
|
if (heatmapAktif) buatHeatmap();
|
|
}
|
|
|
|
// --- EVENT KLIK PETA ---
|
|
function onMapClick(e) {
|
|
if (ROLE === 'viewer') return;
|
|
|
|
if (currentMode === 'point') {
|
|
let formHtml = `
|
|
<div style="width: 200px;">
|
|
<h4 style="margin-top:0; border-bottom:1px solid #ddd; padding-bottom:5px;"><i class="fa-solid fa-gas-pump"></i> SPBU Baru</h4>
|
|
<form onsubmit="simpanSPBU(event, ${e.latlng.lat}, ${e.latlng.lng})">
|
|
<input type="text" id="nama_spbu" placeholder="Nama SPBU" required style="width: 100%; margin-bottom: 8px; padding:6px; box-sizing:border-box;">
|
|
<input type="tel" id="no_wa" placeholder="No WhatsApp" required style="width: 100%; margin-bottom: 8px; padding:6px; box-sizing:border-box;">
|
|
<label style="font-size:12px; font-weight:bold;">Buka 24 Jam?</label><br>
|
|
<label><input type="radio" name="buka_24jam" value="1" required> Ya</label>
|
|
<label><input type="radio" name="buka_24jam" value="0"> Tidak</label><br><br>
|
|
<button type="submit" style="width: 100%; padding: 8px; background:#2ecc71; color:#fff; border:none; border-radius:4px; font-weight:bold; cursor:pointer;"><i class="fa-solid fa-save"></i> Simpan Data</button>
|
|
</form>
|
|
</div>`;
|
|
popup.setLatLng(e.latlng).setContent(formHtml).openOn(map);
|
|
} else if (currentMode === 'polyline') {
|
|
tempLatLngs.push(e.latlng);
|
|
if (!tempPolyline) tempPolyline = L.polyline(tempLatLngs, {color: '#3498db', weight: 4}).addTo(map);
|
|
else tempPolyline.setLatLngs(tempLatLngs);
|
|
} else if (currentMode === 'polygon') {
|
|
tempPolygonLatLngs.push(e.latlng);
|
|
if (!tempPolygon) tempPolygon = L.polygon(tempPolygonLatLngs, {color: '#2ecc71', fillColor: '#2ecc71', fillOpacity: 0.4}).addTo(map);
|
|
else tempPolygon.setLatLngs(tempPolygonLatLngs);
|
|
} else if (currentMode === 'prasejahtera') {
|
|
let formHtml = `
|
|
<div style="width: 250px;">
|
|
<h4 style="margin-top:0; border-bottom:1px solid #ddd; padding-bottom:5px;"><i class="fa-solid fa-home"></i> Data Prasejahtera</h4>
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Nama Kepala Keluarga:</label>
|
|
<input type="text" id="nama_kk" style="width: 100%; margin-bottom: 8px; padding:4px;">
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Jumlah Anak:</label>
|
|
<input type="number" id="jumlah_anak" value="0" style="width: 100%; margin-bottom: 8px; padding:4px;">
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Umur Anak (Pisahkan dgn koma):</label>
|
|
<input type="text" id="umur_anak" placeholder="Contoh: 15, 12, 8" style="width: 100%; margin-bottom: 8px; padding:4px;">
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Status Orang Tua:</label>
|
|
<select id="status_ortu" onchange="toggleStatusOrtu()" style="width: 100%; margin-bottom: 8px; padding:4px;">
|
|
<option value="Bekerja">Bekerja</option>
|
|
<option value="Pensiun">Pensiun</option>
|
|
<option value="Meninggal">Meninggal Dunia</option>
|
|
</select>
|
|
|
|
<div id="grup_bekerja" style="display:block; background:#e8f8f5; padding:5px; border-radius:4px; margin-bottom:8px;">
|
|
<label style="font-size:12px; font-weight:bold;">Penghasilan/Bulan (Rp):</label>
|
|
<input type="number" id="penghasilan" value="0" style="width: 100%; padding:4px;">
|
|
</div>
|
|
|
|
<div id="grup_pensiun" style="display:none; background:#fef9e7; padding:5px; border-radius:4px; margin-bottom:8px;">
|
|
<label style="font-size:12px; font-weight:bold;">Ada Uang Pensiun?</label>
|
|
<select id="ada_pensiun" onchange="togglePensiun()" style="width: 100%; margin-bottom: 5px; padding:4px;">
|
|
<option value="Tidak">Tidak Ada</option>
|
|
<option value="Ya">Ya, Ada</option>
|
|
</select>
|
|
<div id="grup_nominal_pensiun" style="display:none;">
|
|
<label style="font-size:12px; font-weight:bold;">Nominal Pensiun (Rp):</label>
|
|
<input type="number" id="nominal_pensiun" value="0" style="width: 100%; padding:4px;">
|
|
</div>
|
|
</div>
|
|
|
|
<div id="grup_meninggal" style="display:none; background:#fdedec; padding:5px; border-radius:4px; margin-bottom:8px;">
|
|
<label style="font-size:12px; font-weight:bold;">Ada Uang Terusan?</label>
|
|
<select id="ada_terusan" onchange="toggleTerusan()" style="width: 100%; margin-bottom: 5px; padding:4px;">
|
|
<option value="Tidak">Tidak Ada</option>
|
|
<option value="Ya">Ya, Ada</option>
|
|
</select>
|
|
<div id="grup_nominal_terusan" style="display:none;">
|
|
<label style="font-size:12px; font-weight:bold;">Nominal Terusan (Rp):</label>
|
|
<input type="number" id="nominal_terusan" value="0" style="width: 100%; padding:4px;">
|
|
</div>
|
|
</div>
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Keterangan Tambahan:</label>
|
|
<textarea id="keterangan" style="width: 100%; margin-bottom: 10px; padding:4px;"></textarea>
|
|
|
|
<button type="button" onclick="simpanPrasejahtera(${e.latlng.lat}, ${e.latlng.lng})" style="width: 100%; padding: 8px; background:#2ecc71; color:#fff; border:none; border-radius:4px; font-weight:bold; cursor:pointer;">
|
|
<i class="fa-solid fa-save"></i> Simpan Data
|
|
</button>
|
|
</div>
|
|
`;
|
|
popup.setLatLng(e.latlng).setContent(formHtml).openOn(map);
|
|
} else if (currentMode === 'ibadah') {
|
|
let formHtml = `
|
|
<div style="width: 220px;">
|
|
<h4 style="margin-top:0; border-bottom:1px solid #ddd; padding-bottom:5px;">
|
|
<i class="fa-solid fa-place-of-worship"></i> Rumah Ibadah
|
|
</h4>
|
|
<form onsubmit="simpanIbadah(event, ${e.latlng.lat}, ${e.latlng.lng})">
|
|
<label style="font-size:12px; font-weight:bold;">Jenis:</label>
|
|
<select id="jenis_ibadah" style="width:100%; margin-bottom:8px; padding:6px; box-sizing:border-box;">
|
|
<option value="Masjid">🕌 Masjid</option>
|
|
<option value="Gereja">⛪ Gereja</option>
|
|
<option value="Vihara">🛕 Vihara</option>
|
|
<option value="Pura">🪔 Pura</option>
|
|
<option value="Klenteng">🏮 Klenteng</option>
|
|
</select>
|
|
<input type="text" id="nama_ibadah" placeholder="Nama Rumah Ibadah" required
|
|
style="width:100%; margin-bottom:8px; padding:6px; box-sizing:border-box;">
|
|
<label style="font-size:12px; font-weight:bold;">Radius Bantuan (meter):</label>
|
|
<input type="number" id="radius_ibadah" value="500" min="50" max="5000" required
|
|
style="width:100%; margin-bottom:8px; padding:6px; box-sizing:border-box;">
|
|
<button type="submit" style="width:100%; padding:8px; background:#8e44ad; color:#fff; border:none; border-radius:4px; font-weight:bold; cursor:pointer;">
|
|
<i class="fa-solid fa-save"></i> Simpan
|
|
</button>
|
|
</form>
|
|
</div>`;
|
|
popup.setLatLng(e.latlng).setContent(formHtml).openOn(map);
|
|
}
|
|
}
|
|
map.on('click', onMapClick);
|
|
|
|
function simpanPrasejahtera(lat, lng) {
|
|
// 1. Validasi Manual
|
|
let nama_kk = document.getElementById('nama_kk').value.trim();
|
|
if (!nama_kk || nama_kk === "") {
|
|
Toast.fire({ icon: 'warning', title: 'Nama Kepala Keluarga wajib diisi!' });
|
|
return; // Hentikan proses eksekusi jika kosong
|
|
}
|
|
|
|
// 2. Susun Data
|
|
let dataKirim = {
|
|
lat: lat, lng: lng,
|
|
nama_kk: nama_kk,
|
|
penghasilan: parseInt(document.getElementById('penghasilan').value) || 0,
|
|
jumlah_anak: parseInt(document.getElementById('jumlah_anak').value) || 0,
|
|
umur_anak: document.getElementById('umur_anak').value,
|
|
status_ortu: document.getElementById('status_ortu').value,
|
|
ada_pensiun: document.getElementById('ada_pensiun').value,
|
|
nominal_pensiun: parseInt(document.getElementById('nominal_pensiun').value) || 0,
|
|
ada_terusan: document.getElementById('ada_terusan').value,
|
|
nominal_terusan: parseInt(document.getElementById('nominal_terusan').value) || 0,
|
|
keterangan: document.getElementById('keterangan').value
|
|
};
|
|
|
|
// 3. Kirim ke Database
|
|
fetch('api/prasejahtera/simpan_prasejahtera.php', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify(dataKirim)
|
|
})
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
Toast.fire({ icon: 'success', title: 'Data Berhasil Disimpan!' });
|
|
map.closePopup();
|
|
refreshPeta(); // Sinkronisasi seketika
|
|
} else {
|
|
Toast.fire({ icon: 'error', title: 'Gagal Menyimpan: ' + (data.message || 'Error Database') });
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error("Terjadi masalah:", error);
|
|
Toast.fire({ icon: 'error', title: 'Koneksi ke Server Gagal!' });
|
|
});
|
|
}
|
|
|
|
function hapusPrasejahtera(id) {
|
|
Swal.fire({ title: 'Hapus data ini?', icon: 'warning', showCancelButton: true,
|
|
confirmButtonColor: '#d33', cancelButtonColor: '#3085d6',
|
|
confirmButtonText: 'Ya, Hapus!', cancelButtonText: 'Batal'
|
|
}).then(result => {
|
|
if (result.isConfirmed) {
|
|
fetch('api/prasejahtera/hapus_prasejahtera.php', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ id: id }) })
|
|
.then(res => res.json()).then(data => {
|
|
if (data.status === 'success') {
|
|
Toast.fire({ icon: 'success', title: 'Data Dihapus!' });
|
|
|
|
// Cukup panggil fungsi ini, Leaflet akan menyapu bersih peta
|
|
// dan memanggil ulang data terbaru dari database secara otomatis!
|
|
refreshPeta();
|
|
|
|
} else Toast.fire({ icon: 'error', title: 'Gagal Menghapus!' });
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateLokasiPrasejahtera(id, lat, lng) {
|
|
fetch('api/prasejahtera/update_prasejahtera.php', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ id, lat, lng }) })
|
|
.then(res => res.json()).then(data => { if (data.status === 'success') Toast.fire({ icon: 'info', title: 'Posisi Diperbarui' }); });
|
|
}
|
|
|
|
function simpanIbadah(event, lat, lng) {
|
|
event.preventDefault();
|
|
let dataKirim = {
|
|
lat, lng,
|
|
nama_ibadah: document.getElementById('nama_ibadah').value,
|
|
jenis: document.getElementById('jenis_ibadah').value,
|
|
radius_m: parseInt(document.getElementById('radius_ibadah').value)
|
|
};
|
|
fetch('api/rumahibadah/simpan_ibadah.php', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(dataKirim) })
|
|
.then(res => res.json()).then(data => {
|
|
if (data.status === 'success') {
|
|
Toast.fire({ icon: 'success', title: 'Rumah Ibadah Disimpan!' });
|
|
map.closePopup();
|
|
refreshPeta();
|
|
} else Toast.fire({ icon: 'error', title: 'Gagal Menyimpan!' });
|
|
});
|
|
}
|
|
|
|
function hapusIbadah(id) {
|
|
Swal.fire({ title: 'Hapus Rumah Ibadah?', icon: 'warning', showCancelButton: true,
|
|
confirmButtonColor: '#d33', cancelButtonColor: '#3085d6',
|
|
confirmButtonText: 'Ya, Hapus!', cancelButtonText: 'Batal'
|
|
}).then(result => {
|
|
if (result.isConfirmed) {
|
|
fetch('api/rumahibadah/hapus_ibadah.php', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ id }) })
|
|
.then(res => res.json()).then(data => {
|
|
if (data.status === 'success') {
|
|
Toast.fire({ icon: 'success', title: 'Data Dihapus!' });
|
|
|
|
// Gunakan refreshPeta agar sinkron dengan database 100%
|
|
refreshPeta();
|
|
|
|
} else Toast.fire({ icon: 'error', title: 'Gagal Menghapus!' });
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateLokasiIbadah(id, lat, lng) {
|
|
fetch('api/rumahibadah/update_ibadah.php', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ id, lat, lng }) })
|
|
.then(res => res.json()).then(data => { if (data.status === 'success') Toast.fire({ icon: 'info', title: 'Posisi Diperbarui' }); });
|
|
}
|
|
|
|
// --- FUNGSI TOGGLE FORM PRASEJAHTERA ---
|
|
function toggleStatusOrtu() {
|
|
let status = document.getElementById('status_ortu').value;
|
|
|
|
// Atur visibilitas grup
|
|
document.getElementById('grup_bekerja').style.display = (status === 'Bekerja') ? 'block' : 'none';
|
|
document.getElementById('grup_pensiun').style.display = (status === 'Pensiun') ? 'block' : 'none';
|
|
document.getElementById('grup_meninggal').style.display = (status === 'Meninggal') ? 'block' : 'none';
|
|
|
|
// Reset nilai yang tersembunyi agar tidak ikut tersimpan salah
|
|
if(status !== 'Bekerja') document.getElementById('penghasilan').value = 0;
|
|
if(status !== 'Pensiun') { document.getElementById('ada_pensiun').value = 'Tidak'; togglePensiun(); }
|
|
if(status !== 'Meninggal') { document.getElementById('ada_terusan').value = 'Tidak'; toggleTerusan(); }
|
|
}
|
|
|
|
function togglePensiun() {
|
|
let ada = document.getElementById('ada_pensiun').value;
|
|
document.getElementById('grup_nominal_pensiun').style.display = (ada === 'Ya') ? 'block' : 'none';
|
|
if(ada === 'Tidak') document.getElementById('nominal_pensiun').value = 0;
|
|
}
|
|
|
|
function toggleTerusan() {
|
|
let ada = document.getElementById('ada_terusan').value;
|
|
document.getElementById('grup_nominal_terusan').style.display = (ada === 'Ya') ? 'block' : 'none';
|
|
if(ada === 'Tidak') document.getElementById('nominal_terusan').value = 0;
|
|
}
|
|
|
|
// --- EDIT PRASEJAHTERA ---
|
|
function editPrasejahtera(id) {
|
|
fetch(`api/prasejahtera/get_prasejahtera.php?id=${id}`)
|
|
.then(res => res.json())
|
|
.then(d => {
|
|
let formHtml = `
|
|
<div style="width: 250px;">
|
|
<h4 style="margin-top:0; border-bottom:1px solid #ddd; padding-bottom:5px;">
|
|
<i class="fa-solid fa-pen-to-square"></i> Edit Data Prasejahtera
|
|
</h4>
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Nama Kepala Keluarga:</label>
|
|
<input type="text" id="edit_nama_kk" value="${d.nama_kepala_keluarga}"
|
|
style="width:100%; margin-bottom:8px; padding:4px;">
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Jumlah Anak:</label>
|
|
<input type="number" id="edit_jumlah_anak" value="${d.jumlah_anak}"
|
|
style="width:100%; margin-bottom:8px; padding:4px;">
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Umur Anak (pisahkan dgn koma):</label>
|
|
<input type="text" id="edit_umur_anak" value="${d.umur_anak || ''}"
|
|
placeholder="Contoh: 15, 12, 8"
|
|
style="width:100%; margin-bottom:8px; padding:4px;">
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Status Orang Tua:</label>
|
|
<select id="edit_status_ortu" onchange="toggleEditStatusOrtu()"
|
|
style="width:100%; margin-bottom:8px; padding:4px;">
|
|
<option value="Bekerja" ${d.status_ortu === 'Bekerja' ? 'selected' : ''}>Bekerja</option>
|
|
<option value="Pensiun" ${d.status_ortu === 'Pensiun' ? 'selected' : ''}>Pensiun</option>
|
|
<option value="Meninggal" ${d.status_ortu === 'Meninggal' ? 'selected' : ''}>Meninggal Dunia</option>
|
|
</select>
|
|
|
|
<div id="edit_grup_bekerja" style="display:${d.status_ortu === 'Bekerja' ? 'block' : 'none'};
|
|
background:#e8f8f5; padding:5px; border-radius:4px; margin-bottom:8px;">
|
|
<label style="font-size:12px; font-weight:bold;">Penghasilan/Bulan (Rp):</label>
|
|
<input type="number" id="edit_penghasilan" value="${d.penghasilan || 0}"
|
|
style="width:100%; padding:4px;">
|
|
</div>
|
|
|
|
<div id="edit_grup_pensiun" style="display:${d.status_ortu === 'Pensiun' ? 'block' : 'none'};
|
|
background:#fef9e7; padding:5px; border-radius:4px; margin-bottom:8px;">
|
|
<label style="font-size:12px; font-weight:bold;">Ada Uang Pensiun?</label>
|
|
<select id="edit_ada_pensiun" onchange="toggleEditPensiun()"
|
|
style="width:100%; margin-bottom:5px; padding:4px;">
|
|
<option value="Tidak" ${d.ada_pensiun === 'Tidak' ? 'selected' : ''}>Tidak Ada</option>
|
|
<option value="Ya" ${d.ada_pensiun === 'Ya' ? 'selected' : ''}>Ya, Ada</option>
|
|
</select>
|
|
<div id="edit_grup_nominal_pensiun" style="display:${d.ada_pensiun === 'Ya' ? 'block' : 'none'};">
|
|
<label style="font-size:12px; font-weight:bold;">Nominal Pensiun (Rp):</label>
|
|
<input type="number" id="edit_nominal_pensiun" value="${d.nominal_pensiun || 0}"
|
|
style="width:100%; padding:4px;">
|
|
</div>
|
|
</div>
|
|
|
|
<div id="edit_grup_meninggal" style="display:${d.status_ortu === 'Meninggal' ? 'block' : 'none'};
|
|
background:#fdedec; padding:5px; border-radius:4px; margin-bottom:8px;">
|
|
<label style="font-size:12px; font-weight:bold;">Ada Uang Terusan?</label>
|
|
<select id="edit_ada_terusan" onchange="toggleEditTerusan()"
|
|
style="width:100%; margin-bottom:5px; padding:4px;">
|
|
<option value="Tidak" ${d.ada_terusan === 'Tidak' ? 'selected' : ''}>Tidak Ada</option>
|
|
<option value="Ya" ${d.ada_terusan === 'Ya' ? 'selected' : ''}>Ya, Ada</option>
|
|
</select>
|
|
<div id="edit_grup_nominal_terusan" style="display:${d.ada_terusan === 'Ya' ? 'block' : 'none'};">
|
|
<label style="font-size:12px; font-weight:bold;">Nominal Terusan (Rp):</label>
|
|
<input type="number" id="edit_nominal_terusan" value="${d.nominal_terusan || 0}"
|
|
style="width:100%; padding:4px;">
|
|
</div>
|
|
</div>
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Keterangan Tambahan:</label>
|
|
<textarea id="edit_keterangan" style="width:100%; margin-bottom:10px; padding:4px;">${d.keterangan || ''}</textarea>
|
|
|
|
<button onclick="simpanEditPrasejahtera(${id})"
|
|
style="width:100%; padding:8px; background:#2980b9; color:white;
|
|
border:none; border-radius:4px; font-weight:bold; cursor:pointer;">
|
|
<i class="fa-solid fa-save"></i> Simpan Perubahan
|
|
</button>
|
|
</div>`;
|
|
|
|
// Ganti konten popup yang sudah terbuka dengan form edit
|
|
daftarMarker['p_' + id].getPopup().setContent(formHtml);
|
|
})
|
|
.catch(() => Toast.fire({ icon: 'error', title: 'Gagal memuat data!' }));
|
|
}
|
|
|
|
function toggleEditStatusOrtu() {
|
|
let status = document.getElementById('edit_status_ortu').value;
|
|
document.getElementById('edit_grup_bekerja').style.display = status === 'Bekerja' ? 'block' : 'none';
|
|
document.getElementById('edit_grup_pensiun').style.display = status === 'Pensiun' ? 'block' : 'none';
|
|
document.getElementById('edit_grup_meninggal').style.display = status === 'Meninggal' ? 'block' : 'none';
|
|
if (status !== 'Bekerja') document.getElementById('edit_penghasilan').value = 0;
|
|
if (status !== 'Pensiun') { document.getElementById('edit_ada_pensiun').value = 'Tidak'; toggleEditPensiun(); }
|
|
if (status !== 'Meninggal') { document.getElementById('edit_ada_terusan').value = 'Tidak'; toggleEditTerusan(); }
|
|
}
|
|
|
|
function toggleEditPensiun() {
|
|
let ada = document.getElementById('edit_ada_pensiun').value;
|
|
document.getElementById('edit_grup_nominal_pensiun').style.display = ada === 'Ya' ? 'block' : 'none';
|
|
if (ada === 'Tidak') document.getElementById('edit_nominal_pensiun').value = 0;
|
|
}
|
|
|
|
function toggleEditTerusan() {
|
|
let ada = document.getElementById('edit_ada_terusan').value;
|
|
document.getElementById('edit_grup_nominal_terusan').style.display = ada === 'Ya' ? 'block' : 'none';
|
|
if (ada === 'Tidak') document.getElementById('edit_nominal_terusan').value = 0;
|
|
}
|
|
|
|
function simpanEditPrasejahtera(id) {
|
|
let nama_kk = document.getElementById('edit_nama_kk').value.trim();
|
|
if (!nama_kk) {
|
|
Toast.fire({ icon: 'warning', title: 'Nama Kepala Keluarga wajib diisi!' });
|
|
return;
|
|
}
|
|
|
|
let dataKirim = {
|
|
id: id,
|
|
nama_kk: nama_kk,
|
|
jumlah_anak: parseInt(document.getElementById('edit_jumlah_anak').value) || 0,
|
|
umur_anak: document.getElementById('edit_umur_anak').value,
|
|
status_ortu: document.getElementById('edit_status_ortu').value,
|
|
penghasilan: parseInt(document.getElementById('edit_penghasilan').value) || 0,
|
|
ada_pensiun: document.getElementById('edit_ada_pensiun').value,
|
|
nominal_pensiun: parseInt(document.getElementById('edit_nominal_pensiun').value) || 0,
|
|
ada_terusan: document.getElementById('edit_ada_terusan').value,
|
|
nominal_terusan: parseInt(document.getElementById('edit_nominal_terusan').value) || 0,
|
|
keterangan: document.getElementById('edit_keterangan').value
|
|
};
|
|
|
|
fetch('api/prasejahtera/update_prasejahtera.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(dataKirim)
|
|
})
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
Toast.fire({ icon: 'success', title: 'Data Berhasil Diperbarui!' });
|
|
map.closePopup();
|
|
refreshPeta();
|
|
} else {
|
|
Toast.fire({ icon: 'error', title: 'Gagal: ' + (data.message || 'Error') });
|
|
}
|
|
});
|
|
}
|
|
|
|
// --- EDIT IBADAH ---
|
|
function editIbadah(id) {
|
|
fetch(`api/rumahibadah/get_ibadah.php?id=${id}`)
|
|
.then(res => res.json())
|
|
.then(d => {
|
|
let jenisOptions = ['Masjid', 'Gereja', 'Vihara', 'Pura', 'Klenteng'].map(j =>
|
|
`<option value="${j}" ${d.jenis === j ? 'selected' : ''}>${j}</option>`
|
|
).join('');
|
|
|
|
let formHtml = `
|
|
<div style="width: 220px;">
|
|
<h4 style="margin-top:0; border-bottom:1px solid #ddd; padding-bottom:5px;">
|
|
<i class="fa-solid fa-pen-to-square"></i> Edit Rumah Ibadah
|
|
</h4>
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Jenis:</label>
|
|
<select id="edit_jenis_ibadah" style="width:100%; margin-bottom:8px; padding:6px; box-sizing:border-box;">
|
|
${jenisOptions}
|
|
</select>
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Nama Rumah Ibadah:</label>
|
|
<input type="text" id="edit_nama_ibadah" value="${d.nama_ibadah}"
|
|
style="width:100%; margin-bottom:8px; padding:6px; box-sizing:border-box;">
|
|
|
|
<label style="font-size:12px; font-weight:bold;">Radius Bantuan (meter):</label>
|
|
<input type="number" id="edit_radius_ibadah" value="${d.radius_m}"
|
|
min="50" max="5000"
|
|
style="width:100%; margin-bottom:12px; padding:6px; box-sizing:border-box;">
|
|
|
|
<button onclick="simpanEditIbadah(${id})"
|
|
style="width:100%; padding:8px; background:#8e44ad; color:white;
|
|
border:none; border-radius:4px; font-weight:bold; cursor:pointer;">
|
|
<i class="fa-solid fa-save"></i> Simpan Perubahan
|
|
</button>
|
|
</div>`;
|
|
|
|
daftarMarker['ib_' + id].getPopup().setContent(formHtml);
|
|
})
|
|
.catch(() => Toast.fire({ icon: 'error', title: 'Gagal memuat data!' }));
|
|
}
|
|
|
|
function simpanEditIbadah(id) {
|
|
let nama = document.getElementById('edit_nama_ibadah').value.trim();
|
|
if (!nama) {
|
|
Toast.fire({ icon: 'warning', title: 'Nama Rumah Ibadah wajib diisi!' });
|
|
return;
|
|
}
|
|
|
|
let dataKirim = {
|
|
id: id,
|
|
nama_ibadah: nama,
|
|
jenis: document.getElementById('edit_jenis_ibadah').value,
|
|
radius_m: parseInt(document.getElementById('edit_radius_ibadah').value)
|
|
};
|
|
|
|
fetch('api/rumahibadah/update_ibadah.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(dataKirim)
|
|
})
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
Toast.fire({ icon: 'success', title: 'Rumah Ibadah Diperbarui!' });
|
|
map.closePopup();
|
|
refreshPeta();
|
|
} else {
|
|
Toast.fire({ icon: 'error', title: 'Gagal: ' + (data.message || 'Error') });
|
|
}
|
|
});
|
|
}
|
|
|
|
// --- HEATMAP ---
|
|
let heatmapLayer = null;
|
|
let heatmapAktif = false;
|
|
|
|
function toggleHeatmap() {
|
|
let checkbox = document.getElementById('checkbox-heatmap');
|
|
|
|
if (checkbox.checked) {
|
|
buatHeatmap();
|
|
heatmapAktif = true;
|
|
} else {
|
|
if (heatmapLayer) map.removeLayer(heatmapLayer);
|
|
heatmapAktif = false;
|
|
}
|
|
}
|
|
|
|
function buatHeatmap() {
|
|
// Ambil koordinat dari dataPrasejahtera yang sudah ada di memori
|
|
let points = [];
|
|
for (let id in dataPrasejahtera) {
|
|
let p = dataPrasejahtera[id];
|
|
points.push([p.lat, p.lng, 1]); // [lat, lng, intensity]
|
|
}
|
|
|
|
// Hapus layer lama kalau ada
|
|
if (heatmapLayer) map.removeLayer(heatmapLayer);
|
|
|
|
heatmapLayer = L.heatLayer(points, {
|
|
radius: 35, // ukuran area panas per titik
|
|
blur: 25, // tingkat kehalusan gradasi
|
|
maxZoom: 17, // zoom maksimal sebelum intensitas penuh
|
|
max: 1.0,
|
|
gradient: {
|
|
0.2: '#3498db', // biru = kepadatan rendah
|
|
0.5: '#f1c40f', // kuning = kepadatan sedang
|
|
0.8: '#e67e22', // oranye = kepadatan tinggi
|
|
1.0: '#e74c3c' // merah = kepadatan sangat tinggi
|
|
}
|
|
}).addTo(map);
|
|
}
|
|
|
|
function updateRingkasan() {
|
|
let totalPrasejahtera = Object.keys(dataPrasejahtera).length;
|
|
let totalIbadah = Object.keys(dataIbadah).length;
|
|
let totalTercakup = layerTercakup.getLayers().length;
|
|
let totalTidak = layerTidakTercakup.getLayers().length;
|
|
let persen = totalPrasejahtera > 0
|
|
? Math.round((totalTercakup / totalPrasejahtera) * 100) : 0;
|
|
|
|
document.getElementById('stat-total').textContent = totalPrasejahtera;
|
|
document.getElementById('stat-tercakup').textContent = totalTercakup;
|
|
document.getElementById('stat-tidak').textContent = totalTidak;
|
|
document.getElementById('stat-persen').textContent = persen + '%';
|
|
document.getElementById('stat-ibadah').textContent = totalIbadah;
|
|
|
|
// Update progress bar
|
|
document.getElementById('stat-progress').style.width = persen + '%';
|
|
|
|
// Warna progress bar berdasarkan persentase
|
|
let warna = persen >= 70 ? '#27ae60' : persen >= 40 ? '#f39c12' : '#e74c3c';
|
|
document.getElementById('stat-progress').style.background = warna;
|
|
} |