// ========================================== // 1. INISIALISASI PETA & LAYER // ========================================== var map = L.map('map', { zoomControl: false }).setView([-0.0227, 109.3425], 14); // Zoom control di kanan bawah L.control.zoom({ position: 'bottomright' }).addTo(map); // OpenStreetMap Tile Layer L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); // Layer Groups var spbu24JamLayer = L.layerGroup().addTo(map); var spbuRegulerLayer = L.layerGroup().addTo(map); var drawnItems = new L.FeatureGroup().addTo(map); // Layer Control (Checkbox di kanan atas) var overlayMaps = { "⛽ SPBU Buka 24 Jam": spbu24JamLayer, "⛽ SPBU Reguler": spbuRegulerLayer }; L.control.layers(null, overlayMaps, { collapsed: true, position: 'bottomleft' }).addTo(map); // Standard Leaflet Marker Icons var 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], shadowSize: [41, 41] }); var 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], shadowSize: [41, 41] }); // Global Variables var databasePencarian = []; var spbuMarkers = {}; var sidebarPickMode = false; var sidebarTempLat = 0.0; var sidebarTempLng = 0.0; // ========================================== // 2. FUNGSI LOAD DATA DARI DATABASE // ========================================== function loadSPBU() { spbu24JamLayer.clearLayers(); spbuRegulerLayer.clearLayers(); spbuMarkers = {}; databasePencarian = []; fetch('load.php?jenis=spbu') .then(res => res.json()) .then(data => { data.forEach(item => { var is24Jam = item.kategori === 'Ya'; var statusBuka = is24Jam ? 'Buka 24 Jam' : 'Reguler'; var icon = is24Jam ? greenIcon : redIcon; var statusColor = is24Jam ? '#10b981' : '#ef4444'; var viewHTML = ` `; var marker = L.marker([item.latitude, item.longitude], { icon: icon, draggable: false }); if (is24Jam) { marker.addTo(spbu24JamLayer); } else { marker.addTo(spbuRegulerLayer); } marker.bindPopup(viewHTML); spbuMarkers[String(item.id)] = marker; marker.on('click', function () { map.flyTo(marker.getLatLng(), 16, { animate: true }); }); // Update coordinates input on marker drag end (during edit) marker.on('dragend', function (e) { var position = marker.getLatLng(); if (document.getElementById('edit_lat')) { document.getElementById('edit_lat').value = position.lat.toFixed(6); document.getElementById('edit_lng').value = position.lng.toFixed(6); } marker.openPopup(); }); databasePencarian.push({ namaLower: item.nama_spbu.toLowerCase(), namaAsli: item.nama_spbu, kategori: 'SPBU', ikon: '⛽', tipe: 'titik', layer: marker }); }); }) .catch(e => console.log('Belum ada data SPBU', e)); } // Load data awal loadSPBU(); // ========================================== // 3. EDIT & UPDATE DATA // ========================================== function formEditSPBU(id, nama, hp, kategori) { var markerId = String(id); var currentMarker = spbuMarkers[markerId]; if (currentMarker) { currentMarker.dragging.enable(); } setTimeout(function () { var container = document.getElementById(`popup-spbu-${id}`); if (!container) return; var lat = currentMarker.getLatLng().lat.toFixed(6); var lng = currentMarker.getLatLng().lng.toFixed(6); container.innerHTML = ` `; }, 50); } function updateData(e, tabel, id) { e.preventDefault(); var formData = new FormData(); formData.append('tabel', tabel); formData.append('id', id); formData.append('nama_spbu', document.getElementById('edit_nama').value); formData.append('no_hp', document.getElementById('edit_hp').value); formData.append('kategori', document.getElementById('edit_kategori').value); // Get current dragged position var markerPosisi = spbuMarkers[String(id)].getLatLng(); formData.append('latitude', markerPosisi.lat); formData.append('longitude', markerPosisi.lng); fetch('update_data.php', { method: 'POST', body: formData }) .then(r => r.text()) .then(res => { alert(res); map.closePopup(); loadSPBU(); }) .catch(error => console.error("Error updating data:", error)); } // ========================================== // 4. HAPUS DATA // ========================================== function deleteData(tabel, id) { if (confirm('Apakah Anda yakin ingin menghapus data SPBU ini?')) { var formData = new FormData(); formData.append('id', id); formData.append('tabel', tabel); fetch('delete_data.php', { method: 'POST', body: formData }) .then(r => r.text()) .then(res => { alert(res); map.closePopup(); loadSPBU(); }) .catch(error => console.error("Error deleting data:", error)); } } // ========================================== // 5. SISTEM PENCARIAN & ZOOM // ========================================== function jalankanPencarian() { var kataKunci = document.getElementById('search-input').value.toLowerCase(); var kategori = document.getElementById('search-category').value; var wadahHasil = document.getElementById('search-results'); wadahHasil.innerHTML = ''; if (kataKunci.length < 2) { wadahHasil.style.display = 'none'; return; } var hasil = databasePencarian.filter(function (item) { var cocokNama = item.namaLower.includes(kataKunci); var cocokKategori = (kategori === 'Semua') || (item.kategori === kategori); return cocokNama && cocokKategori; }); if (hasil.length > 0) { wadahHasil.style.display = 'block'; wadahHasil.innerHTML = `
${hasil.length} hasil ditemukan
`; hasil.forEach(function (item) { var div = document.createElement('div'); div.className = 'result-item'; div.innerHTML = `
${item.ikon}
${item.namaAsli}
Klik untuk zoom ke lokasi
${item.kategori}`; div.onclick = function () { map.flyTo(item.layer.getLatLng(), 16, { animate: true, duration: 1.5 }); item.layer.openPopup(); wadahHasil.style.display = 'none'; document.getElementById('search-input').value = item.namaAsli; toggleClearBtn(); }; wadahHasil.appendChild(div); }); } else { wadahHasil.style.display = 'block'; wadahHasil.innerHTML = `
Data tidak ditemukan
`; } } function toggleClearBtn() { var input = document.getElementById('search-input'); var clearBtn = document.getElementById('search-clear'); clearBtn.style.display = input.value.length > 0 ? 'flex' : 'none'; } function clearSearch() { document.getElementById('search-input').value = ''; document.getElementById('search-results').style.display = 'none'; document.getElementById('search-clear').style.display = 'none'; } // Tutup hasil saat klik di luar document.addEventListener('click', function (e) { var wrapper = document.querySelector('.search-wrapper'); if (wrapper && !wrapper.contains(e.target)) { document.getElementById('search-results').style.display = 'none'; } }); // Shortcut Ctrl + K untuk fokus ke pencarian document.addEventListener('keydown', function (e) { if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); document.getElementById('search-input').focus(); } if (e.key === 'Escape') { clearSearch(); document.getElementById('search-input').blur(); } }); // ========================================== // 6. LOGIKA INPUT SIDEBAR & PROGRAMMATIC PICK // ========================================== // Buka/Tutup Sidebar document.getElementById('sidebar-toggle').addEventListener('click', function () { var sidebar = document.getElementById('input-sidebar'); sidebar.classList.toggle('open'); this.classList.toggle('open'); }); document.getElementById('sidebar-close').addEventListener('click', function () { document.getElementById('input-sidebar').classList.remove('open'); document.getElementById('sidebar-toggle').classList.remove('open'); }); // Aktifkan mode pilih titik di peta function activatePickMode() { sidebarPickMode = true; document.getElementById('pick-overlay').classList.add('active'); document.getElementById('btn-pick-spbu').classList.add('active-pick'); map.getContainer().style.cursor = 'crosshair'; } // Batalkan mode pick function deactivatePickMode() { sidebarPickMode = false; document.getElementById('pick-overlay').classList.remove('active'); document.getElementById('btn-pick-spbu').classList.remove('active-pick'); map.getContainer().style.cursor = ''; } // Tangkap klik peta untuk mendapatkan koordinat map.on('click', function (e) { if (!sidebarPickMode) return; var lat = e.latlng.lat; var lng = e.latlng.lng; sidebarTempLat = lat; sidebarTempLng = lng; var el = document.getElementById('coords-spbu-val'); el.textContent = lat.toFixed(6) + ', ' + lng.toFixed(6); el.classList.add('has-coords'); // Tempatkan penanda sementara drawnItems.clearLayers(); L.marker([lat, lng], { icon: redIcon }).addTo(drawnItems); deactivatePickMode(); }); // ========================================== // 7. SIMPAN DATA DARI SIDEBAR // ========================================== function saveSPBUSidebar() { if (!sidebarTempLat || !sidebarTempLng) { alert('Silakan pilih lokasi SPBU di peta terlebih dahulu!'); return; } var nama = document.getElementById('sb_nama_spbu').value.trim(); if (!nama) { alert('Nama SPBU wajib diisi!'); return; } var formData = new FormData(); formData.append('nama_spbu', nama); formData.append('no_hp', document.getElementById('sb_nohp_spbu').value.trim()); formData.append('kategori', document.getElementById('sb_kategori_spbu').value); formData.append('latitude', sidebarTempLat); formData.append('longitude', sidebarTempLng); fetch('save.php', { method: 'POST', body: formData }) .then(r => r.text()) .then(res => { alert(res); document.getElementById('sb_nama_spbu').value = ''; document.getElementById('sb_nohp_spbu').value = ''; document.getElementById('coords-spbu-val').textContent = 'Belum dipilih'; document.getElementById('coords-spbu-val').classList.remove('has-coords'); sidebarTempLat = 0.0; sidebarTempLng = 0.0; drawnItems.clearLayers(); loadSPBU(); }) .catch(e => console.error("Error saving SPBU:", e)); } // ========================================== // 8. DROPDOWN KATEGORI DI HEADER // ========================================== document.addEventListener('DOMContentLoaded', function () { var wrap = document.getElementById('custom-select-wrap'); var trigger = document.getElementById('custom-select-trigger'); var options = document.getElementById('custom-select-options'); var hiddenInput = document.getElementById('search-category'); var optionItems = document.querySelectorAll('.custom-option'); // Toggle dropdown wrap.addEventListener('click', function (e) { e.stopPropagation(); options.classList.toggle('show'); }); // Pilihan dropdown diklik optionItems.forEach(function (item) { item.addEventListener('click', function (e) { e.stopPropagation(); optionItems.forEach(opt => opt.classList.remove('selected')); this.classList.add('selected'); trigger.textContent = this.textContent; hiddenInput.value = this.getAttribute('data-value'); options.classList.remove('show'); jalankanPencarian(); }); }); // Tutup dropdown jika klik di luar document.addEventListener('click', function () { options.classList.remove('show'); }); });