// ========================================
// FILE: js/main.js
// Main JavaScript untuk Pemetaan Kemiskinan
// ========================================
// ========== KONFIGURASI ==========
const MAP_CENTER = [-0.0612, 109.3449]; // Koordinat pusat peta (Pontianak)
const MAP_ZOOM = 12; // Tingkat perbesaran bawaan peta
const API_PATH = 'php/'; // Jalur relatif menuju berkas API PHP
let map;
const markers = {
masyarakat: [],
ibadah: [],
spbu: []
};
const layers = {
jalan: L.layerGroup(),
polygon: L.layerGroup()
};
let current_tab = 'masyarakat';
const all_data = {
masyarakat: [],
ibadah: [],
jalan: [],
polygon: [],
spbu: []
};
let drawnItems;
// ========== ICON MARKER ==========
const iconMasyarakat = L.icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
shadowSize: [41, 41]
});
const iconIbadah = L.icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
shadowSize: [41, 41]
});
// ========== UTILITAS KEAMANAN & FORMAT ==========
/**
* Mengamankan string teks dari potensi serangan injeksi XSS.
* @param {string} str - String mentah yang akan dibersihkan.
* @returns {string} String yang aman untuk direndering ke DOM.
*/
function escapeHTML(str) {
if (str === null || str === undefined) return '-';
return String(str)
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
/**
* Melakukan validasi dasar terhadap respons HTTP Fetch sebelum diproses menjadi JSON.
* @param {Response} response - Objek respons dari Fetch API.
* @returns {Promise} Mengembalikan Promise berupa objek JSON jika sukses.
*/
function handleFetchResponse(response) {
if (!response.ok) {
throw new Error(`Gagal memuat data dari server (Status: ${response.status})`);
}
return response.json();
}
// ========== INISIALISASI ==========
document.addEventListener('DOMContentLoaded', function() {
initMap();
loadData();
attachEventListeners();
// Check initial active tab from landing page
const activeTab = localStorage.getItem('activeTab');
const accs = document.querySelectorAll('.accordion');
if (activeTab === 'fasilitas') {
if (accs.length > 0) {
accs[0].style.display = 'flex'; // Show Fasilitas
if (accs.length > 1) accs[1].style.display = 'none'; // Hide Sosial
if (accs.length > 2) accs[2].style.display = 'none'; // Hide Publik
accs[0].classList.add('active');
accs[0].nextElementSibling.style.display = 'block';
const firstTab = accs[0].nextElementSibling.querySelector('.tab-button');
if (firstTab) firstTab.click();
}
} else if (activeTab === 'sosial') {
if (accs.length > 1) {
if (accs.length > 0) accs[0].style.display = 'none'; // Hide Fasilitas
accs[1].style.display = 'flex'; // Show Sosial
if (accs.length > 2) accs[2].style.display = 'none'; // Hide Publik
accs[1].classList.add('active');
accs[1].nextElementSibling.style.display = 'block';
const firstTab = accs[1].nextElementSibling.querySelector('.tab-button');
if (firstTab) firstTab.click();
}
} else if (activeTab === 'publik') {
// Mode Publik: Sembunyikan semua tombol Add dan Form Input
document.querySelectorAll('.btn-primary').forEach(btn => {
if(btn.textContent.includes('+')) btn.style.display = 'none';
});
document.querySelector('.leaflet-draw').style.display = 'none'; // Sembunyikan toolbar Leaflet Draw
// Buka Layanan Publik (Accordion 3)
if (accs.length > 0) accs[0].style.display = 'none';
if (accs.length > 1) accs[1].style.display = 'none';
if (accs.length > 2) {
accs[2].style.display = 'flex';
accs[2].classList.add('active');
accs[2].nextElementSibling.style.display = 'block';
const firstTab = accs[2].nextElementSibling.querySelector('.tab-button');
if (firstTab) firstTab.click();
}
// Tambahkan badge Portal Publik di sidebar jika belum ada
if (!document.getElementById('badge-publik')) {
const sidebar = document.getElementById('sidebar');
const badge = document.createElement('div');
badge.id = 'badge-publik';
badge.innerHTML = '
Mode Akses Publik
';
sidebar.insertBefore(badge, sidebar.children[2]);
}
}
});
/**
* Menginisialisasi objek peta Leaflet dan menambahkan event listener klik.
*/
function initMap() {
map = L.map('map').setView(MAP_CENTER, MAP_ZOOM);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors'
}).addTo(map);
// LEAFLET DRAW
drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
const drawControl = new L.Control.Draw({
edit: { featureGroup: drawnItems },
draw: {
polyline: true,
polygon: true,
circle: false,
marker: false,
circlemarker: false,
rectangle: false
}
});
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (e) {
const type = e.layerType;
const layer = e.layer;
const geojson = JSON.stringify(layer.toGeoJSON());
if (type === 'polyline') {
openModal('modal-form-jalan');
setTimeout(() => { document.getElementById('geojson-jalan').value = geojson; }, 100);
} else if (type === 'polygon') {
openModal('modal-form-polygon');
setTimeout(() => { document.getElementById('geojson-polygon').value = geojson; }, 100);
}
});
// Klik peta untuk memunculkan pilihan tambah data
map.on('click', function(e) {
const lat = e.latlng.lat.toFixed(8);
const lng = e.latlng.lng.toFixed(8);
document.querySelectorAll('input[name="latitude"]').forEach(el => el.value = lat);
document.querySelectorAll('input[name="longitude"]').forEach(el => el.value = lng);
let buttonsHTML = '';
if (current_tab === 'masyarakat') {
buttonsHTML = ``;
} else if (current_tab === 'ibadah') {
buttonsHTML = ``;
} else if (current_tab === 'spbu') {
buttonsHTML = ``;
} else {
buttonsHTML = `Silakan pilih tab yang sesuai (Warga, Ibadah, atau SPBU) di menu kiri terlebih dahulu.`;
}
// Buat konten popup pilihan
const popupContent = `
Pilih Data untuk Ditambah
${lat}, ${lng}
${buttonsHTML}
`;
L.popup()
.setLatLng(e.latlng)
.setContent(popupContent)
.openOn(map);
});
}
/**
* Memicu proses memuat seluruh data dari API secara paralel.
*/
function loadData() {
loadMasyarakat();
loadRumahIbadah();
loadJalan();
loadPolygon();
loadSPBU();
}
function loadJalan() {
fetch(API_PATH + 'ambil_fasilitas_jalan.php').then(handleFetchResponse).then(result => {
if (result.status === 'success') {
all_data.jalan = result.data || [];
tampilkanDataJalan(all_data.jalan);
}
}).catch(e => console.error(e));
}
function loadPolygon() {
fetch(API_PATH + 'ambil_fasilitas_polygon.php').then(handleFetchResponse).then(result => {
if (result.status === 'success') {
all_data.polygon = result.data || [];
tampilkanDataPolygon(all_data.polygon);
}
}).catch(e => console.error(e));
}
function loadSPBU() {
fetch(API_PATH + 'ambil_fasilitas_spbu.php').then(handleFetchResponse).then(result => {
if (result.status === 'success') {
all_data.spbu = result.data || [];
tampilkanDataSPBU(all_data.spbu);
}
}).catch(e => console.error(e));
}
/**
* Memuat data masyarakat miskin dari server.
*/
function loadMasyarakat() {
fetch(API_PATH + 'ambil_data_masyarakat.php')
.then(handleFetchResponse)
.then(result => {
if (result.status === 'success') {
all_data.masyarakat = result.data || [];
tampilkanDataMasyarakat(all_data.masyarakat);
} else {
console.error('Gagal memuat data masyarakat:', result.message);
}
})
.catch(error => console.error('Error saat fetch data masyarakat:', error));
}
/**
* Memuat data fasilitas rumah ibadah dari server.
*/
function loadRumahIbadah() {
fetch(API_PATH + 'ambil_rumah_ibadah.php')
.then(handleFetchResponse)
.then(result => {
if (result.status === 'success') {
all_data.ibadah = result.data || [];
tampilkanDataIbadah(all_data.ibadah);
} else {
console.error('Gagal memuat data rumah ibadah:', result.message);
}
})
.catch(error => console.error('Error saat fetch data rumah ibadah:', error));
}
/**
* Merender penanda peta dan elemen daftar sidebar untuk kategori masyarakat.
* @param {Array} data - Larik berisi data objek masyarakat.
*/
function tampilkanDataMasyarakat(data) {
markers.masyarakat.forEach(m => map.removeLayer(m));
markers.masyarakat = [];
const list = document.getElementById('list-masyarakat');
if (!list) return;
list.innerHTML = '';
data.forEach(item => {
const marker = L.marker(
[parseFloat(item.latitude), parseFloat(item.longitude)],
{ icon: iconMasyarakat }
).addTo(map);
const bpjs_class = item.status_bpjs === 'Ya' ? 'status-ya' : (item.status_bpjs === 'Proses' ? 'status-proses' : 'status-tidak');
// Penerapan escapeHTML untuk mencegah kerentanan XSS pada popup
marker.bindPopup(`
${escapeHTML(item.nama)}
${escapeHTML(item.alamat)}
Status BPJS: ${escapeHTML(item.status_bpjs)}
`);
markers.masyarakat.push(marker);
const li = document.createElement('li');
li.innerHTML = `
${escapeHTML(item.nama)}
${escapeHTML(item.kecamatan)} | BPJS: ${escapeHTML(item.status_bpjs)}
`;
li.onclick = () => {
map.setView([item.latitude, item.longitude], 16);
marker.openPopup();
};
list.appendChild(li);
});
updateMapVisibility();
}
/**
* Merender penanda peta dan elemen daftar sidebar untuk kategori rumah ibadah.
* @param {Array} data - Larik berisi data objek rumah ibadah.
*/
function tampilkanDataIbadah(data) {
markers.ibadah.forEach(m => map.removeLayer(m));
markers.ibadah = [];
const list = document.getElementById('list-ibadah');
if (!list) return;
list.innerHTML = '';
data.forEach(item => {
const marker = L.marker(
[parseFloat(item.latitude), parseFloat(item.longitude)],
{ icon: iconIbadah }
).addTo(map);
const info_pemimpin = item.nama_pemimpin ? 'Pemimpin: ' + escapeHTML(item.nama_pemimpin) + '
' : '';
const info_alamat = item.alamat ? '' + escapeHTML(item.alamat) + '' : '';
marker.bindPopup(`
${escapeHTML(item.nama)}
${escapeHTML(item.jenis)}
${info_pemimpin}
${info_alamat}
`);
markers.ibadah.push(marker);
const li = document.createElement('li');
li.innerHTML = `
${escapeHTML(item.nama)}
${escapeHTML(item.jenis)}
`;
li.onclick = () => {
map.setView([item.latitude, item.longitude], 16);
marker.openPopup();
};
list.appendChild(li);
});
updateMapVisibility();
}
function tampilkanDataJalan(data) {
if (layers.jalan) map.removeLayer(layers.jalan);
layers.jalan = L.layerGroup().addTo(map);
const list = document.getElementById('list-jalan');
if (!list) return;
list.innerHTML = '';
data.forEach(item => {
try {
const geojson = JSON.parse(item.geojson);
const layer = L.geoJSON(geojson, { style: { color: 'blue', weight: 4 } }).addTo(layers.jalan);
layer.bindPopup(`${escapeHTML(item.nama)}
${escapeHTML(item.tipe)}
`);
const li = document.createElement('li');
li.innerHTML = `${escapeHTML(item.nama)}
${escapeHTML(item.tipe)}`;
li.onclick = () => { map.fitBounds(layer.getBounds()); layer.openPopup(); };
list.appendChild(li);
} catch(e) { console.error('Invalid GeoJSON', e); }
});
updateMapVisibility();
}
function tampilkanDataPolygon(data) {
if (layers.polygon) map.removeLayer(layers.polygon);
layers.polygon = L.layerGroup().addTo(map);
const list = document.getElementById('list-polygon');
if (!list) return;
list.innerHTML = '';
data.forEach(item => {
try {
const geojson = JSON.parse(item.geojson);
const layer = L.geoJSON(geojson, { style: { color: 'purple', fillColor: 'purple', fillOpacity: 0.4 } }).addTo(layers.polygon);
layer.bindPopup(`${escapeHTML(item.nama)}
${escapeHTML(item.tipe)}
`);
const li = document.createElement('li');
li.innerHTML = `${escapeHTML(item.nama)}
${escapeHTML(item.tipe)}`;
li.onclick = () => { map.fitBounds(layer.getBounds()); layer.openPopup(); };
list.appendChild(li);
} catch(e) { console.error('Invalid GeoJSON', e); }
});
updateMapVisibility();
}
function tampilkanDataSPBU(data) {
markers.spbu.forEach(m => map.removeLayer(m));
markers.spbu = [];
const list = document.getElementById('list-spbu');
if (!list) return;
list.innerHTML = '';
data.forEach(item => {
const is24 = item.is_24_jam === 'Ya';
// Reuse iconIbadah for green (24h) and iconMasyarakat for red (not 24h)
const iconSPBU = is24 ? iconIbadah : iconMasyarakat;
const statusText = is24 ? 'Buka 24 Jam' : 'Tidak 24 Jam';
const marker = L.marker([parseFloat(item.latitude), parseFloat(item.longitude)], {
icon: iconSPBU,
draggable: true
}).addTo(map);
marker.bindPopup(`${escapeHTML(item.nama)}
${escapeHTML(item.alamat)}
${statusText}
`);
marker.on('dragend', function(e) {
const newPos = marker.getLatLng();
if (confirm('Apakah Anda yakin ingin memperbarui lokasi SPBU ini?')) {
const fd = new FormData();
fd.append('id', item.id);
fd.append('latitude', newPos.lat.toFixed(8));
fd.append('longitude', newPos.lng.toFixed(8));
fetch(API_PATH + 'update_lokasi_spbu.php', { method: 'POST', body: fd })
.then(handleFetchResponse)
.then(res => {
if (res.status === 'success') {
alert('Lokasi berhasil diperbarui');
item.latitude = newPos.lat;
item.longitude = newPos.lng;
} else {
alert('Gagal: ' + res.message);
marker.setLatLng([parseFloat(item.latitude), parseFloat(item.longitude)]);
}
}).catch(err => {
alert('Error: ' + err.message);
marker.setLatLng([parseFloat(item.latitude), parseFloat(item.longitude)]);
});
} else {
marker.setLatLng([parseFloat(item.latitude), parseFloat(item.longitude)]);
}
});
markers.spbu.push(marker);
const li = document.createElement('li');
li.innerHTML = `${escapeHTML(item.nama)}
${escapeHTML(item.alamat)}
${statusText}`;
li.onclick = () => { map.setView([item.latitude, item.longitude], 16); marker.openPopup(); };
list.appendChild(li);
});
updateMapVisibility();
}
/**
* Memuat detail data spesifik masyarakat miskin termasuk riwayat bantuan dan status BPJS.
* @param {string|number} id - ID unik entitas masyarakat miskin.
*/
function showDetail(id) {
fetch(API_PATH + 'ambil_detail.php?id=' + encodeURIComponent(id))
.then(handleFetchResponse)
.then(result => {
if (result.status === 'success') {
const data = result.data;
const masyarakat = data.masyarakat;
const bantuan = data.bantuan || [];
const bpjs = data.bpjs;
const bpjs_class = masyarakat.status_bpjs === 'Ya' ? 'status-ya' : (masyarakat.status_bpjs === 'Proses' ? 'status-proses' : 'status-tidak');
let html = `
👤 Data Pribadi
Nama${escapeHTML(masyarakat.nama)}
Tanggal Lahir${escapeHTML(masyarakat.tanggal_lahir)}
Jenis Kelamin${escapeHTML(masyarakat.jenis_kelamin)}
NIK${escapeHTML(masyarakat.nik)}
No. HP${escapeHTML(masyarakat.no_hp)}
🏠 Data Alamat
Alamat${escapeHTML(masyarakat.alamat)}
Kelurahan${escapeHTML(masyarakat.kelurahan)}
Kecamatan${escapeHTML(masyarakat.kecamatan)}
Status Rumah${escapeHTML(masyarakat.status_rumah)}
💼 Data Ekonomi
Pekerjaan${escapeHTML(masyarakat.pekerjaan)}
Pendapatan BulananRp. ${new Intl.NumberFormat('id-ID').format(masyarakat.pendapatan_bulanan || 0)}
Jumlah Tanggungan${escapeHTML(masyarakat.jumlah_tanggungan)} orang
🏥 Status BPJS
Status BPJS${escapeHTML(masyarakat.status_bpjs)}
`;
if (bpjs) {
html += `
No. Peserta BPJS${escapeHTML(bpjs.no_peserta)}
Jenis BPJS${escapeHTML(bpjs.jenis_bpjs)}
Tingkat${escapeHTML(bpjs.tingkat)}
`;
}
html += `
`; // Memperbaiki string penutup tag div yang sebelumnya memicu syntax error
if (bantuan.length > 0) {
html += `💰 Riwayat Bantuan
`;
bantuan.forEach(b => {
html += `
${escapeHTML(b.jenis_bantuan)} (${escapeHTML(b.tanggal_bantuan)})
Nilai: Rp. ${new Intl.NumberFormat('id-ID').format(b.nilai)} ${escapeHTML(b.satuan)}
${b.keterangan ? '
' + escapeHTML(b.keterangan) + '' : ''}
`;
});
html += `
`;
}
html += `
`;
const modal_body = document.getElementById('modal-body');
if (modal_body) {
modal_body.innerHTML = html;
openModal('modal-detail');
}
}
})
.catch(error => console.error('Error saat fetch detail data:', error));
}
/**
* Menghubungkan fungsi penangan kejadian (event handler) ke elemen-elemen HTML DOM.
*/
function attachEventListeners() {
// Accordion Logic
document.querySelectorAll('.accordion').forEach(acc => {
acc.addEventListener('click', function() {
// Close other accordions
document.querySelectorAll('.accordion').forEach(otherAcc => {
if (otherAcc !== this) {
otherAcc.classList.remove('active');
if (otherAcc.nextElementSibling) {
otherAcc.nextElementSibling.style.display = "none";
}
}
});
// Toggle this one
this.classList.toggle('active');
const panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
// Optionally auto-click the first tab in this accordion
const firstTab = panel.querySelector('.tab-button');
if (firstTab && !firstTab.classList.contains('active')) {
firstTab.click();
}
}
});
});
document.querySelectorAll('.tab-button').forEach(btn => {
btn.addEventListener('click', function(e) {
const tab = this.dataset.tab;
switchTab(e, tab);
});
});
const search_input = document.getElementById('search');
const f_kecamatan = document.getElementById('filter-kecamatan');
const f_bpjs = document.getElementById('filter-bpjs');
const f_jenis = document.getElementById('filter-jenis');
if (search_input) search_input.addEventListener('input', filterMasyarakat);
if (f_kecamatan) f_kecamatan.addEventListener('change', filterMasyarakat);
if (f_bpjs) f_bpjs.addEventListener('change', filterMasyarakat);
if (f_jenis) f_jenis.addEventListener('change', filterIbadah);
const form_masyarakat = document.getElementById('form-masyarakat');
const form_ibadah = document.getElementById('form-ibadah');
const form_jalan = document.getElementById('form-jalan');
const form_polygon = document.getElementById('form-polygon');
const form_spbu = document.getElementById('form-spbu');
if (form_masyarakat) form_masyarakat.addEventListener('submit', function(e) { e.preventDefault(); submitFormMasyarakat(); });
if (form_ibadah) form_ibadah.addEventListener('submit', function(e) { e.preventDefault(); submitFormIbadah(); });
if (form_jalan) form_jalan.addEventListener('submit', function(e) { e.preventDefault(); submitFormJalan(); });
if (form_polygon) form_polygon.addEventListener('submit', function(e) { e.preventDefault(); submitFormPolygon(); });
if (form_spbu) form_spbu.addEventListener('submit', function(e) { e.preventDefault(); submitFormSPBU(); });
// Shortcut keyboard untuk membuka formulir penambahan data baru
document.addEventListener('keydown', function(e) {
if (e.key === 'n' || e.key === 'N') {
const active_modal = document.querySelector('.modal.active');
if (active_modal) return; // Cegah konflik jika modal lain sudah terbuka
if (current_tab === 'masyarakat') openModal('modal-form-masyarakat');
else if (current_tab === 'ibadah') openModal('modal-form-ibadah');
}
});
}
/**
* Mengubah status visibilitas tab kategori aktif (Masyarakat / Rumah Ibadah).
* @param {Event} e - Objek event klik dari DOM.
* @param {string} tab - Nama tab penanda tujuan ('masyarakat' / 'ibadah').
*/
function switchTab(e, tab) {
current_tab = tab;
document.querySelectorAll('.tab-button').forEach(btn => {
btn.classList.remove('active');
});
if (e && e.target) {
e.target.classList.add('active');
}
document.querySelectorAll('.list-container').forEach(container => {
container.classList.remove('active');
});
const target_tab = document.getElementById('tab-' + tab);
if (target_tab) target_tab.classList.add('active');
updateMapVisibility();
}
function updateMapVisibility() {
markers.masyarakat.forEach(m => map.removeLayer(m));
markers.ibadah.forEach(m => map.removeLayer(m));
markers.spbu.forEach(m => map.removeLayer(m));
if (layers.jalan) map.removeLayer(layers.jalan);
if (layers.polygon) map.removeLayer(layers.polygon);
if (current_tab === 'masyarakat' || current_tab === 'info-fasilitas') {
markers.masyarakat.forEach(m => map.addLayer(m));
}
if (current_tab === 'ibadah' || current_tab === 'info-fasilitas') {
markers.ibadah.forEach(m => map.addLayer(m));
}
if (current_tab === 'spbu' || current_tab === 'info-fasilitas') {
markers.spbu.forEach(m => map.addLayer(m));
}
if (current_tab === 'jalan' || current_tab === 'info-fasilitas') {
if (layers.jalan) map.addLayer(layers.jalan);
}
if (current_tab === 'polygon' || current_tab === 'info-fasilitas') {
if (layers.polygon) map.addLayer(layers.polygon);
}
}
/**
* Memfilter kumpulan data masyarakat berdasarkan kata kunci pencarian, kecamatan, dan status BPJS.
*/
function filterMasyarakat() {
const search_el = document.getElementById('search');
const kec_el = document.getElementById('filter-kecamatan');
const bpjs_el = document.getElementById('filter-bpjs');
const keyword = search_el ? search_el.value.toLowerCase() : '';
const kecamatan = kec_el ? kec_el.value : '';
const bpjs = bpjs_el ? bpjs_el.value : '';
const filtered = all_data.masyarakat.filter(item => {
const item_nama = item.nama ? item.nama.toLowerCase() : '';
const item_alamat = item.alamat ? item.alamat.toLowerCase() : '';
const match_keyword = item_nama.includes(keyword) || item_alamat.includes(keyword);
const match_kecamatan = !kecamatan || item.kecamatan === kecamatan;
const match_bpjs = !bpjs || item.status_bpjs === bpjs;
return match_keyword && match_kecamatan && match_bpjs;
});
tampilkanDataMasyarakat(filtered);
}
/**
* Memfilter kumpulan data tempat ibadah berdasarkan jenis kategori tempat ibadah.
*/
function filterIbadah() {
const jenis_el = document.getElementById('filter-jenis');
const jenis = jenis_el ? jenis_el.value : '';
const filtered = all_data.ibadah.filter(item => {
return !jenis || item.jenis === jenis;
});
tampilkanDataIbadah(filtered);
}
/**
* Mengirimkan formulir data masyarakat baru ke berkas PHP pemroses menggunakan Fetch FormData.
*/
function submitFormMasyarakat() {
const form = document.getElementById('form-masyarakat');
if (!form) return;
const form_data = new FormData(form);
fetch(API_PATH + 'simpan_masyarakat.php', {
method: 'POST',
body: form_data
})
.then(handleFetchResponse)
.then(result => {
if (result.status === 'success') {
showAlert('alert-form', 'Data berhasil disimpan!', 'success');
form.reset();
setTimeout(() => {
closeModal('modal-form-masyarakat');
loadMasyarakat();
}, 1500);
} else {
showAlert('alert-form', result.message || 'Gagal menyimpan data.', 'error');
}
})
.catch(error => {
showAlert('alert-form', 'Terjadi kesalahan sistem: ' + error.message, 'error');
});
}
/**
* Mengirimkan formulir data rumah ibadah baru ke berkas PHP pemroses menggunakan Fetch FormData.
*/
function submitFormIbadah() {
const form = document.getElementById('form-ibadah');
if (!form) return;
const form_data = new FormData(form);
fetch(API_PATH + 'simpan_rumah_ibadah.php', {
method: 'POST',
body: form_data
})
.then(handleFetchResponse)
.then(result => {
if (result.status === 'success') {
showAlert('alert-form-ibadah', 'Data berhasil disimpan!', 'success');
form.reset();
setTimeout(() => {
closeModal('modal-form-ibadah');
loadRumahIbadah();
}, 1500);
} else {
showAlert('alert-form-ibadah', result.message || 'Gagal menyimpan data.', 'error');
}
})
.catch(error => {
showAlert('alert-form-ibadah', 'Terjadi kesalahan sistem: ' + error.message, 'error');
});
}
function submitFormJalan() {
const form = document.getElementById('form-jalan');
if (!form) return;
const form_data = new FormData(form);
fetch(API_PATH + 'simpan_fasilitas_jalan.php', { method: 'POST', body: form_data })
.then(handleFetchResponse).then(result => {
if (result.status === 'success') {
showAlert('alert-form-jalan', 'Berhasil disimpan', 'success'); form.reset(); drawnItems.clearLayers();
setTimeout(() => { closeModal('modal-form-jalan'); loadJalan(); }, 1000);
} else showAlert('alert-form-jalan', result.message, 'error');
}).catch(e => showAlert('alert-form-jalan', e.message, 'error'));
}
function submitFormPolygon() {
const form = document.getElementById('form-polygon');
if (!form) return;
const form_data = new FormData(form);
fetch(API_PATH + 'simpan_fasilitas_polygon.php', { method: 'POST', body: form_data })
.then(handleFetchResponse).then(result => {
if (result.status === 'success') {
showAlert('alert-form-polygon', 'Berhasil disimpan', 'success'); form.reset(); drawnItems.clearLayers();
setTimeout(() => { closeModal('modal-form-polygon'); loadPolygon(); }, 1000);
} else showAlert('alert-form-polygon', result.message, 'error');
}).catch(e => showAlert('alert-form-polygon', e.message, 'error'));
}
function submitFormSPBU() {
const form = document.getElementById('form-spbu');
if (!form) return;
const form_data = new FormData(form);
fetch(API_PATH + 'simpan_fasilitas_spbu.php', { method: 'POST', body: form_data })
.then(handleFetchResponse).then(result => {
if (result.status === 'success') {
showAlert('alert-form-spbu', 'Berhasil disimpan', 'success'); form.reset();
setTimeout(() => { closeModal('modal-form-spbu'); loadSPBU(); }, 1000);
} else showAlert('alert-form-spbu', result.message, 'error');
}).catch(e => showAlert('alert-form-spbu', e.message, 'error'));
}
/**
* Mengirimkan instruksi penghapusan data spesifik (masyarakat/ibadah) ke sistem basis data backend.
* @param {string} tipe - Jenis kategori data yang akan dihapus ('masyarakat' / 'ibadah').
* @param {string|number} id - ID baris data target.
*/
function hapusData(tipe, id) {
if (!confirm('Apakah Anda yakin ingin menghapus data ini? Tindakan ini tidak dapat dibatalkan.')) {
return;
}
const form_data = new FormData();
form_data.append('tipe', tipe);
form_data.append('id', id);
fetch(API_PATH + 'hapus_data.php', {
method: 'POST',
body: form_data
})
.then(handleFetchResponse)
.then(result => {
if (result.status === 'success') {
alert('Data berhasil dihapus');
closeModal('modal-detail');
if (tipe === 'masyarakat') loadMasyarakat();
else if (tipe === 'ibadah') loadRumahIbadah();
else if (tipe === 'jalan') loadJalan();
else if (tipe === 'polygon') loadPolygon();
else if (tipe === 'spbu') loadSPBU();
} else {
alert('Gagal menghapus: ' + (result.message || 'Error tidak diketahui'));
}
})
.catch(error => {
alert('Terjadi kesalahan jaringan atau sistem: ' + error.message);
});
}
function editBantuan(id) {
alert('Fitur tambah bantuan dengan ID ' + id + ' akan ditambahkan segera');
}
function openModal(modalId) {
const modal = document.getElementById(modalId);
if (modal) modal.classList.add('active');
}
function closeModal(modalId) {
const modal = document.getElementById(modalId);
if (modal) modal.classList.remove('active');
}
function showAlert(elementId, message, type) {
const alert_el = document.getElementById(elementId);
if (!alert_el) return;
alert_el.textContent = message;
alert_el.className = 'alert active alert-' + type;
setTimeout(() => {
alert_el.classList.remove('active');
}, 5000);
}
// Menutup jendela modal otomatis jika pengguna mengklik area luar modal (overlay)
document.addEventListener('click', function(e) {
if (e.target && e.target.classList.contains('modal')) {
e.target.classList.remove('active');
}
});