245 lines
8.9 KiB
PHP
245 lines
8.9 KiB
PHP
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>Peta SPBU - Layer Control</title>
|
||
|
||
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
|
||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
body { font-family: 'Segoe UI', sans-serif; }
|
||
#map { height: 100vh; width: 100%; }
|
||
|
||
.leaflet-control-layers {
|
||
border-radius: 8px !important;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.2) !important;
|
||
font-size: 13px !important;
|
||
}
|
||
.leaflet-control-layers-expanded {
|
||
padding: 10px 14px !important;
|
||
min-width: 210px !important;
|
||
}
|
||
.leaflet-control-layers-separator {
|
||
margin: 6px 0 !important;
|
||
}
|
||
.leaflet-control-layers label {
|
||
font-weight: 500 !important;
|
||
color: #333 !important;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
padding: 2px 0;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div id="map"></div>
|
||
|
||
<script>
|
||
// =========================================================
|
||
// INISIALISASI PETA
|
||
// =========================================================
|
||
const map = L.map('map').setView([-0.02, 109.34], 13);
|
||
|
||
// Base layer
|
||
const osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||
maxZoom: 19,
|
||
attribution: '© OpenStreetMap contributors'
|
||
}).addTo(map);
|
||
|
||
// =========================================================
|
||
// LAYER GROUPS - dua kelompok berdasarkan status 24 jam
|
||
// =========================================================
|
||
const layerSPBU24Jam = L.layerGroup(); // status = 'yes'
|
||
const layerSPBUNon24Jam = L.layerGroup(); // status = 'no'
|
||
|
||
// Tampilkan kedua layer secara default
|
||
layerSPBU24Jam.addTo(map);
|
||
layerSPBUNon24Jam.addTo(map);
|
||
|
||
// =========================================================
|
||
// LAYERS CONTROL
|
||
// =========================================================
|
||
const baseMaps = {
|
||
"🗺️ OpenStreetMap": osm
|
||
};
|
||
|
||
const overlayMaps = {
|
||
"🟢 SPBU Buka 24 Jam" : layerSPBU24Jam,
|
||
"🔴 SPBU Tidak Buka 24 Jam" : layerSPBUNon24Jam
|
||
};
|
||
|
||
L.control.layers(baseMaps, overlayMaps, {
|
||
collapsed: false,
|
||
position: 'topright'
|
||
}).addTo(map);
|
||
|
||
// =========================================================
|
||
// ICON HELPER
|
||
// =========================================================
|
||
function buatIcon(warna) {
|
||
return L.icon({
|
||
iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-${warna}.png`,
|
||
shadowUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-shadow.png',
|
||
iconSize: [25, 41],
|
||
iconAnchor: [12, 41],
|
||
popupAnchor: [1, -34]
|
||
});
|
||
}
|
||
|
||
const iconHijau = buatIcon('green');
|
||
const iconMerah = buatIcon('red');
|
||
|
||
// =========================================================
|
||
// LOAD & RENDER DATA
|
||
// =========================================================
|
||
function loadData() {
|
||
layerSPBU24Jam.clearLayers();
|
||
layerSPBUNon24Jam.clearLayers();
|
||
|
||
fetch('ambil_data.php')
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
data.forEach(d => {
|
||
const is24Jam = d.status === 'yes';
|
||
const icon = is24Jam ? iconHijau : iconMerah;
|
||
|
||
const marker = L.marker([d.latitude, d.longitude], {
|
||
icon: icon,
|
||
draggable: true
|
||
});
|
||
|
||
marker.bindPopup(`
|
||
<div style="min-width:190px">
|
||
<b style="font-size:14px">${d.nama_spbu}</b><br>
|
||
<span style="color:#666">📞 ${d.no_wa}</span><br>
|
||
<span style="
|
||
display:inline-block; margin-top:5px; padding:2px 10px;
|
||
border-radius:12px; font-size:11px; font-weight:600;
|
||
background:${is24Jam ? '#d4edda' : '#f8d7da'};
|
||
color:${is24Jam ? '#155724' : '#721c24'}">
|
||
⏰ ${is24Jam ? 'Buka 24 Jam' : 'Tidak Buka 24 Jam'}
|
||
</span>
|
||
<hr style="margin:8px 0; border:none; border-top:1px solid #eee">
|
||
<button onclick="editData(${d.id},'${d.nama_spbu}','${d.no_wa}','${d.status}',${d.latitude},${d.longitude})"
|
||
style="padding:4px 10px; background:#3498db; color:#fff; border:none; border-radius:4px; cursor:pointer; font-size:12px; margin-right:4px">
|
||
✏️ Edit
|
||
</button>
|
||
<button onclick="hapusData(${d.id})"
|
||
style="padding:4px 10px; background:#e74c3c; color:#fff; border:none; border-radius:4px; cursor:pointer; font-size:12px">
|
||
🗑️ Hapus
|
||
</button>
|
||
</div>
|
||
`);
|
||
|
||
marker.on('dragend', function(e) {
|
||
const pos = e.target.getLatLng();
|
||
fetch('update.php', {
|
||
method: 'POST',
|
||
body: new URLSearchParams({
|
||
id: d.id, nama: d.nama_spbu, wa: d.no_wa,
|
||
status: d.status, lat: pos.lat, lng: pos.lng
|
||
})
|
||
})
|
||
.then(r => r.text())
|
||
.then(r => { if(r === "success") { alert("Lokasi diupdate"); loadData(); } });
|
||
});
|
||
|
||
// Masukkan ke layer group yang sesuai
|
||
if (is24Jam) {
|
||
layerSPBU24Jam.addLayer(marker);
|
||
} else {
|
||
layerSPBUNon24Jam.addLayer(marker);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
loadData();
|
||
|
||
// =========================================================
|
||
// KLIK PETA → TAMBAH DATA BARU
|
||
// =========================================================
|
||
map.on('click', function(e) {
|
||
const lat = e.latlng.lat;
|
||
const lng = e.latlng.lng;
|
||
|
||
const popupContent = `
|
||
<div style="min-width:200px">
|
||
<b>➕ Tambah SPBU Baru</b>
|
||
<hr style="margin:6px 0; border:none; border-top:1px solid #eee">
|
||
<form id="formSPBU" style="font-size:13px">
|
||
Nama SPBU:<br>
|
||
<input type="text" name="nama" required
|
||
style="width:100%; padding:4px 6px; margin:3px 0 8px; border:1px solid #ccc; border-radius:4px"><br>
|
||
No WhatsApp:<br>
|
||
<input type="text" name="wa" required
|
||
style="width:100%; padding:4px 6px; margin:3px 0 8px; border:1px solid #ccc; border-radius:4px"><br>
|
||
Status 24 Jam:<br>
|
||
<select name="status"
|
||
style="width:100%; padding:4px 6px; margin:3px 0 10px; border:1px solid #ccc; border-radius:4px">
|
||
<option value="yes">🟢 Buka 24 Jam</option>
|
||
<option value="no">🔴 Tidak Buka 24 Jam</option>
|
||
</select><br>
|
||
<button type="submit"
|
||
style="width:100%; padding:6px; background:#2ecc71; color:#fff; border:none; border-radius:4px; cursor:pointer; font-weight:600">
|
||
💾 Simpan
|
||
</button>
|
||
</form>
|
||
</div>
|
||
`;
|
||
|
||
L.popup().setLatLng(e.latlng).setContent(popupContent).openOn(map);
|
||
|
||
setTimeout(() => {
|
||
const form = document.getElementById("formSPBU");
|
||
if (!form) return;
|
||
form.onsubmit = function(ev) {
|
||
ev.preventDefault();
|
||
const fd = new FormData(this);
|
||
fd.append("lat", lat);
|
||
fd.append("lng", lng);
|
||
fetch('simpan.php', { method: 'POST', body: fd })
|
||
.then(r => r.text())
|
||
.then(r => {
|
||
if(r === "success") { alert("Data berhasil disimpan"); map.closePopup(); loadData(); }
|
||
else { alert("Gagal menyimpan"); }
|
||
});
|
||
};
|
||
}, 100);
|
||
});
|
||
|
||
// =========================================================
|
||
// EDIT DATA
|
||
// =========================================================
|
||
function editData(id, nama, wa, status, lat, lng) {
|
||
const newNama = prompt("Nama SPBU:", nama);
|
||
const newWa = prompt("No WhatsApp:", wa);
|
||
const newStatus = prompt("Status 24 Jam (yes/no):", status);
|
||
if (newNama && newWa && newStatus) {
|
||
fetch('update.php', {
|
||
method: 'POST',
|
||
body: new URLSearchParams({ id, nama: newNama, wa: newWa, status: newStatus, lat, lng })
|
||
})
|
||
.then(r => r.text())
|
||
.then(r => { if(r === "success") { alert("Data diupdate"); map.closePopup(); loadData(); } });
|
||
}
|
||
}
|
||
|
||
// =========================================================
|
||
// HAPUS DATA
|
||
// =========================================================
|
||
function hapusData(id) {
|
||
if (confirm("Yakin mau hapus data SPBU ini?")) {
|
||
fetch('hapus.php', { method: 'POST', body: new URLSearchParams({ id }) })
|
||
.then(r => r.text())
|
||
.then(r => { if(r === "success") { alert("Data dihapus"); map.closePopup(); loadData(); } });
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|