// ========================================================================= // 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 ? `
` : ''; 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) ? `` : ''; actionButtons = ` ${btnBantuanHtml} `; } 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 += ``; }); } 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 = `
`; if(ang.rekomendasi_pelatihan) { aksiHtml += `
โœจ Rekomendasi Pelatihan
`; } 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 = `
${tableRows}
NIKNama & UmurPendidikanPekerjaanAksi

+ Tambah Anggota Keluarga Baru

`; } 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 = `
${tableRows}
TanggalCatatan / TopikRincian Item Penyaluran
`; } 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 = `
${tableRows}
Nama AnggotaProgram PelatihanStatus
`; } 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 = ``; if(data.length > 0) { data.forEach(p => { html += ``; }); } else { html += ``; } html += `
Nama PelatihanPenyelenggaraPeriode
${p.nama_pelatihan}${p.penyelenggara}${p.tanggal_mulai} s/d ${p.tanggal_selesai}
Belum ada program aktif.
`; 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();