// ===== 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 ---- // removed // removed 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 collapse handled in map.js // ---- 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) { if (typeof window.deactivateAddMode === 'function') window.deactivateAddMode(); activePanel = panel; rightPanel.classList.add('open'); document.body.classList.add('right-panel-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() { if (typeof window.deactivateAddMode === 'function') window.deactivateAddMode(); activePanel = null; rightPanel.classList.remove('open'); document.body.classList.remove('right-panel-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 'ibadah': renderIbadahPanel(); break; case 'miskin': renderMiskinPanel(); break; case 'log_bantuan': renderLogBantuanPanel(); break; } } // ========================== // ===== Ibadah Panel ======= // ========================== function renderIbadahPanel() { rightPanelTitle.textContent = '🕌 Rumah Ibadah'; const isAdmin = !!(window.currentUser && window.currentUser.role === 'admin'); if (isAdmin) { rightPanelActions.innerHTML = ` `; document.getElementById('btnPanelAddIbadah').addEventListener('click', () => { window.activateAddMode('rumah_ibadah'); }); } else { rightPanelActions.innerHTML = ''; } 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'; let actionButtons = ''; if (isAdmin) { actionButtons = `
`; } card.innerHTML = `
${emoji}
${escHtml(d.nama)}
${escHtml(d.jenis || 'Masjid')} • 📡 ${d.radius} m
${actionButtons}
`; if (isAdmin) { 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'; const canManage = !!(window.currentUser && (window.currentUser.role === 'admin' || window.currentUser.role === 'pengelola')); if (canManage) { const isPengelola = window.currentUser.role === 'pengelola'; const addLabel = isPengelola ? ' Tambah (dalam radius)' : ' Tambah'; rightPanelActions.innerHTML = ` `; document.getElementById('btnPanelTambahMiskin').addEventListener('click', () => { window.currentAddMode = 'miskin_click'; document.getElementById('map').style.cursor = 'crosshair'; if (window.cursorTooltip) { const tipText = isPengelola ? 'Klik di dalam radius ibadah Anda untuk tambah penduduk' : 'Klik di peta untuk tentukan lokasi penduduk miskin'; window.cursorTooltip.textContent = tipText; } }); document.getElementById('btnPanelImportMiskin').addEventListener('click', () => { if (typeof window.openImportMiskinModal === 'function') { window.openImportMiskinModal(); } else { alert('Fitur impor belum siap.'); } }); } else { rightPanelActions.innerHTML = ''; } 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))); } } // ========================== // ===== Log Bantuan Panel == // ========================== function renderLogBantuanPanel() { rightPanelTitle.textContent = '📋 Log Bantuan'; rightPanelActions.innerHTML = ''; const all = []; if (typeof pendudukMiskinLayer !== 'undefined') { pendudukMiskinLayer.eachLayer(l => { if (l.miskinData) all.push(l.miskinData); }); } if (!all.length) { rightPanelBody.innerHTML = '
Belum ada data penduduk miskin
'; return; } rightPanelBody.innerHTML = ''; const canLog = !!(window.currentUser && (window.currentUser.role === 'admin' || window.currentUser.role === 'pengelola')); // Hint strip const hint = document.createElement('div'); hint.className = 'panel-hint'; hint.innerHTML = ` ${canLog ? 'Klik penduduk untuk lihat atau tambah log bantuan.' : 'Klik penduduk untuk melihat riwayat log bantuan.'}`; rightPanelBody.appendChild(hint); // Summary badge const summary = document.createElement('div'); summary.className = 'panel-section-title'; summary.textContent = `${all.length} Kepala Keluarga`; rightPanelBody.appendChild(summary); all.forEach(d => { const isMakan = d.kategori_bantuan === 'Makan'; const card = document.createElement('div'); card.className = 'log-person-card'; const badgeHtml = isMakan ? 'Bantuan Makan' : 'Pemberdayaan'; const avatarCls = isMakan ? 'avatar-makan' : 'avatar-pmbr'; card.innerHTML = `
🏠
${escHtml(d.nama)}
👨‍👩‍👧 ${d.jumlah_jiwa || '-'} jiwa ${badgeHtml}
`; card.addEventListener('click', () => window.openLogBantuan(d.id, d.nama)); rightPanelBody.appendChild(card); }); } function buildMiskinCard(d, terurus) { // Pengelola hanya boleh edit/hapus penduduk yang dalam radius ibadahnya const isPengelolaOrAdmin = !!(window.currentUser && (window.currentUser.role === 'admin' || window.currentUser.role === 'pengelola')); const canManage = isPengelolaOrAdmin && (typeof window.isInMyIbadahRadius === 'function' ? window.isInMyIbadahRadius(d.lat, d.lng) : true); 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; let actionButtons = ''; if (canManage) { actionButtons = `
`; } let fotoHtml = ''; if (d.foto_rumah || d.foto_kk) { fotoHtml += `
`; if (d.foto_rumah) { fotoHtml += `
Foto Rumah
`; } if (d.foto_kk) { fotoHtml += `
Foto KK
`; } fotoHtml += `
`; } card.innerHTML = `
🏠
${escHtml(d.nama)}
👨‍👩‍👧 ${d.jumlah_jiwa || '-'} jiwa
${badge}
${actionButtons}
Kepala Keluarga${escHtml(d.nama)}
Kategori Bantuan${escHtml(d.kategori_bantuan)}
Jumlah Jiwa${d.jumlah_jiwa || '-'}
Status${terurus ? 'Terurus ✅' : 'Tidak Terurus ⚠️'}
${fotoHtml}
`; if (canManage) { 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 ================== // ========================================== window.openLogBantuan = function (miskinId, nama) { const modal = document.getElementById('logBantuanModal'); document.getElementById('logBantuanTitle').textContent = '📋 Log Bantuan — ' + nama; document.getElementById('logBantuanMiskinId').value = miskinId; modal.classList.add('show'); loadLogBantuan(miskinId); // Tampilkan form tambah hanya untuk admin/pengelola const canLog = !!(window.currentUser && (window.currentUser.role === 'admin' || window.currentUser.role === 'pengelola')); document.getElementById('logBantuanFormSection').style.display = canLog ? 'block' : 'none'; // Isi dropdown ibadah jika pengelola (auto-select ibadahnya) if (canLog) populateLogIbadahSelect(); }; window.closeLogBantuanModal = function () { document.getElementById('logBantuanModal').classList.remove('show'); }; function loadLogBantuan(miskinId) { const listEl = document.getElementById('logBantuanList'); listEl.innerHTML = '
Memuat log...
'; fetch('api/log_bantuan/read.php?miskin_id=' + miskinId) .then(r => r.json()) .then(res => { if (res.status !== 'success' || !res.data.length) { listEl.innerHTML = '
Belum ada log bantuan tercatat.
'; return; } listEl.innerHTML = ''; res.data.forEach(log => { const item = document.createElement('div'); item.className = 'log-item'; const tgl = new Date(log.tanggal).toLocaleDateString('id-ID', { day: '2-digit', month: 'short', year: 'numeric' }); item.innerHTML = `
${escHtml(log.tipe_bantuan)} ${tgl}
🕌 ${escHtml(log.nama_ibadah)} ${escHtml(log.jenis_ibadah)}
${log.keterangan ? `
${escHtml(log.keterangan)}
` : ''} `; listEl.appendChild(item); }); }) .catch(() => { listEl.innerHTML = '
Gagal memuat data log.
'; }); } function populateLogIbadahSelect() { const sel = document.getElementById('logIbadahId'); sel.innerHTML = ''; if (window.currentUser && window.currentUser.role === 'pengelola' && window.currentUser.ibadah_id) { // Pengelola hanya bisa pilih ibadah miliknya — fetch dari layer const id = window.currentUser.ibadah_id; let found = false; if (typeof rumahIbadahLayer !== 'undefined') { rumahIbadahLayer.eachLayer(l => { if (l.ibadahData) { const opt = document.createElement('option'); opt.value = l.ibadahData.id; opt.textContent = l.ibadahData.nama; if (l.ibadahData.id == id) { opt.selected = true; found = true; } sel.appendChild(opt); } }); } } else { // Admin bisa pilih semua if (typeof rumahIbadahLayer !== 'undefined') { rumahIbadahLayer.eachLayer(l => { if (l.ibadahData) { const opt = document.createElement('option'); opt.value = l.ibadahData.id; opt.textContent = l.ibadahData.nama; sel.appendChild(opt); } }); } } } document.getElementById('btnSaveLog').addEventListener('click', function () { const miskinId = parseInt(document.getElementById('logBantuanMiskinId').value); const ibadahId = parseInt(document.getElementById('logIbadahId').value); const tipe = document.getElementById('logTipeBantuan').value.trim(); const tanggal = document.getElementById('logTanggal').value; const keterangan = document.getElementById('logKeterangan').value.trim(); if (!ibadahId || !tipe || !tanggal) { window.showToast('Lengkapi semua field wajib', 'error'); return; } const btn = this; btn.disabled = true; btn.textContent = 'Menyimpan...'; fetch('api/log_bantuan/create.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ miskin_id: miskinId, ibadah_id: ibadahId, tipe_bantuan: tipe, tanggal, keterangan }) }) .then(r => r.json()) .then(res => { btn.disabled = false; btn.textContent = 'Simpan Log'; if (res.status === 'success') { window.showToast('Log bantuan berhasil disimpan', 'success'); document.getElementById('logTipeBantuan').value = ''; document.getElementById('logTanggal').value = ''; document.getElementById('logKeterangan').value = ''; loadLogBantuan(miskinId); } else { window.showToast(res.message || 'Gagal menyimpan log', 'error'); } }) .catch(() => { btn.disabled = false; btn.textContent = 'Simpan Log'; window.showToast('Terjadi kesalahan koneksi', 'error'); }); }); // Close on overlay click document.getElementById('logBantuanModal').addEventListener('click', function(e) { if (e.target === this) window.closeLogBantuanModal(); }); // ---- Utility ---- function escHtml(str) { if (!str) return ''; return String(str).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } // ---- Expose ---- window.openRightPanel = openPanel; })();