// ===== Panel Management ===== // Mengelola Left Sidebar Toggle + Right Panel + Layer Control (function () { // ---- Konstanta Jenis Ibadah ---- const IBADAH_EMOJI = { 'Masjid': '🕌', 'Gereja': '⛪', 'Pura': '🛕', 'Vihara': '🪷', 'Kelenteng': '🏮', }; window.IBADAH_EMOJI = IBADAH_EMOJI; // ---- State ---- let activePanel = null; // ---- Elements ---- const sidebarToggleBtn = document.getElementById('sidebarToggleBtn'); const sidebarToggleIcon = document.getElementById('sidebarToggleIcon'); const leftSidebar = document.getElementById('leftSidebar'); const rightPanel = document.getElementById('rightPanel'); const rightPanelTitle = document.getElementById('rightPanelTitle'); const rightPanelActions = document.getElementById('rightPanelActions'); const rightPanelBody = document.getElementById('rightPanelBody'); const rightPanelClose = document.getElementById('rightPanelClose'); // ---- Sidebar Toggle ---- sidebarToggleBtn.addEventListener('click', function () { const isOpen = leftSidebar.style.display !== 'none'; if (isOpen) { leftSidebar.style.display = 'none'; sidebarToggleBtn.classList.remove('open'); sidebarToggleIcon.className = 'fas fa-chevron-right'; } else { leftSidebar.style.display = 'flex'; sidebarToggleBtn.classList.add('open'); sidebarToggleIcon.className = 'fas fa-chevron-left'; } }); // ---- Sidebar Buttons ---- document.querySelectorAll('.sidebar-btn').forEach(btn => { btn.addEventListener('click', function () { const panel = this.dataset.panel; if (activePanel === panel) { closePanel(); } else { openPanel(panel); } }); }); rightPanelClose.addEventListener('click', closePanel); // ---- Open / Close Panel ---- function openPanel(panel) { activePanel = panel; rightPanel.classList.add('open'); document.querySelectorAll('.sidebar-btn').forEach(b => b.classList.remove('active')); const activeBtn = document.querySelector(`.sidebar-btn[data-panel="${panel}"]`); if (activeBtn) activeBtn.classList.add('active'); renderPanel(panel); } function closePanel() { activePanel = null; rightPanel.classList.remove('open'); document.querySelectorAll('.sidebar-btn').forEach(b => b.classList.remove('active')); } window.refreshActivePanel = function () { if (activePanel && activePanel !== 'layer') renderPanel(activePanel); }; // ---- Render Panel by Type ---- function renderPanel(type) { rightPanelBody.innerHTML = '
Memuat data...
'; rightPanelActions.innerHTML = ''; switch (type) { case 'spbu': renderSpbuPanel(); break; case 'jalan': renderJalanPanel(); break; case 'parsil': renderParsilPanel(); break; case 'ibadah': renderIbadahPanel(); break; case 'miskin': renderMiskinPanel(); break; } } // ========================== // ===== SPBU Panel ========= // ========================== function renderSpbuPanel() { rightPanelTitle.textContent = '⛽ SPBU'; rightPanelActions.innerHTML = ` `; document.getElementById('btnPanelAddSpbu').addEventListener('click', () => { window.activateAddMode('spbu'); }); const items = []; spbuLayer.eachLayer(l => { if (l.spbuData) items.push(l.spbuData); }); if (!items.length) { rightPanelBody.innerHTML = '
Belum ada data SPBU
'; return; } rightPanelBody.innerHTML = ''; items.forEach(d => { const bdg = d.is_24_jam ? '24 Jam' : 'Tidak 24 Jam'; const card = document.createElement('div'); card.className = 'data-card'; card.innerHTML = `
${escHtml(d.nama)}
📞 ${d.no_wa || '-'}
${bdg}
`; card.querySelector('.btn-card-edit').addEventListener('click', (e) => { e.stopPropagation(); openEditSpbuModal(d.id); }); card.querySelector('.btn-card-delete').addEventListener('click', (e) => { e.stopPropagation(); deleteSpbu(d.id); }); card.addEventListener('click', () => flyToSpbu(d.id)); rightPanelBody.appendChild(card); }); } function flyToSpbu(id) { spbuLayer.eachLayer(l => { if (l.spbuData && l.spbuData.id == id) { map.setView(l.getLatLng(), 17); l.openPopup(); } }); } // ========================== // ===== Jalan Panel ======== // ========================== function renderJalanPanel() { rightPanelTitle.textContent = '🛣️ Jalan'; rightPanelActions.innerHTML = ` `; document.getElementById('btnPanelAddJalan').addEventListener('click', () => { window.activateDraw('polyline'); }); const items = []; jalanLayer.eachLayer(l => { if (l.jalanData) items.push(l.jalanData); }); if (!items.length) { rightPanelBody.innerHTML = '
Belum ada data jalan
'; return; } const statusBadge = { 'Nasional' : 'Nasional', 'Provinsi' : 'Provinsi', 'Kabupaten': 'Kabupaten', }; rightPanelBody.innerHTML = ''; items.forEach(d => { const km = (d.panjang / 1000).toFixed(2); const card = document.createElement('div'); card.className = 'data-card'; card.innerHTML = `
🛣️
${escHtml(d.nama)}
📏 ${km} km
${statusBadge[d.status] || ''}
`; card.querySelector('.btn-card-edit').addEventListener('click', (e) => { e.stopPropagation(); openEditJalanModal(d.id); }); card.querySelector('.btn-card-delete').addEventListener('click', (e) => { e.stopPropagation(); deleteJalan(d.id); }); card.addEventListener('click', () => flyToJalan(d.id)); rightPanelBody.appendChild(card); }); } function flyToJalan(id) { jalanLayer.eachLayer(l => { if (l.jalanData && l.jalanData.id == id && l.getBounds) { map.fitBounds(l.getBounds(), { padding: [40, 40] }); l.openPopup(); } }); } // ========================== // ===== Parsil Panel ======= // ========================== function renderParsilPanel() { rightPanelTitle.textContent = '🗺️ Parsil Tanah'; rightPanelActions.innerHTML = ` `; document.getElementById('btnPanelAddParsil').addEventListener('click', () => { window.activateDraw('polygon'); }); const items = []; parsilLayer.eachLayer(l => { if (l.parsilData) items.push(l.parsilData); }); if (!items.length) { rightPanelBody.innerHTML = '
Belum ada data parsil
'; return; } const statusBadge = { 'SHM': 'SHM', 'HGB': 'HGB', 'HGU': 'HGU', 'HP' : 'HP', }; rightPanelBody.innerHTML = ''; items.forEach(d => { const luas = d.luas >= 10000 ? (d.luas / 10000).toFixed(2) + ' ha' : d.luas.toFixed(0) + ' m²'; const card = document.createElement('div'); card.className = 'data-card'; card.innerHTML = `
🗺️
${escHtml(d.nama || 'Tanpa Nama')}
📐 ${luas}
${statusBadge[d.status] || ''}
`; card.querySelector('.btn-card-edit').addEventListener('click', (e) => { e.stopPropagation(); openEditParsilModal(d.id); }); card.querySelector('.btn-card-delete').addEventListener('click', (e) => { e.stopPropagation(); deleteParsil(d.id); }); card.addEventListener('click', () => flyToParsil(d.id)); rightPanelBody.appendChild(card); }); } function flyToParsil(id) { parsilLayer.eachLayer(l => { if (l.parsilData && l.parsilData.id == id && l.getBounds) { map.fitBounds(l.getBounds(), { padding: [40, 40] }); l.openPopup(); } }); } // ========================== // ===== Ibadah Panel ======= // ========================== function renderIbadahPanel() { rightPanelTitle.textContent = '🕌 Rumah Ibadah'; rightPanelActions.innerHTML = ` `; document.getElementById('btnPanelAddIbadah').addEventListener('click', () => { window.activateAddMode('rumah_ibadah'); }); const items = []; rumahIbadahLayer.eachLayer(l => { if (l.ibadahData && l instanceof L.Marker) items.push(l.ibadahData); }); if (!items.length) { rightPanelBody.innerHTML = '
Belum ada data rumah ibadah
'; return; } rightPanelBody.innerHTML = ''; items.forEach(d => { const emoji = IBADAH_EMOJI[d.jenis] || '🕌'; const card = document.createElement('div'); card.className = 'data-card'; card.innerHTML = `
${emoji}
${escHtml(d.nama)}
${escHtml(d.jenis || 'Masjid')} • 📡 ${d.radius} m
`; card.querySelector('.btn-card-edit').addEventListener('click', (e) => { e.stopPropagation(); openEditIbadahModal(d.id); }); card.querySelector('.btn-card-delete').addEventListener('click', (e) => { e.stopPropagation(); deleteIbadah(d.id); }); card.addEventListener('click', () => flyToIbadah(d.id)); rightPanelBody.appendChild(card); }); } function flyToIbadah(id) { rumahIbadahLayer.eachLayer(l => { if (l.ibadahData && l.ibadahData.id == id && l instanceof L.Marker) { map.setView(l.getLatLng(), 17); l.openPopup(); } }); } // ========================== // ===== Miskin Panel ======= // ========================== function renderMiskinPanel() { rightPanelTitle.textContent = '🏠 Penduduk Miskin'; rightPanelActions.innerHTML = ` `; // Tombol Tambah: buka form via right-click popup di peta document.getElementById('btnPanelTambahMiskin').addEventListener('click', () => { // Aktifkan mode: klik kiri di peta = tambah miskin window.currentAddMode = 'miskin_click'; document.getElementById('map').style.cursor = 'crosshair'; if (window.cursorTooltip) { window.cursorTooltip.textContent = 'Klik di peta untuk tentukan lokasi penduduk miskin'; } }); document.getElementById('btnPanelImportMiskin').addEventListener('click', () => { alert('Fitur impor CSV akan segera tersedia.'); }); const all = []; pendudukMiskinLayer.eachLayer(l => { if (l.miskinData) all.push(l.miskinData); }); if (!all.length) { rightPanelBody.innerHTML = '
Belum ada data penduduk miskin
'; return; } const inRadius = (d) => { if (typeof ibadahDataList === 'undefined') return false; for (const ib of ibadahDataList) { const dist = L.latLng(d.lat, d.lng).distanceTo(L.latLng(ib.lat, ib.lng)); if (dist <= ib.radius) return true; } return false; }; rightPanelBody.innerHTML = ''; const terurusItems = all.filter(d => inRadius(d)); const tidakItems = all.filter(d => !inRadius(d)); if (terurusItems.length) { const h1 = document.createElement('div'); h1.className = 'panel-section-title'; h1.innerHTML = `✅ Terurus (${terurusItems.length})`; rightPanelBody.appendChild(h1); terurusItems.forEach(d => rightPanelBody.appendChild(buildMiskinCard(d, true))); } if (tidakItems.length) { const h2 = document.createElement('div'); h2.className = 'panel-section-title'; h2.innerHTML = `⚠️ Tidak Terurus (${tidakItems.length})`; rightPanelBody.appendChild(h2); tidakItems.forEach(d => rightPanelBody.appendChild(buildMiskinCard(d, false))); } } function buildMiskinCard(d, terurus) { const iconCls = terurus ? 'card-icon-miskin-in' : 'card-icon-miskin-out'; const badge = d.kategori_bantuan === 'Makan' ? 'Bantuan Makan' : 'Pemberdayaan'; const card = document.createElement('div'); card.className = 'data-card'; card.dataset.miskinId = d.id; card.innerHTML = `
🏠
${escHtml(d.nama)}
👨‍👩‍👧 ${d.jumlah_jiwa || '-'} jiwa
${badge}
Kategori Bantuan${escHtml(d.kategori_bantuan)}
Jumlah Jiwa${d.jumlah_jiwa || '-'}
Status${terurus ? 'Terurus ✅' : 'Tidak Terurus ⚠️'}
`; card.querySelector('.btn-card-edit').addEventListener('click', (e) => { e.stopPropagation(); openEditMiskinModal(d.id); }); card.querySelector('.btn-card-delete').addEventListener('click', (e) => { e.stopPropagation(); deleteMiskin(d.id); }); card.querySelector('.btn-log-bantuan').addEventListener('click', (e) => { e.stopPropagation(); openLogBantuan(d.id, d.nama); }); card.querySelector('.data-card-main').addEventListener('click', () => { card.classList.toggle('expanded'); flyToMiskin(d.id); }); return card; } function flyToMiskin(id) { pendudukMiskinLayer.eachLayer(l => { if (l.miskinData && l.miskinData.id == id) { map.setView(l.getLatLng(), 17); l.openPopup(); } }); } // ---- Hook: klik peta saat mode miskin_click ---- // Ditangkap oleh kemiskinan.js via contextmenu — mode ini pakai klik kiri map.on('click', function(e) { if (window.currentAddMode === 'miskin_click') { window.currentAddMode = null; document.getElementById('map').style.cursor = ''; if (window.cursorTooltip) window.cursorTooltip.style.display = 'none'; // Buka form tambah miskin if (typeof window.formAddMiskin === 'function') { window.formAddMiskin(e.latlng.lat, e.latlng.lng); } } }); // ========================== // ===== Log Bantuan Modal == // ========================== const logModal = document.getElementById('logBantuanModal'); const logTitle = document.getElementById('logBantuanTitle'); const logList = document.getElementById('logBantuanList'); const logSaveBtn = document.getElementById('logSaveBtn'); const logIbadahSel = document.getElementById('logIbadahId'); let _logMiskinId = null; window.openLogBantuan = function (miskinId, nama) { _logMiskinId = miskinId; logTitle.textContent = `Log Bantuan — ${nama}`; logModal.classList.add('show'); // Isi dropdown ibadah logIbadahSel.innerHTML = ''; if (typeof ibadahDataList !== 'undefined') { ibadahDataList.forEach(ib => { const opt = document.createElement('option'); opt.value = ib.id; opt.textContent = `${IBADAH_EMOJI[ib.jenis] || '🕌'} ${ib.nama}`; logIbadahSel.appendChild(opt); }); } // Set tanggal default hari ini document.getElementById('logTanggal').valueAsDate = new Date(); fetchLogBantuan(miskinId); }; window.closeLogBantuanModal = function () { logModal.classList.remove('show'); _logMiskinId = null; }; function fetchLogBantuan(miskinId) { logList.innerHTML = '
Memuat...
'; fetch(`api/log_bantuan/read.php?miskin_id=${miskinId}`) .then(r => r.json()) .then(data => { if (!data.data || !data.data.length) { logList.innerHTML = '
Belum ada riwayat bantuan
'; return; } logList.innerHTML = ''; data.data.forEach(log => { const tgl = new Date(log.tanggal).toLocaleDateString('id-ID', { day:'2-digit', month:'short', year:'numeric' }); const item = document.createElement('div'); item.className = 'log-item'; item.innerHTML = `
${escHtml(log.tipe_bantuan)}
${IBADAH_EMOJI[log.jenis_ibadah] || '🕌'} ${escHtml(log.nama_ibadah)} • ${tgl}
${log.keterangan ? `
${escHtml(log.keterangan)}
` : ''}
`; logList.appendChild(item); }); }) .catch(() => { logList.innerHTML = '
Gagal memuat data
'; }); } logSaveBtn.addEventListener('click', function () { const ibadah_id = logIbadahSel.value; const tipe_bantuan = document.getElementById('logTipeBantuan').value; const tanggal = document.getElementById('logTanggal').value; const keterangan = document.getElementById('logKeterangan').value; if (!ibadah_id) { alert('Pilih rumah ibadah terlebih dahulu!'); return; } if (!tanggal) { alert('Tanggal harus diisi!'); return; } fetch('api/log_bantuan/create.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ miskin_id: _logMiskinId, ibadah_id, tipe_bantuan, tanggal, keterangan }) }) .then(r => r.json()) .then(data => { if (data.status === 'success') { document.getElementById('logKeterangan').value = ''; fetchLogBantuan(_logMiskinId); } else { alert(data.message || 'Gagal menyimpan'); } }); }); // ---- Utility ---- function escHtml(str) { if (!str) return ''; return String(str).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } // ---- Expose ---- window.openRightPanel = openPanel; })();