271 lines
11 KiB
JavaScript
271 lines
11 KiB
JavaScript
// ===== Panel Management =====
|
|
// Mengelola Left Sidebar Toggle + Right Panel + Layer Control
|
|
|
|
(function () {
|
|
// ---- 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 ----
|
|
if (sidebarToggleBtn) {
|
|
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);
|
|
}
|
|
});
|
|
});
|
|
|
|
if (rightPanelClose) {
|
|
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 = '<div class="panel-empty">Memuat data...</div>';
|
|
rightPanelActions.innerHTML = '';
|
|
|
|
switch (type) {
|
|
case 'spbu': renderSpbuPanel(); break;
|
|
case 'jalan': renderJalanPanel(); break;
|
|
case 'parsil': renderParsilPanel(); break;
|
|
}
|
|
}
|
|
|
|
// ==========================
|
|
// ===== SPBU Panel =======
|
|
// ==========================
|
|
function renderSpbuPanel() {
|
|
rightPanelTitle.textContent = '⛽ Daftar SPBU';
|
|
const isAdmin = !!(window.currentUser && window.currentUser.role === 'admin');
|
|
if (isAdmin) {
|
|
rightPanelActions.innerHTML = `
|
|
<button class="btn-panel-add" id="btnPanelAddSpbu">
|
|
<i class="fas fa-plus"></i> Tambah SPBU
|
|
</button>`;
|
|
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 = '<div class="panel-empty">Belum ada data SPBU</div>';
|
|
return;
|
|
}
|
|
|
|
rightPanelBody.innerHTML = '';
|
|
items.forEach(d => {
|
|
const card = document.createElement('div');
|
|
card.className = 'data-card';
|
|
let actionButtons = '';
|
|
if (isAdmin) {
|
|
actionButtons = `
|
|
<div class="data-card-actions">
|
|
<button class="btn-card-action btn-card-edit" title="Edit"><i class="fas fa-pen"></i></button>
|
|
<button class="btn-card-action btn-card-delete" title="Hapus"><i class="fas fa-trash"></i></button>
|
|
</div>
|
|
`;
|
|
}
|
|
card.innerHTML = `
|
|
<div class="data-card-main">
|
|
<div class="data-card-icon" style="background:#fef3c7; color:#d97706; padding:8px; border-radius:8px; font-size:18px;">⛽</div>
|
|
<div class="data-card-info">
|
|
<div class="data-card-name">${escHtml(d.nama)}</div>
|
|
<div class="data-card-sub">📞 ${escHtml(d.no_wa || '-')} • 🕐 ${d.is_24_jam ? '24 Jam' : 'Tidak 24 Jam'}</div>
|
|
</div>
|
|
${actionButtons}
|
|
</div>`;
|
|
if (isAdmin) {
|
|
card.querySelector('.btn-card-edit').addEventListener('click', (e) => { e.stopPropagation(); window.openEditSpbuModal(d.id); });
|
|
card.querySelector('.btn-card-delete').addEventListener('click', (e) => { e.stopPropagation(); window.deleteSpbu(d.id); });
|
|
}
|
|
card.addEventListener('click', () => {
|
|
spbuLayer.eachLayer(l => {
|
|
if (l.spbuData && l.spbuData.id == d.id) {
|
|
map.setView(l.getLatLng(), 17); l.openPopup();
|
|
}
|
|
});
|
|
});
|
|
rightPanelBody.appendChild(card);
|
|
});
|
|
}
|
|
|
|
// ==========================
|
|
// ===== Jalan Panel =======
|
|
// ==========================
|
|
function renderJalanPanel() {
|
|
rightPanelTitle.textContent = '🛣️ Daftar Jalan';
|
|
const isAdmin = !!(window.currentUser && window.currentUser.role === 'admin');
|
|
|
|
rightPanelActions.innerHTML = '';
|
|
|
|
const items = [];
|
|
jalanLayer.eachLayer(l => {
|
|
if (l.jalanData) items.push(l.jalanData);
|
|
});
|
|
|
|
if (!items.length) {
|
|
rightPanelBody.innerHTML = '<div class="panel-empty">Belum ada data Jalan</div>';
|
|
return;
|
|
}
|
|
|
|
rightPanelBody.innerHTML = '';
|
|
items.forEach(d => {
|
|
const card = document.createElement('div');
|
|
card.className = 'data-card';
|
|
let actionButtons = '';
|
|
if (isAdmin) {
|
|
actionButtons = `
|
|
<div class="data-card-actions">
|
|
<button class="btn-card-action btn-card-edit" title="Edit"><i class="fas fa-pen"></i></button>
|
|
<button class="btn-card-action btn-card-delete" title="Hapus"><i class="fas fa-trash"></i></button>
|
|
</div>
|
|
`;
|
|
}
|
|
card.innerHTML = `
|
|
<div class="data-card-main">
|
|
<div class="data-card-icon" style="background:#e0e7ff; color:#4f46e5; padding:8px; border-radius:8px; font-size:18px;">🛣️</div>
|
|
<div class="data-card-info">
|
|
<div class="data-card-name">${escHtml(d.nama)}</div>
|
|
<div class="data-card-sub">📏 ${d.panjang.toFixed(2)} m • 🏷️ ${escHtml(d.status)}</div>
|
|
</div>
|
|
${actionButtons}
|
|
</div>`;
|
|
if (isAdmin) {
|
|
card.querySelector('.btn-card-edit').addEventListener('click', (e) => { e.stopPropagation(); window.openEditJalanModal(d.id); });
|
|
card.querySelector('.btn-card-delete').addEventListener('click', (e) => { e.stopPropagation(); window.deleteJalan(d.id); });
|
|
}
|
|
card.addEventListener('click', () => {
|
|
jalanLayer.eachLayer(l => {
|
|
if (l.jalanData && l.jalanData.id == d.id) {
|
|
map.fitBounds(l.getBounds()); l.openPopup();
|
|
}
|
|
});
|
|
});
|
|
rightPanelBody.appendChild(card);
|
|
});
|
|
}
|
|
|
|
// ==========================
|
|
// ===== Parsil Panel =======
|
|
// ==========================
|
|
function renderParsilPanel() {
|
|
rightPanelTitle.textContent = '🗺️ Daftar Parsil Tanah';
|
|
const isAdmin = !!(window.currentUser && window.currentUser.role === 'admin');
|
|
|
|
rightPanelActions.innerHTML = '';
|
|
|
|
const items = [];
|
|
parsilLayer.eachLayer(l => {
|
|
if (l.parsilData) items.push(l.parsilData);
|
|
});
|
|
|
|
if (!items.length) {
|
|
rightPanelBody.innerHTML = '<div class="panel-empty">Belum ada data Parsil</div>';
|
|
return;
|
|
}
|
|
|
|
rightPanelBody.innerHTML = '';
|
|
items.forEach(d => {
|
|
const card = document.createElement('div');
|
|
card.className = 'data-card';
|
|
let actionButtons = '';
|
|
if (isAdmin) {
|
|
actionButtons = `
|
|
<div class="data-card-actions">
|
|
<button class="btn-card-action btn-card-edit" title="Edit"><i class="fas fa-pen"></i></button>
|
|
<button class="btn-card-action btn-card-delete" title="Hapus"><i class="fas fa-trash"></i></button>
|
|
</div>
|
|
`;
|
|
}
|
|
card.innerHTML = `
|
|
<div class="data-card-main">
|
|
<div class="data-card-icon" style="background:#d1fae5; color:#059669; padding:8px; border-radius:8px; font-size:18px;">🗺️</div>
|
|
<div class="data-card-info">
|
|
<div class="data-card-name">${escHtml(d.nama || 'Tanpa Nama')}</div>
|
|
<div class="data-card-sub">📐 ${d.luas.toFixed(2)} m² • 🏷️ ${escHtml(d.status)}</div>
|
|
</div>
|
|
${actionButtons}
|
|
</div>`;
|
|
if (isAdmin) {
|
|
card.querySelector('.btn-card-edit').addEventListener('click', (e) => { e.stopPropagation(); window.openEditParsilModal(d.id); });
|
|
card.querySelector('.btn-card-delete').addEventListener('click', (e) => { e.stopPropagation(); window.deleteParsil(d.id); });
|
|
}
|
|
card.addEventListener('click', () => {
|
|
parsilLayer.eachLayer(l => {
|
|
if (l.parsilData && l.parsilData.id == d.id) {
|
|
map.fitBounds(l.getBounds()); l.openPopup();
|
|
}
|
|
});
|
|
});
|
|
rightPanelBody.appendChild(card);
|
|
});
|
|
}
|
|
|
|
// ---- Utility ----
|
|
function escHtml(str) {
|
|
if (!str) return '';
|
|
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
|
}
|
|
|
|
// ---- Expose ----
|
|
window.openRightPanel = openPanel;
|
|
|
|
})();
|