// =========================================================================
// FILE: assets/js/webgis.js
// Otak Front-End untuk Peta Bansos (Melayani Admin Lokal & Super Admin)
// =========================================================================
// Variabel Global Leaflet
let tempLat, tempLng;
const map = L.map('map', { zoomControl: false }).setView([-0.0263, 109.3425], 13);
L.control.zoom({ position: 'topright' }).addTo(map);
const baseOsm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap' }).addTo(map);
// Inisialisasi Ikon
const redIcon = 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] });
const greenIcon = 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] });
const violetIcon = new L.Icon({ iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-violet.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] });
const daruratIcon = new L.Icon({ iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-orange.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], className: 'marker-darurat' });
const layerIbadah = L.layerGroup().addTo(map);
const layerPenduduk = L.layerGroup().addTo(map);
let searchableLayers = [];
// --- UTILITAS UMUM ---
window.konfirmasiLogout = function(urlLogout) {
if(confirm("Apakah Anda yakin ingin keluar dari sistem?")) { window.location.href = urlLogout; }
}
window.tutupModal = function(modalId) { document.getElementById(modalId).style.display = "none"; }
window.onclick = function(event) { if (event.target.classList.contains('modal')) { event.target.style.display = "none"; } }
window.toggleOpsiLanjutan = function(id) {
let el = document.getElementById('opsi-' + id);
el.style.display = (el.style.display === 'none') ? 'block' : 'none';
}
window.cariLokasiSaya = function() { map.locate({setView: true, maxZoom: 16}); }
map.on('locationfound', function(e) { L.marker(e.latlng).addTo(map).bindPopup("๐ Anda di sini.").openPopup(); });
async function getAlamatOtomatis(lat, lng) {
try {
const r = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`);
const d = await r.json();
if(d && d.address) return [d.address.road, d.address.village||d.address.suburb, d.address.city_district].filter(Boolean).join(", ");
} catch (e) {} return "";
}
window.cariData = function() {
const kw = document.getElementById('searchInput').value.toLowerCase().trim(); if (!kw) return;
let f = false;
for (let i of searchableLayers) {
if (i.nama && i.nama.toLowerCase().includes(kw)) { map.flyTo(i.layer.getLatLng(), 18); i.layer.openPopup(); f = true; break; }
}
if (!f) alert("Data tidak ditemukan!");
}
window.handleEnter = function(e) { if (e.key === 'Enter') cariData(); }
// --- FUNGSI RENDER PETA (DIPANGGIL DARI PHP HTML) ---
function initWebGIS() {
// Kalkulasi Jarak & Radius Warga ke Institusi terdekat
DATA_PENDUDUK.forEach(p => {
let latlngPenduduk = L.latLng(p.latitude, p.longitude);
let minDist = Infinity; let closestIbadah = null;
DATA_IBADAH.forEach(ib => {
let dist = latlngPenduduk.distanceTo(L.latLng(ib.latitude, ib.longitude));
if (dist < minDist) { minDist = dist; closestIbadah = ib; }
});
p.closestIbadah = closestIbadah;
p.minDist = minDist;
p.isInside = (closestIbadah && minDist <= closestIbadah.radius);
if (p.isInside && closestIbadah) {
let ibadahIndex = DATA_IBADAH.findIndex(ib => ib.id === closestIbadah.id);
if(ibadahIndex !== -1) DATA_IBADAH[ibadahIndex].warga_count++;
}
});
// Render Tempat Ibadah
DATA_IBADAH.forEach(ib => {
const marker = L.marker([ib.latitude, ib.longitude], { icon: violetIcon });
let ibadahControls = IS_SUPER_ADMIN ? `
Edit Profil
Hapus
` : '';
let htmlPopup = `
`;
marker.bindPopup(htmlPopup);
marker.addTo(layerIbadah);
L.circle([ib.latitude, ib.longitude], { radius: ib.radius, color: 'violet', fillOpacity: 0.1 }).addTo(layerIbadah);
searchableLayers.push({ nama: ib.nama, layer: marker, tipe: 'titik' });
});
// Render Warga Miskin
DATA_PENDUDUK.forEach(p => {
let isDarurat = p.is_darurat > 0;
let idMusibahAktif = p.id_musibah_aktif ? p.id_musibah_aktif : 'null';
let iconPenduduk = isDarurat ? daruratIcon : (p.isInside ? greenIcon : redIcon);
let statusBadge = ""; let statusLabel = "";
let statusKemiskinan = p.status_kemiskinan || "Data Belum Lengkap";
if (statusKemiskinan === "Data Belum Lengkap" || (!p.skor_aset && !p.pengeluaran)) {
statusBadge = "bg-gray"; statusLabel = "Data Belum Lengkap";
} else if (statusKemiskinan === "Sangat Miskin") {
statusBadge = "bg-red"; statusLabel = "SANGAT MISKIN (P1)";
} else if (statusKemiskinan === "Miskin") {
statusBadge = "bg-orange"; statusLabel = "MISKIN (P2)";
} else {
statusBadge = "bg-yellow"; statusLabel = "RENTAN MISKIN";
}
let radiusText = '';
let actionButtons = '';
let isOwnedByAdmin = IS_SUPER_ADMIN ? true : (p.closestIbadah && p.closestIbadah.id == ADMIN_ID_IBADAH && p.isInside);
let bannerDarurat = isDarurat ? `
๐จ STATUS DARURAT MUSIBAH
` : '';
if (p.isInside || IS_SUPER_ADMIN) {
radiusText = p.isInside ? `๐ข Masuk area ${p.closestIbadah.nama} ` : `๐ด Di luar jangkauan (Bypass Super Admin)`;
if (isOwnedByAdmin) {
let btnBantuanHtml = (!IS_SUPER_ADMIN) ? `๐ฆ Catat Penyaluran Bantuan ` : '';
actionButtons = `
${btnBantuanHtml}
๐จ Lapor Musibah Darurat
๐จโ๐ฉโ๐งโ๐ฆ Data Keluarga & Pelatihan
โ๏ธ Opsi Lanjutan โผ
๐ Lihat Riwayat Bantuan
๐ Lihat Log Pelatihan
Edit Data Induk
Hapus Rumah
`;
} else {
actionButtons = `Wewenang: ${p.closestIbadah.nama}
`;
}
} else {
radiusText = `๐ด Di Luar Jangkauan Bantuan`;
actionButtons = `Tidak masuk radius wewenang tempat ibadah manapun.
`;
}
let marker = L.marker([p.latitude, p.longitude], { icon: iconPenduduk }).bindPopup(`
`);
marker.addTo(layerPenduduk);
searchableLayers.push({ nama: p.nama_kk, layer: marker, tipe: 'titik' });
});
// Menampilkan Layer
loadBasemap(layerPenduduk, layerIbadah);
}
// --- FUNGSI LOAD KECAMATAN JSON ---
async function loadBasemap(layerPenduduk, layerIbadah) {
const adminGrp = L.layerGroup().addTo(map);
try {
// PERHATIAN: Sesuaikan URL json ini jika Anda memindahkannya ke folder assets
const dataAdmin = await (await fetch('assets/data/Admin_Kecamatan.json')).json();
L.geoJSON(dataAdmin, {
style: function (f) {
const n = (f.properties.Ket || "").toUpperCase();
let c = "#ccc";
if(n.includes("BARAT")) c="#e41a1c"; else if(n.includes("KOTA")) c="#377eb8"; else if(n.includes("SELATAN")) c="#4daf4a";
else if(n.includes("TENGGARA")) c="#984ea3"; else if(n.includes("TIMUR")) c="#ff7f00"; else if(n.includes("UTARA")) c="#f1c40f";
return { color: "black", weight: 2, fillOpacity: 0.2, fillColor: c };
},
onEachFeature: function (f, layer) {
const p = new Intl.NumberFormat('id-ID').format(f.properties.penduduk || 0);
layer.bindPopup(`Kecamatan ${f.properties.Ket || '?'}
Penduduk: ${p} Jiwa `);
}
}).addTo(adminGrp);
} catch (e) { console.error("Gagal load geojson kecamatan"); }
const lc = L.control.layers(null, { "Batas Kecamatan": adminGrp, "Lokasi Warga": layerPenduduk, "Tempat Ibadah (Ungu)": layerIbadah }, { collapsed: false }).addTo(map);
document.getElementById('layerControlWrapper').appendChild(lc.getContainer());
}
// --- DRAW CONTROL ---
const drawControl = new L.Control.Draw({ draw: { polyline: false, polygon: false, circle: false, rectangle: false, circlemarker: false, marker: { icon: redIcon } } }).addTo(map);
document.getElementById('drawControlWrapper').appendChild(drawControl.getContainer());
map.on(L.Draw.Event.CREATED, async function (e) {
const layer = e.layer;
tempLat = layer.getLatLng().lat; tempLng = layer.getLatLng().lng;
let latlngNew = L.latLng(tempLat, tempLng);
if (!IS_SUPER_ADMIN) {
let ibadahAdmin = DATA_IBADAH.find(ib => ib.id == ADMIN_ID_IBADAH);
if(ibadahAdmin && latlngNew.distanceTo(L.latLng(ibadahAdmin.latitude, ibadahAdmin.longitude)) > ibadahAdmin.radius) {
alert("Titik ini berada di LUAR radius tempat ibadah Anda. Anda tidak berhak menambahkan warga di area ini.");
return;
}
}
layer.bindPopup("Menyiapkan form... ").addTo(map).openPopup();
const alamatAuto = await getAlamatOtomatis(tempLat, tempLng);
if (IS_SUPER_ADMIN) {
let modePilih = document.getElementById('modeTambah').value;
if(modePilih === 'warga') tampilkanFormPenduduk(layer, 0, '', alamatAuto, 'Islam', 0, '', 0, 0, 0, 0, 0, 'tambah');
else tampilkanFormIbadah(layer, 0, '', 'Masjid', 500, alamatAuto, 'tambah');
} else {
tampilkanFormPenduduk(layer, 0, '', alamatAuto, 'Islam', 0, '', 0, 0, 0, 0, 0, 'tambah');
}
});
// --- FUNGSI CRUD WARGA ---
function tampilkanFormPenduduk(layerOrId, id, nama, alamat, agama, tanggungan, pengeluaran, lantai, dinding, sanitasi, listrik, air, mode) {
tanggungan = tanggungan || 0; pengeluaran = pengeluaran || '';
const formContent = `
`;
if (mode === 'tambah') layerOrId.setPopupContent(formContent); else L.popup().setLatLng([tempLat, tempLng]).setContent(formContent).openOn(map);
}
window.editPenduduk = function(id, nama, alamat, agama, tanggungan, pengeluaran, lantai, dinding, sanitasi, listrik, air, lat, lng) {
tempLat = lat; tempLng = lng; map.closePopup(); tampilkanFormPenduduk(null, id, nama, alamat, agama, tanggungan, pengeluaran, lantai, dinding, sanitasi, listrik, air, 'edit');
}
window.simpanPenduduk = async function(id, mode) {
let valLantai = parseInt(document.getElementById('p_lantai').value); let valDinding = parseInt(document.getElementById('p_dinding').value);
let valSanitasi = parseInt(document.getElementById('p_sanitasi').value); let valListrik = parseInt(document.getElementById('p_listrik').value);
let valAir = parseInt(document.getElementById('p_air').value);
let skorAset = valLantai + valDinding + valSanitasi + valListrik + valAir;
let valPengeluaran = parseFloat(document.getElementById('p_pengeluaran').value) || 0; let valTanggungan = parseInt(document.getElementById('p_tanggungan').value) || 1;
let pengeluaranKapita = valPengeluaran / (valTanggungan > 0 ? valTanggungan : 1);
let miskinMoneter = pengeluaranKapita < GARIS_KEMISKINAN_KALBAR;
let statusKemiskinan = (valPengeluaran > 0) ? (miskinMoneter && skorAset >= 3 ? "Sangat Miskin" : (miskinMoneter ? "Miskin" : "Rentan Miskin")) : "Data Belum Lengkap";
const fd = new FormData(); if (mode === 'edit') fd.append('id', id);
fd.append('latitude', tempLat); fd.append('longitude', tempLng); fd.append('nama_kk', document.getElementById('p_nama').value); fd.append('alamat', document.getElementById('p_alamat').value);
fd.append('agama', document.getElementById('p_agama').value); fd.append('tanggungan', valTanggungan); fd.append('pengeluaran', valPengeluaran); fd.append('skor_aset', skorAset);
fd.append('lantai', valLantai); fd.append('dinding', valDinding); fd.append('sanitasi', valSanitasi); fd.append('listrik', valListrik); fd.append('air', valAir); fd.append('status_kemiskinan', statusKemiskinan);
const endpoint = mode === 'tambah' ? 'api/penduduk/tambah_penduduk.php' : 'api/penduduk/update_penduduk.php';
const response = await fetch(endpoint, { method: 'POST', body: fd });
if ((await response.json()).status === 'success') location.reload(); else alert("Gagal menyimpan data!");
}
window.hapusPenduduk = async function(id) { if (confirm("Hapus rumah dan seluruh keluarga ini?")) { await fetch(`api/penduduk/hapus_penduduk.php?id=${id}`); location.reload(); } }
// --- FUNGSI CRUD KELUARGA & PELATIHAN ---
window.bukaModalKeluarga = async function(id_penduduk, nama_kk) {
map.closePopup();
document.getElementById('modalTitle').innerText = "๐จโ๐ฉโ๐งโ๐ฆ Manajemen Anggota & Pelatihan: Keluarga " + nama_kk;
document.getElementById('keluargaModal').style.display = "block";
let opsiPelatihanHtml = '';
try {
const resPelatihan = await fetch('api/transaksi/get_master_pelatihan.php');
const dataPelatihan = await resPelatihan.json();
dataPelatihan.forEach(pel => { opsiPelatihanHtml += `${pel.nama_pelatihan} (Oleh: ${pel.penyelenggara}) `; });
} catch(e) {}
document.getElementById('modalBody').innerHTML = `Memuat data anggota...
`;
const response = await fetch(`api/anggota/get_anggota_keluarga.php?id_penduduk=${id_penduduk}`);
const dataAnggota = await response.json();
let tableRows = '';
if(dataAnggota.length > 0) {
dataAnggota.forEach(ang => {
let aksiHtml = `
Edit
Hapus
`;
if(ang.rekomendasi_pelatihan) {
aksiHtml += `
โจ Rekomendasi Pelatihan
${opsiPelatihanHtml ? opsiPelatihanHtml : 'Tidak ada pelatihan aktif '}
Daftarkan
`;
} else { aksiHtml += `โ Tidak Memenuhi Syarat Pelatihan
`; }
tableRows += `${ang.nik} ${ang.nama_lengkap} ${ang.umur} Tahun ${ang.pendidikan_terakhir} ${ang.pekerjaan} ${aksiHtml} `;
});
} else { tableRows = `Belum ada anggota keluarga ditambahkan. `; }
document.getElementById('modalBody').innerHTML = `
NIK Nama & Umur Pendidikan Pekerjaan Aksi
${tableRows}
`;
}
window.siapkanEditAnggota = function(id, nik, nama, tgl, pendidikan, pekerjaan) {
document.getElementById('ak_id_edit').value = id; document.getElementById('ak_nik').value = nik; document.getElementById('ak_nama').value = nama; document.getElementById('ak_tgl').value = tgl; document.getElementById('ak_pendidikan').value = pendidikan; document.getElementById('ak_pekerjaan').value = pekerjaan;
document.getElementById('formAnggotaTitle').innerText = "โ๏ธ Edit Data Anggota Keluarga"; document.getElementById('formContainerAnggota').style.backgroundColor = "#fef9e7"; document.getElementById('formContainerAnggota').style.borderColor = "#f1c40f";
let btnSimpan = document.getElementById('btnSimpanAnggota'); btnSimpan.innerText = "Update Data Anggota"; btnSimpan.style.backgroundColor = "#f39c12"; document.getElementById('btnBatalEdit').style.display = "block";
}
window.simpanAnggota = async function(id_penduduk, nama_kk) {
let id_edit = document.getElementById('ak_id_edit').value;
const fd = new FormData(); if(id_edit) fd.append('id_anggota', id_edit);
fd.append('id_penduduk', id_penduduk); fd.append('nik', document.getElementById('ak_nik').value); fd.append('nama_lengkap', document.getElementById('ak_nama').value); fd.append('tanggal_lahir', document.getElementById('ak_tgl').value); fd.append('pendidikan_terakhir', document.getElementById('ak_pendidikan').value); fd.append('pekerjaan', document.getElementById('ak_pekerjaan').value);
if(!fd.get('nik') || !fd.get('nama_lengkap') || !fd.get('tanggal_lahir') || !fd.get('pekerjaan')) { alert("Lengkapi semua data!"); return; }
const r = await fetch(id_edit ? 'api/anggota/update_anggota_keluarga.php' : 'api/anggota/tambah_anggota_keluarga.php', { method: 'POST', body: fd });
if((await r.json()).status === 'success') { alert(id_edit ? "Berhasil diperbarui!" : "Berhasil ditambah!"); bukaModalKeluarga(id_penduduk, nama_kk); } else { alert("Gagal menyimpan."); }
}
window.hapusAnggota = async function(id_anggota, id_penduduk, nama_kk) {
if(confirm("Yakin ingin menghapus anggota ini?")) {
const r = await fetch(`api/anggota/hapus_anggota_keluarga.php?id=${id_anggota}`);
if((await r.json()).status === 'success') bukaModalKeluarga(id_penduduk, nama_kk);
}
}
window.daftarkanPelatihan = async function(id_anggota, id_penduduk, nama_kk) {
let id_pel = document.getElementById('sel_pelatihan_' + id_anggota).value; if(!id_pel) return;
if(confirm("Daftarkan anggota ini ke pelatihan?")) {
const fd = new FormData(); fd.append('id_anggota', id_anggota); fd.append('id_pelatihan', id_pel);
const r = await fetch('api/transaksi/tambah_log_pelatihan.php', { method: 'POST', body: fd });
if((await r.json()).status === 'success') alert("Berhasil didaftarkan!"); else alert("Gagal didaftarkan");
}
}
// --- FUNGSI BANTUAN & MUSIBAH ---
window.bukaFormMusibah = function(id_penduduk, lat, lng) {
map.closePopup();
L.popup().setLatLng([lat, lng]).setContent(`
`).openOn(map);
}
window.simpanLaporanMusibah = async function(id_penduduk) {
let deskripsi = document.getElementById('m_deskripsi').value; if(!deskripsi.trim()) { alert("Isi deskripsi!"); return; }
const fd = new FormData(); fd.append('id_penduduk', id_penduduk); fd.append('id_ibadah', ADMIN_ID_IBADAH); fd.append('jenis_musibah', document.getElementById('m_jenis').value); fd.append('deskripsi', deskripsi);
const res = await (await fetch('api/transaksi/tambah_musibah.php', { method: 'POST', body: fd })).json();
if(res.status === 'success') { alert("Berhasil dicatat!"); location.reload(); } else { alert("Gagal."); }
}
window.bukaFormBantuan = function(id_penduduk, status, lat, lng, id_musibah = null) {
map.closePopup();
let beras = 0, minyak = 0, gula = 0, telur = 0, susu = 0, uang = 0;
if (status.includes("SANGAT MISKIN")) { beras = 10; minyak = 2; gula = 2; telur = 2; susu = 3; uang = 300000; }
else if (status.includes("MISKIN (P2)")) { beras = 5; minyak = 2; gula = 1; telur = 1; susu = 2; uang = 150000; }
else if (status.includes("RENTAN MISKIN")) { beras = 5; minyak = 1; gula = 1; telur = 0; susu = 1; uang = 0; }
L.popup().setLatLng([lat, lng]).setContent(`
`).openOn(map);
}
window.simpanLogBantuan = async function(id_penduduk, id_musibah) {
const fd = new FormData();
fd.append('id_penduduk', id_penduduk); fd.append('id_ibadah', ADMIN_ID_IBADAH);
if (id_musibah !== null && id_musibah !== undefined) { fd.append('id_musibah', id_musibah); }
fd.append('beras_kg', document.getElementById('b_beras').value); fd.append('minyak_l', document.getElementById('b_minyak').value);
fd.append('gula_kg', document.getElementById('b_gula').value); fd.append('telur_kg', document.getElementById('b_telur').value);
fd.append('susu_kaleng', document.getElementById('b_susu').value); fd.append('uang_tunai', document.getElementById('b_uang').value);
fd.append('catatan', document.getElementById('b_catatan').value);
const res = await (await fetch('api/transaksi/tambah_log_bantuan.php', { method: 'POST', body: fd })).json();
if (res.status === 'success') { alert("Berhasil dicatat!"); location.reload(); } else { alert("Gagal menyimpan."); }
}
// --- FUNGSI MODAL LEBAR (Riwayat Bantuan & Pelatihan) ---
window.lihatRiwayat = async function(id_penduduk, nama_kk, lat, lng) {
map.closePopup();
document.getElementById('rbModalTitle').innerText = "๐ Riwayat Penyaluran Bantuan: Keluarga " + nama_kk;
document.getElementById('riwayatBantuanModal').style.display = "block";
document.getElementById('rbModalBody').innerHTML = `Memuat data riwayat...
`;
try {
const data = await (await fetch(`api/transaksi/get_log_bantuan.php?id_penduduk=${id_penduduk}`)).json();
let tableRows = '';
if(data.length > 0) {
data.forEach(log => {
let catatanTeks = (log.catatan !== undefined && log.catatan !== null && log.catatan !== '') ? log.catatan : '-';
tableRows += `
${log.tanggal_penyaluran}
${catatanTeks}
Beras: ${log.beras_kg} Kg; Minyak: ${log.minyak_l} L; Gula: ${log.gula_kg} Kg
Telur: ${log.telur_kg} Kg; Susu: ${log.susu_kaleng} Kaleng; Uang: Rp${log.uang_tunai}
`;
});
} else { tableRows = `Belum ada riwayat. `; }
document.getElementById('rbModalBody').innerHTML = `
Tanggal Catatan / Topik Rincian Item Penyaluran
${tableRows}
`;
} catch (e) { document.getElementById('rbModalBody').innerHTML = `Gagal memuat data.
`; }
}
window.lihatLogPelatihan = async function(id_penduduk, nama_kk, lat, lng) {
map.closePopup();
document.getElementById('rpModalTitle').innerText = "๐ Riwayat Pelatihan: Keluarga " + nama_kk;
document.getElementById('riwayatPelatihanModal').style.display = "block";
document.getElementById('rpModalBody').innerHTML = `Memuat data riwayat pelatihan...
`;
try {
const data = await (await fetch(`api/transaksi/get_log_pelatihan.php?id_penduduk=${id_penduduk}`)).json();
let tableRows = '';
if(data.length > 0) {
data.forEach(log => {
let statusColor = log.status_kelulusan === 'Lulus' ? 'color: #27ae60;' : (log.status_kelulusan === 'Sedang Berjalan' ? 'color: #f39c12;' : 'color: #c0392b;');
tableRows += `
${log.nama_lengkap} Daftar: ${log.tanggal_daftar}
${log.nama_pelatihan}Oleh: ${log.penyelenggara}
${log.status_kelulusan}
`;
});
} else { tableRows = `Belum ada riwayat. `; }
document.getElementById('rpModalBody').innerHTML = `
Nama Anggota Program Pelatihan Status
${tableRows}
`;
} catch (error) { document.getElementById('rpModalBody').innerHTML = `Gagal memuat log.
`; }
}
// --- FUNGSI SUPER ADMIN KHUSUS ---
window.updateGarisKemiskinan = async function() {
let newVal = document.getElementById('input_gk').value;
if(!newVal || newVal < 100000) { alert("Masukkan nilai yang valid!"); return; }
const fd = new FormData(); fd.append('garis_kemiskinan', newVal);
await fetch('api/sistem/update_pengaturan.php', { method: 'POST', body: fd });
alert("Garis Kemiskinan berhasil diperbarui!"); location.reload();
}
window.bukaModalMasterPelatihan = async function() {
document.getElementById('masterPelatihanModal').style.display = "block";
memuatDaftarMasterPelatihan();
}
window.memuatDaftarMasterPelatihan = async function() {
try {
const res = await fetch('api/transaksi/get_master_pelatihan.php');
const data = await res.json();
let html = `Nama Pelatihan Penyelenggara Periode `;
if(data.length > 0) {
data.forEach(p => {
html += `${p.nama_pelatihan} ${p.penyelenggara} ${p.tanggal_mulai} s/d ${p.tanggal_selesai} `;
});
} else { html += `Belum ada program aktif. `; }
html += `
`;
document.getElementById('listMasterPelatihan').innerHTML = html;
} catch(e) { document.getElementById('listMasterPelatihan').innerHTML = "Gagal memuat data."; }
}
window.simpanMasterPelatihan = async function() {
const fd = new FormData();
fd.append('nama_pelatihan', document.getElementById('mp_nama').value);
fd.append('penyelenggara', document.getElementById('mp_instansi').value);
fd.append('tanggal_mulai', document.getElementById('mp_mulai').value);
fd.append('tanggal_selesai', document.getElementById('mp_selesai').value);
fd.append('deskripsi', document.getElementById('mp_deskripsi').value);
if(!fd.get('nama_pelatihan') || !fd.get('tanggal_mulai')) { alert("Data tidak lengkap!"); return; }
const res = await (await fetch('api/transaksi/tambah_master_pelatihan.php', { method: 'POST', body: fd })).json();
if(res.status === 'success') { alert("Berhasil ditambahkan!"); memuatDaftarMasterPelatihan(); } else { alert("Gagal: " + res.pesan); }
}
function tampilkanFormIbadah(layerOrId, id, nama, jenis, radius, alamat, mode) {
const formHtml = ``;
if (mode === 'tambah') layerOrId.setPopupContent(formHtml); else L.popup().setLatLng([tempLat, tempLng]).setContent(formHtml).openOn(map);
}
window.editIbadah = function(id, nama, jenis, radius, alamat, lat, lng) { tempLat = lat; tempLng = lng; map.closePopup(); tampilkanFormIbadah(null, id, nama, jenis, radius, alamat, 'edit'); }
window.simpanIbadah = async function(id, mode) {
const fd = new FormData(); if (mode === 'edit') fd.append('id', id);
fd.append('latitude', tempLat); fd.append('longitude', tempLng); fd.append('nama', document.getElementById('i_nama').value); fd.append('jenis', document.getElementById('i_jenis').value); fd.append('radius', document.getElementById('i_radius').value); fd.append('alamat', document.getElementById('i_alamat').value);
await fetch(mode === 'tambah' ? 'api/ibadah/tambah_ibadah.php' : 'api/ibadah/update_ibadah.php', { method: 'POST', body: fd }); location.reload();
}
window.hapusIbadah = async function(id) { if (confirm("Hapus Institusi ini?")) { await fetch(`api/ibadah/hapus_ibadah.php?id=${id}`); location.reload(); } }
// Memulai Aplikasi setelah semua kode siap
initWebGIS();