2nd commit: Menambahkan landing page, integrasi ikon FontAwesome secara global, dan perbaikan bug
This commit is contained in:
+15
-15
@@ -95,7 +95,7 @@ const RightToolbar = L.Control.extend({
|
||||
onAdd: function() {
|
||||
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
||||
container.innerHTML = `
|
||||
<button class="tool-btn" id="btn-tool-marker" title="Mode Marker" onclick="toggleMarkerMode()">📍</button>
|
||||
<button class="tool-btn" id="btn-tool-marker" title="Mode Marker" onclick="toggleMarkerMode()"><i class='fa-solid fa-map-pin'></i></button>
|
||||
`;
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
return container;
|
||||
@@ -200,7 +200,7 @@ map.on('click', async function(e) {
|
||||
// --- UTILITAS & KOSMETIK MODAL ---
|
||||
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
||||
const toast = document.getElementById('toast-notification');
|
||||
toast.innerText = pesan; toast.classList.add('show');
|
||||
toast.innerHTML = pesan; toast.classList.add('show');
|
||||
setTimeout(() => { toast.classList.remove('show'); }, 3000);
|
||||
}
|
||||
|
||||
@@ -355,19 +355,19 @@ function renderSPBU() {
|
||||
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
||||
marker.on('dragend', async function(e) {
|
||||
const pos = e.target.getLatLng();
|
||||
triggerToastNotification("⏳ Menganalisis alamat baru...");
|
||||
triggerToastNotification("<i class='fa-solid fa-hourglass-half'></i> Menganalisis alamat baru...");
|
||||
|
||||
// Tunggu alamat baru dari satelit sebelum dikirim ke database
|
||||
const alamatBaru = await dapatkanAlamat(pos.lat, pos.lng);
|
||||
|
||||
fetch('otak_spbu/api_update_coords.php', {
|
||||
fetch('../otak_spbu/api_update_coords.php', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ id: d.id, lat: pos.lat, lng: pos.lng, alamat: alamatBaru })
|
||||
}).then(res => res.ok ? res.json() : Promise.reject(res)).then(res => {
|
||||
dataStore.spbu[d.id].latitude = pos.lat;
|
||||
dataStore.spbu[d.id].longitude = pos.lng;
|
||||
dataStore.spbu[d.id].alamat = alamatBaru;
|
||||
triggerToastNotification("📍 Koordinat & Alamat berhasil digeser!");
|
||||
triggerToastNotification("<i class='fa-solid fa-map-pin'></i> Koordinat & Alamat berhasil digeser!");
|
||||
renderSPBU(); // Gambar ulang untuk update text di Sidebar
|
||||
}).catch(err => {
|
||||
alert("Gagal menyimpan posisi."); e.target.setLatLng([dataStore.spbu[d.id].latitude, dataStore.spbu[d.id].longitude]);
|
||||
@@ -456,15 +456,15 @@ window.eksekusiSimpanBaru = () => {
|
||||
lat: document.getElementById('spbu-lat').value,
|
||||
lng: document.getElementById('spbu-lng').value
|
||||
};
|
||||
safeFetch('../otak_spbu/api_simpan.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("✅ SPBU ditambahkan!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_simpan.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-check'></i> SPBU ditambahkan!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdate = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('spbu-nama').value, status: document.getElementById('spbu-status').value, telp: document.getElementById('spbu-telp').value };
|
||||
safeFetch('../otak_spbu/api_update.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("✅ SPBU diperbarui!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_update.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-check'></i> SPBU diperbarui!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapus = (id) => {
|
||||
if(!confirm("Hapus SPBU ini?")) return;
|
||||
safeFetch('../otak_spbu/api_hapus.php', { id: id }).then(() => { tutupModalSpbu(); triggerToastNotification("🗑️ SPBU dihapus."); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_hapus.php', { id: id }).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-trash'></i> SPBU dihapus."); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
// --- JALAN ---
|
||||
@@ -475,15 +475,15 @@ window.muatDataJalan = () => {
|
||||
};
|
||||
window.eksekusiSimpanJalan = () => {
|
||||
const payload = { nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value, jarak: document.getElementById('jalan-jarak').value, koordinat: document.getElementById('jalan-koordinat').value };
|
||||
safeFetch('../otak_jalan/api_simpan.php', payload).then(() => { batalGambarJalan(); triggerToastNotification("✅ Jalan ditambahkan!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_simpan.php', payload).then(() => { batalGambarJalan(); triggerToastNotification("<i class='fa-solid fa-check'></i> Jalan ditambahkan!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdateJalan = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
||||
safeFetch('../otak_jalan/api_update.php', payload).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("✅ Jalan diperbarui!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_update.php', payload).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> Jalan diperbarui!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapusJalan = (id) => {
|
||||
if(!confirm("Hapus jalur ini?")) return;
|
||||
safeFetch('../otak_jalan/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("🗑️ Jalan dihapus."); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("<i class='fa-solid fa-trash'></i> Jalan dihapus."); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
// --- TANAH ---
|
||||
@@ -494,15 +494,15 @@ window.muatDataTanah = () => {
|
||||
};
|
||||
window.eksekusiSimpanTanah = () => {
|
||||
const payload = { nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value, luas: document.getElementById('tanah-luas').value, koordinat: document.getElementById('tanah-koordinat').value };
|
||||
safeFetch('../otak_parsil/api_simpan.php', payload).then(() => { batalGambarTanah(); triggerToastNotification("✅ Tanah ditambahkan!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_simpan.php', payload).then(() => { batalGambarTanah(); triggerToastNotification("<i class='fa-solid fa-check'></i> Tanah ditambahkan!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdateTanah = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value };
|
||||
safeFetch('../otak_parsil/api_update.php', payload).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("✅ Tanah diperbarui!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_update.php', payload).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> Tanah diperbarui!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapusTanah = (id) => {
|
||||
if(!confirm("Hapus parsil ini?")) return;
|
||||
safeFetch('../otak_parsil/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("🗑️ Tanah dihapus."); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("<i class='fa-solid fa-trash'></i> Tanah dihapus."); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@ setTimeout(() => {
|
||||
Promise.all([
|
||||
muatDataSPBU()
|
||||
]).then(() => {
|
||||
console.log("✅ Sistem WebGIS V2 Siap dan Data Tersinkronisasi Penuh.");
|
||||
console.log("<i class='fa-solid fa-check'></i> Sistem WebGIS V2 Siap dan Data Tersinkronisasi Penuh.");
|
||||
}).catch(err => {
|
||||
console.error("Kegagalan Fatal Jaringan:", err);
|
||||
});
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
|
||||
<link rel="stylesheet" href="../assets/style.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="sidebar-container">
|
||||
<a href="../" class="btn-back-home">⬅ Kembali ke Beranda</a>
|
||||
<div id="sidebar-header">
|
||||
WebGis-Pontianak
|
||||
</div>
|
||||
|
||||
+17
-17
@@ -87,9 +87,9 @@ const RightToolbar = L.Control.extend({
|
||||
onAdd: function() {
|
||||
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
||||
container.innerHTML = `
|
||||
<button class="tool-btn" id="btn-tool-marker" title="Mode Marker" onclick="toggleMarkerMode()">📍</button>
|
||||
<button class="tool-btn" id="btn-tool-jalan" title="Mode Jalan" onclick="toggleRoadMode()">🛣️</button>
|
||||
<button class="tool-btn" id="btn-tool-tanah" title="Mode Tanah" onclick="toggleLandMode()">🟩</button>
|
||||
<button class="tool-btn" id="btn-tool-marker" title="Mode Marker" onclick="toggleMarkerMode()"><i class='fa-solid fa-map-pin'></i></button>
|
||||
<button class="tool-btn" id="btn-tool-jalan" title="Mode Jalan" onclick="toggleRoadMode()"><i class='fa-solid fa-road'></i></button>
|
||||
<button class="tool-btn" id="btn-tool-tanah" title="Mode Tanah" onclick="toggleLandMode()"><i class='fa-solid fa-draw-polygon'></i></button>
|
||||
`;
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
return container;
|
||||
@@ -183,7 +183,7 @@ map.on('click', async function(e) {
|
||||
// --- UTILITAS & KOSMETIK MODAL ---
|
||||
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
||||
const toast = document.getElementById('toast-notification');
|
||||
toast.innerText = pesan; toast.classList.add('show');
|
||||
toast.innerHTML = pesan; toast.classList.add('show');
|
||||
setTimeout(() => { toast.classList.remove('show'); }, 3000);
|
||||
}
|
||||
|
||||
@@ -337,19 +337,19 @@ function renderSPBU() {
|
||||
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
||||
marker.on('dragend', async function(e) {
|
||||
const pos = e.target.getLatLng();
|
||||
triggerToastNotification("⏳ Menganalisis alamat baru...");
|
||||
triggerToastNotification("<i class='fa-solid fa-hourglass-half'></i> Menganalisis alamat baru...");
|
||||
|
||||
// Tunggu alamat baru dari satelit sebelum dikirim ke database
|
||||
const alamatBaru = await dapatkanAlamat(pos.lat, pos.lng);
|
||||
|
||||
fetch('otak_spbu/api_update_coords.php', {
|
||||
fetch('../otak_spbu/api_update_coords.php', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ id: d.id, lat: pos.lat, lng: pos.lng, alamat: alamatBaru })
|
||||
}).then(res => res.ok ? res.json() : Promise.reject(res)).then(res => {
|
||||
dataStore.spbu[d.id].latitude = pos.lat;
|
||||
dataStore.spbu[d.id].longitude = pos.lng;
|
||||
dataStore.spbu[d.id].alamat = alamatBaru;
|
||||
triggerToastNotification("📍 Koordinat & Alamat berhasil digeser!");
|
||||
triggerToastNotification("<i class='fa-solid fa-map-pin'></i> Koordinat & Alamat berhasil digeser!");
|
||||
renderSPBU(); // Gambar ulang untuk update text di Sidebar
|
||||
}).catch(err => {
|
||||
alert("Gagal menyimpan posisi."); e.target.setLatLng([dataStore.spbu[d.id].latitude, dataStore.spbu[d.id].longitude]);
|
||||
@@ -436,15 +436,15 @@ window.eksekusiSimpanBaru = () => {
|
||||
lat: document.getElementById('spbu-lat').value,
|
||||
lng: document.getElementById('spbu-lng').value
|
||||
};
|
||||
safeFetch('../otak_spbu/api_simpan.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("✅ SPBU ditambahkan!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_simpan.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-check'></i> SPBU ditambahkan!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdate = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('spbu-nama').value, status: document.getElementById('spbu-status').value, telp: document.getElementById('spbu-telp').value };
|
||||
safeFetch('../otak_spbu/api_update.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("✅ SPBU diperbarui!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_update.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-check'></i> SPBU diperbarui!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapus = (id) => {
|
||||
if(!confirm("Hapus SPBU ini?")) return;
|
||||
safeFetch('../otak_spbu/api_hapus.php', { id: id }).then(() => { tutupModalSpbu(); triggerToastNotification("🗑️ SPBU dihapus."); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_hapus.php', { id: id }).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-trash'></i> SPBU dihapus."); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
// --- JALAN ---
|
||||
@@ -455,15 +455,15 @@ window.muatDataJalan = () => {
|
||||
};
|
||||
window.eksekusiSimpanJalan = () => {
|
||||
const payload = { nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value, jarak: document.getElementById('jalan-jarak').value, koordinat: document.getElementById('jalan-koordinat').value };
|
||||
safeFetch('../otak_jalan/api_simpan.php', payload).then(() => { batalGambarJalan(); triggerToastNotification("✅ Jalan ditambahkan!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_simpan.php', payload).then(() => { batalGambarJalan(); triggerToastNotification("<i class='fa-solid fa-check'></i> Jalan ditambahkan!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdateJalan = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
||||
safeFetch('../otak_jalan/api_update.php', payload).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("✅ Jalan diperbarui!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_update.php', payload).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> Jalan diperbarui!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapusJalan = (id) => {
|
||||
if(!confirm("Hapus jalur ini?")) return;
|
||||
safeFetch('../otak_jalan/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("🗑️ Jalan dihapus."); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("<i class='fa-solid fa-trash'></i> Jalan dihapus."); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
// --- TANAH ---
|
||||
@@ -474,15 +474,15 @@ window.muatDataTanah = () => {
|
||||
};
|
||||
window.eksekusiSimpanTanah = () => {
|
||||
const payload = { nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value, luas: document.getElementById('tanah-luas').value, koordinat: document.getElementById('tanah-koordinat').value };
|
||||
safeFetch('../otak_parsil/api_simpan.php', payload).then(() => { batalGambarTanah(); triggerToastNotification("✅ Tanah ditambahkan!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_simpan.php', payload).then(() => { batalGambarTanah(); triggerToastNotification("<i class='fa-solid fa-check'></i> Tanah ditambahkan!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdateTanah = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value };
|
||||
safeFetch('../otak_parsil/api_update.php', payload).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("✅ Tanah diperbarui!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_update.php', payload).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> Tanah diperbarui!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapusTanah = (id) => {
|
||||
if(!confirm("Hapus parsil ini?")) return;
|
||||
safeFetch('../otak_parsil/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("🗑️ Tanah dihapus."); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("<i class='fa-solid fa-trash'></i> Tanah dihapus."); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
|
||||
@@ -498,7 +498,7 @@ setTimeout(() => {
|
||||
muatDataJalan(),
|
||||
muatDataTanah()
|
||||
]).then(() => {
|
||||
console.log("✅ Sistem WebGIS V2 Siap dan Data Tersinkronisasi Penuh.");
|
||||
console.log("<i class='fa-solid fa-check'></i> Sistem WebGIS V2 Siap dan Data Tersinkronisasi Penuh.");
|
||||
}).catch(err => {
|
||||
console.error("Kegagalan Fatal Jaringan:", err);
|
||||
});
|
||||
|
||||
+4
-2
@@ -8,10 +8,12 @@
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
|
||||
|
||||
<link rel="stylesheet" href="../assets/style.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="sidebar-container">
|
||||
<a href="../" class="btn-back-home">⬅ Kembali ke Beranda</a>
|
||||
<div id="sidebar-header">
|
||||
WebGis-Pontianak
|
||||
</div>
|
||||
@@ -23,8 +25,8 @@
|
||||
</div>
|
||||
<?php include '../components/modals.php'; ?>
|
||||
|
||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()">✓ Selesai Gambar Jalan</button>
|
||||
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()">✓ Selesai Area Tanah</button>
|
||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()"><i class='fa-solid fa-check'></i> Selesai Gambar Jalan</button>
|
||||
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()"><i class='fa-solid fa-check'></i> Selesai Area Tanah</button>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
|
||||
+17
-17
@@ -91,9 +91,9 @@ const RightToolbar = L.Control.extend({
|
||||
onAdd: function() {
|
||||
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
||||
container.innerHTML = `
|
||||
<button class="tool-btn" id="btn-tool-marker" title="Mode Marker" onclick="toggleMarkerMode()">📍</button>
|
||||
<button class="tool-btn" id="btn-tool-jalan" title="Mode Jalan" onclick="toggleRoadMode()">🛣️</button>
|
||||
<button class="tool-btn" id="btn-tool-tanah" title="Mode Tanah" onclick="toggleLandMode()">🟩</button>
|
||||
<button class="tool-btn" id="btn-tool-marker" title="Mode Marker" onclick="toggleMarkerMode()"><i class='fa-solid fa-map-pin'></i></button>
|
||||
<button class="tool-btn" id="btn-tool-jalan" title="Mode Jalan" onclick="toggleRoadMode()"><i class='fa-solid fa-road'></i></button>
|
||||
<button class="tool-btn" id="btn-tool-tanah" title="Mode Tanah" onclick="toggleLandMode()"><i class='fa-solid fa-draw-polygon'></i></button>
|
||||
`;
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
return container;
|
||||
@@ -198,7 +198,7 @@ map.on('click', async function(e) {
|
||||
// --- UTILITAS & KOSMETIK MODAL ---
|
||||
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
||||
const toast = document.getElementById('toast-notification');
|
||||
toast.innerText = pesan; toast.classList.add('show');
|
||||
toast.innerHTML = pesan; toast.classList.add('show');
|
||||
setTimeout(() => { toast.classList.remove('show'); }, 3000);
|
||||
}
|
||||
|
||||
@@ -353,19 +353,19 @@ function renderSPBU() {
|
||||
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
||||
marker.on('dragend', async function(e) {
|
||||
const pos = e.target.getLatLng();
|
||||
triggerToastNotification("⏳ Menganalisis alamat baru...");
|
||||
triggerToastNotification("<i class='fa-solid fa-hourglass-half'></i> Menganalisis alamat baru...");
|
||||
|
||||
// Tunggu alamat baru dari satelit sebelum dikirim ke database
|
||||
const alamatBaru = await dapatkanAlamat(pos.lat, pos.lng);
|
||||
|
||||
fetch('otak_spbu/api_update_coords.php', {
|
||||
fetch('../otak_spbu/api_update_coords.php', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ id: d.id, lat: pos.lat, lng: pos.lng, alamat: alamatBaru })
|
||||
}).then(res => res.ok ? res.json() : Promise.reject(res)).then(res => {
|
||||
dataStore.spbu[d.id].latitude = pos.lat;
|
||||
dataStore.spbu[d.id].longitude = pos.lng;
|
||||
dataStore.spbu[d.id].alamat = alamatBaru;
|
||||
triggerToastNotification("📍 Koordinat & Alamat berhasil digeser!");
|
||||
triggerToastNotification("<i class='fa-solid fa-map-pin'></i> Koordinat & Alamat berhasil digeser!");
|
||||
renderSPBU(); // Gambar ulang untuk update text di Sidebar
|
||||
}).catch(err => {
|
||||
alert("Gagal menyimpan posisi."); e.target.setLatLng([dataStore.spbu[d.id].latitude, dataStore.spbu[d.id].longitude]);
|
||||
@@ -454,15 +454,15 @@ window.eksekusiSimpanBaru = () => {
|
||||
lat: document.getElementById('spbu-lat').value,
|
||||
lng: document.getElementById('spbu-lng').value
|
||||
};
|
||||
safeFetch('../otak_spbu/api_simpan.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("✅ SPBU ditambahkan!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_simpan.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-check'></i> SPBU ditambahkan!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdate = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('spbu-nama').value, status: document.getElementById('spbu-status').value, telp: document.getElementById('spbu-telp').value };
|
||||
safeFetch('../otak_spbu/api_update.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("✅ SPBU diperbarui!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_update.php', payload).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-check'></i> SPBU diperbarui!"); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapus = (id) => {
|
||||
if(!confirm("Hapus SPBU ini?")) return;
|
||||
safeFetch('../otak_spbu/api_hapus.php', { id: id }).then(() => { tutupModalSpbu(); triggerToastNotification("🗑️ SPBU dihapus."); muatDataSPBU(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_spbu/api_hapus.php', { id: id }).then(() => { tutupModalSpbu(); triggerToastNotification("<i class='fa-solid fa-trash'></i> SPBU dihapus."); muatDataSPBU(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
// --- JALAN ---
|
||||
@@ -473,15 +473,15 @@ window.muatDataJalan = () => {
|
||||
};
|
||||
window.eksekusiSimpanJalan = () => {
|
||||
const payload = { nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value, jarak: document.getElementById('jalan-jarak').value, koordinat: document.getElementById('jalan-koordinat').value };
|
||||
safeFetch('../otak_jalan/api_simpan.php', payload).then(() => { batalGambarJalan(); triggerToastNotification("✅ Jalan ditambahkan!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_simpan.php', payload).then(() => { batalGambarJalan(); triggerToastNotification("<i class='fa-solid fa-check'></i> Jalan ditambahkan!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdateJalan = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
||||
safeFetch('../otak_jalan/api_update.php', payload).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("✅ Jalan diperbarui!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_update.php', payload).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> Jalan diperbarui!"); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapusJalan = (id) => {
|
||||
if(!confirm("Hapus jalur ini?")) return;
|
||||
safeFetch('../otak_jalan/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("🗑️ Jalan dihapus."); muatDataJalan(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_jalan/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("<i class='fa-solid fa-trash'></i> Jalan dihapus."); muatDataJalan(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
// --- TANAH ---
|
||||
@@ -492,15 +492,15 @@ window.muatDataTanah = () => {
|
||||
};
|
||||
window.eksekusiSimpanTanah = () => {
|
||||
const payload = { nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value, luas: document.getElementById('tanah-luas').value, koordinat: document.getElementById('tanah-koordinat').value };
|
||||
safeFetch('../otak_parsil/api_simpan.php', payload).then(() => { batalGambarTanah(); triggerToastNotification("✅ Tanah ditambahkan!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_simpan.php', payload).then(() => { batalGambarTanah(); triggerToastNotification("<i class='fa-solid fa-check'></i> Tanah ditambahkan!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdateTanah = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value };
|
||||
safeFetch('../otak_parsil/api_update.php', payload).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("✅ Tanah diperbarui!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_update.php', payload).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> Tanah diperbarui!"); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapusTanah = (id) => {
|
||||
if(!confirm("Hapus parsil ini?")) return;
|
||||
safeFetch('../otak_parsil/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("🗑️ Tanah dihapus."); muatDataTanah(); }).catch(err => alert(err));
|
||||
safeFetch('../otak_parsil/api_hapus.php', { id: id }).then(() => { document.getElementById('modal-tanah').style.display='none'; triggerToastNotification("<i class='fa-solid fa-trash'></i> Tanah dihapus."); muatDataTanah(); }).catch(err => alert(err));
|
||||
};
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@ setTimeout(() => {
|
||||
muatDataJalan(),
|
||||
muatDataTanah()
|
||||
]).then(() => {
|
||||
console.log("✅ Sistem WebGIS V2 Siap dan Data Tersinkronisasi Penuh.");
|
||||
console.log("<i class='fa-solid fa-check'></i> Sistem WebGIS V2 Siap dan Data Tersinkronisasi Penuh.");
|
||||
}).catch(err => {
|
||||
console.error("Kegagalan Fatal Jaringan:", err);
|
||||
});
|
||||
|
||||
+6
-4
@@ -7,18 +7,20 @@
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
|
||||
<link rel="stylesheet" href="../assets/style.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="sidebar-container">
|
||||
<a href="../" class="btn-back-home">⬅ Kembali ke Beranda</a>
|
||||
<div id="sidebar-header">
|
||||
WebGis-Pontianak
|
||||
</div>
|
||||
|
||||
<div id="filter-bar">
|
||||
<button class="filter-tool-btn" id="btn-filter-layer" title="Filter Layer" onclick="bukaModalFilterLayer()">⚙️</button>
|
||||
<button class="filter-tool-btn" id="btn-filter-layer" title="Filter Layer" onclick="bukaModalFilterLayer()"><i class='fa-solid fa-gear'></i></button>
|
||||
<span class="filter-label">Status SPBU:</span>
|
||||
<button class="filter-tool-btn" id="btn-filter-spbu" title="Filter SPBU" onclick="bukaModalFilterSPBU()">🔍</button>
|
||||
<button class="filter-tool-btn" id="btn-filter-spbu" title="Filter SPBU" onclick="bukaModalFilterSPBU()"><i class='fa-solid fa-filter'></i></button>
|
||||
</div>
|
||||
|
||||
<div id="card-container" class="card-list-area">
|
||||
@@ -29,8 +31,8 @@
|
||||
|
||||
<?php include '../components/modals.php'; ?>
|
||||
|
||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()">✓ Selesai Gambar Jalan</button>
|
||||
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()">✓ Selesai Area Tanah</button>
|
||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()"><i class='fa-solid fa-check'></i> Selesai Gambar Jalan</button>
|
||||
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()"><i class='fa-solid fa-check'></i> Selesai Area Tanah</button>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
|
||||
+19
-19
@@ -86,7 +86,7 @@ async function dapatkanAlamat(lat, lng) {
|
||||
|
||||
function triggerToastNotification(pesan) {
|
||||
const toast = document.getElementById('toast-notification');
|
||||
toast.innerText = pesan; toast.classList.add('show');
|
||||
toast.innerHTML = pesan; toast.classList.add('show');
|
||||
setTimeout(() => { toast.classList.remove('show'); }, 3000);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ window.toggleKemiskinanMode = () => {
|
||||
const wasActive = state.isKemiskinanMode; resetAllModes();
|
||||
if (!wasActive) {
|
||||
state.isKemiskinanMode = true; const btn = document.getElementById('btn-add-kemiskinan');
|
||||
btn.classList.add('active'); btn.innerHTML = `<span class="icon">📍</span> Mode Penempatan Aktif`;
|
||||
btn.classList.add('active'); btn.innerHTML = `<span class="icon"><i class='fa-solid fa-map-pin'></i></span> Mode Penempatan Aktif`;
|
||||
map.getContainer().style.cursor = 'none';
|
||||
}
|
||||
};
|
||||
@@ -198,7 +198,7 @@ const RightToolbar = L.Control.extend({
|
||||
options: { position: 'topright' },
|
||||
onAdd: function() {
|
||||
const c = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
||||
c.innerHTML = `<button class="tool-btn" id="btn-tool-marker" title="SPBU" onclick="toggleMarkerMode()">📍</button><button class="tool-btn" id="btn-tool-jalan" title="Jalan" onclick="toggleRoadMode()">🛣️</button><button class="tool-btn" id="btn-tool-tanah" title="Tanah" onclick="toggleLandMode()">🟩</button>`;
|
||||
c.innerHTML = `<button class="tool-btn" id="btn-tool-marker" title="SPBU" onclick="toggleMarkerMode()"><i class='fa-solid fa-map-pin'></i></button><button class="tool-btn" id="btn-tool-jalan" title="Jalan" onclick="toggleRoadMode()"><i class='fa-solid fa-road'></i></button><button class="tool-btn" id="btn-tool-tanah" title="Tanah" onclick="toggleLandMode()"><i class='fa-solid fa-draw-polygon'></i></button>`;
|
||||
L.DomEvent.disableClickPropagation(c); return c;
|
||||
}
|
||||
});
|
||||
@@ -382,13 +382,13 @@ function renderSPBU() {
|
||||
|
||||
marker.on('dragend', async function(e) {
|
||||
const pos = e.target.getLatLng();
|
||||
triggerToastNotification("⏳ Menganalisis alamat baru...");
|
||||
triggerToastNotification("<i class='fa-solid fa-hourglass-half'></i> Menganalisis alamat baru...");
|
||||
const alamatBaru = await dapatkanAlamat(pos.lat, pos.lng);
|
||||
fetch('../otak_spbu/api_update_coords.php', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: d.id, lat: pos.lat, lng: pos.lng, alamat: alamatBaru })
|
||||
}).then(res => res.ok ? res.json() : Promise.reject(res)).then(res => {
|
||||
dataStore.spbu[d.id].latitude = pos.lat; dataStore.spbu[d.id].longitude = pos.lng; dataStore.spbu[d.id].alamat = alamatBaru;
|
||||
triggerToastNotification("📍 Koordinat & Alamat berhasil digeser!"); renderSPBU();
|
||||
triggerToastNotification("<i class='fa-solid fa-map-pin'></i> Koordinat & Alamat berhasil digeser!"); renderSPBU();
|
||||
}).catch(err => { alert("Gagal."); e.target.setLatLng([dataStore.spbu[d.id].latitude, dataStore.spbu[d.id].longitude]); });
|
||||
});
|
||||
|
||||
@@ -771,11 +771,11 @@ window.eksekusiUpdateGaris = () => {
|
||||
|
||||
if(!confirm(`PERINGATAN: Mengubah garis kemiskinan menjadi Rp${val} akan mengkalibrasi ulang status miskin/tidak miskin seluruh penduduk di database saat ini.\n\nLanjutkan?`)) return;
|
||||
|
||||
triggerToastNotification("⏳ Mengkalibrasi ulang seluruh data penduduk...");
|
||||
triggerToastNotification("<i class='fa-solid fa-hourglass-half'></i> Mengkalibrasi ulang seluruh data penduduk...");
|
||||
|
||||
safeFetch('../otak_kemiskinan/api_update_gariskemiskinan.php', { nilai: parseInt(val) })
|
||||
.then(res => {
|
||||
triggerToastNotification("✅ " + res.pesan);
|
||||
triggerToastNotification("<i class='fa-solid fa-check'></i> " + res.pesan);
|
||||
document.getElementById('input-garis-kemiskinan').value = "";
|
||||
muatDataSemua();
|
||||
})
|
||||
@@ -786,19 +786,19 @@ window.eksekusiUpdateGaris = () => {
|
||||
window.eksekusiSimpanBaru = () => {
|
||||
const payload = { nama: document.getElementById('spbu-nama').value, status: document.getElementById('spbu-status').value, telp: document.getElementById('spbu-telp').value, alamat: document.getElementById('spbu-alamat') ? document.getElementById('spbu-alamat').value : "", lat: document.getElementById('spbu-lat').value, lng: document.getElementById('spbu-lng').value };
|
||||
safeFetch('../otak_spbu/api_simpan.php', payload)
|
||||
.then(() => { document.getElementById('modal-spbu').style.display='none'; triggerToastNotification("✅ SPBU ditambahkan!"); muatDataSemua(); })
|
||||
.then(() => { document.getElementById('modal-spbu').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> SPBU ditambahkan!"); muatDataSemua(); })
|
||||
.catch(err => alert(`Gagal menyimpan data.\nAlasan: ${err.message}\nPastikan nama dan lokasi file PHP Anda benar.`));
|
||||
};
|
||||
window.eksekusiUpdate = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('spbu-nama').value, status: document.getElementById('spbu-status').value, telp: document.getElementById('spbu-telp').value };
|
||||
safeFetch('../otak_spbu/api_update.php', payload)
|
||||
.then(() => { document.getElementById('modal-spbu').style.display='none'; triggerToastNotification("✅ SPBU diperbarui!"); muatDataSemua(); })
|
||||
.then(() => { document.getElementById('modal-spbu').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> SPBU diperbarui!"); muatDataSemua(); })
|
||||
.catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapus = (id) => {
|
||||
if(!confirm("Hapus SPBU ini?")) return;
|
||||
safeFetch('../otak_spbu/api_hapus.php', { id: id })
|
||||
.then(() => { document.getElementById('modal-spbu').style.display='none'; triggerToastNotification("🗑️ SPBU dihapus."); muatDataSemua(); })
|
||||
.then(() => { document.getElementById('modal-spbu').style.display='none'; triggerToastNotification("<i class='fa-solid fa-trash'></i> SPBU dihapus."); muatDataSemua(); })
|
||||
.catch(err => alert(err));
|
||||
};
|
||||
|
||||
@@ -806,19 +806,19 @@ window.eksekusiHapus = (id) => {
|
||||
window.eksekusiSimpanJalan = () => {
|
||||
const payload = { nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value, jarak: document.getElementById('jalan-jarak').value, koordinat: document.getElementById('jalan-koordinat').value };
|
||||
safeFetch('../otak_jalan/api_simpan.php', payload)
|
||||
.then(() => { batalGambarJalan(); triggerToastNotification("✅ Jalan ditambahkan!"); muatDataSemua(); })
|
||||
.then(() => { batalGambarJalan(); triggerToastNotification("<i class='fa-solid fa-check'></i> Jalan ditambahkan!"); muatDataSemua(); })
|
||||
.catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiUpdateJalan = (id) => {
|
||||
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
||||
safeFetch('../otak_jalan/api_update.php', payload)
|
||||
.then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("✅ Jalan diperbarui!"); muatDataSemua(); })
|
||||
.then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("<i class='fa-solid fa-check'></i> Jalan diperbarui!"); muatDataSemua(); })
|
||||
.catch(err => alert(err));
|
||||
};
|
||||
window.eksekusiHapusJalan = (id) => {
|
||||
if(!confirm("Hapus jalur ini?")) return;
|
||||
safeFetch('../otak_jalan/api_hapus.php', { id: id })
|
||||
.then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("🗑️ Jalan dihapus."); muatDataSemua(); })
|
||||
.then(() => { document.getElementById('modal-jalan').style.display='none'; triggerToastNotification("<i class='fa-solid fa-trash'></i> Jalan dihapus."); muatDataSemua(); })
|
||||
.catch(err => alert(err));
|
||||
};
|
||||
|
||||
@@ -923,7 +923,7 @@ window.updatePendudukPopup = (id, popupRef) => {
|
||||
window.eksekusiHapusPenduduk = (id) => {
|
||||
safeFetch('../otak_kemiskinan/api_hapus_penduduk.php', { id: id })
|
||||
.then(() => {
|
||||
triggerToastNotification("🗑️ Data Penduduk dihapus permanen.");
|
||||
triggerToastNotification("<i class='fa-solid fa-trash'></i> Data Penduduk dihapus permanen.");
|
||||
muatDataSemua();
|
||||
})
|
||||
.catch(err => alert(err));
|
||||
@@ -963,7 +963,7 @@ window.eksekusiSimpanLogBantuan = () => {
|
||||
safeFetch('../otak_kemiskinan/api_simpan_logbantuan.php', payload)
|
||||
.then(() => {
|
||||
document.getElementById('modal-log-bantuan').style.display = 'none';
|
||||
triggerToastNotification("✅ Log bantuan berhasil dicatat.");
|
||||
triggerToastNotification("<i class='fa-solid fa-check'></i> Log bantuan berhasil dicatat.");
|
||||
})
|
||||
.catch(err => alert("Gagal menyimpan log bantuan: " + err));
|
||||
};
|
||||
@@ -1023,7 +1023,7 @@ window.simpanIbadahPopup = (lat, lng, popupRef) => {
|
||||
.then(() => {
|
||||
map.closePopup(popupRef);
|
||||
resetAllModes();
|
||||
triggerToastNotification("✅ Rumah Ibadah berhasil ditambahkan!");
|
||||
triggerToastNotification("<i class='fa-solid fa-check'></i> Rumah Ibadah berhasil ditambahkan!");
|
||||
muatDataSemua();
|
||||
})
|
||||
.catch(err => alert("Gagal menyimpan data: " + err));
|
||||
@@ -1081,7 +1081,7 @@ window.updateIbadahPopup = (id, popupRef) => {
|
||||
.then(() => {
|
||||
map.closePopup(popupRef);
|
||||
resetAllModes();
|
||||
triggerToastNotification("✅ Data Rumah Ibadah berhasil diperbarui.");
|
||||
triggerToastNotification("<i class='fa-solid fa-check'></i> Data Rumah Ibadah berhasil diperbarui.");
|
||||
muatDataSemua();
|
||||
})
|
||||
.catch(err => alert("Gagal mengupdate data: " + err));
|
||||
@@ -1090,7 +1090,7 @@ window.updateIbadahPopup = (id, popupRef) => {
|
||||
window.eksekusiHapusIbadah = (id) => {
|
||||
safeFetch('../otak_kemiskinan/api_hapus_ibadah.php', { id: id })
|
||||
.then(() => {
|
||||
triggerToastNotification("🗑️ Rumah Ibadah dihapus permanen.");
|
||||
triggerToastNotification("<i class='fa-solid fa-trash'></i> Rumah Ibadah dihapus permanen.");
|
||||
muatDataSemua();
|
||||
})
|
||||
.catch(err => alert(err));
|
||||
@@ -1119,7 +1119,7 @@ window.muatDataSemua = () => {
|
||||
}).catch(e => console.warn("API Garis Kemiskinan Offline"))
|
||||
]).then(() => {
|
||||
renderKemiskinan();
|
||||
console.log("✅ Sistem WebGIS V3 Siap dan Data Tersinkronisasi Penuh.");
|
||||
console.log("<i class='fa-solid fa-check'></i> Sistem WebGIS V3 Siap dan Data Tersinkronisasi Penuh.");
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
+10
-8
@@ -7,10 +7,12 @@
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
|
||||
<link rel="stylesheet" href="../assets/style.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="sidebar-container">
|
||||
<a href="../" class="btn-back-home">⬅ Kembali ke Beranda</a>
|
||||
<div id="sidebar-header">WebGis-Pontianak</div>
|
||||
<!-- Tab Navigasi -->
|
||||
<div class="sidebar-tabs">
|
||||
@@ -20,7 +22,7 @@
|
||||
<!-- TAB 1: KEMISKINAN (BARU) -->
|
||||
<div id="tab-kemiskinan" class="tab-content active">
|
||||
<div class="control-panel">
|
||||
<button class="btn-gps" onclick="lokasiSaya()">📍 Arahkan ke Lokasi Saya</button>
|
||||
<button class="btn-gps" onclick="lokasiSaya()"><i class='fa-solid fa-location-crosshairs'></i> Arahkan ke Lokasi Saya</button>
|
||||
<!-- Input Garis Kemiskinan -->
|
||||
<div class="add-marker-box" style="margin-bottom: 0; padding: 10px 12px;">
|
||||
<label>Batas Garis Kemiskinan (Rp):</label>
|
||||
@@ -31,14 +33,14 @@
|
||||
</div>
|
||||
<!-- Tombol Kelola Program Pelatihan -->
|
||||
<button class="btn btn-warning" onclick="bukaModalPelatihan()" style="margin-bottom: 10px; width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px;">
|
||||
<span style="font-size: 1.2rem;">📋</span> Kelola Program Pelatihan
|
||||
<span style="font-size: 1.2rem;"><i class='fa-solid fa-clipboard-list'></i></span> Kelola Program Pelatihan
|
||||
</button>
|
||||
<!-- Tombol Tambah Marker Modern -->
|
||||
<div class="modern-action-box">
|
||||
<label>Mode Penambahan Data:</label>
|
||||
<select id="pilihan-marker-baru" class="modern-select">
|
||||
<option value="ibadah">🕌 Pusat Radius (Rumah Ibadah)</option>
|
||||
<option value="penduduk">🏠 Data Keluarga (Penduduk)</option>
|
||||
<option value="ibadah"><i class='fa-solid fa-mosque'></i> Pusat Radius (Rumah Ibadah)</option>
|
||||
<option value="penduduk"><i class='fa-solid fa-house-chimney-user'></i> Data Keluarga (Penduduk)</option>
|
||||
</select>
|
||||
<button class="btn-modern-add" id="btn-add-kemiskinan" onclick="toggleKemiskinanMode()">
|
||||
<span class="icon">+</span> Aktifkan Kursor Marker
|
||||
@@ -59,9 +61,9 @@
|
||||
<!-- TAB 2: FILTER & SPBU (LAMA) -->
|
||||
<div id="tab-filter" class="tab-content">
|
||||
<div id="filter-bar">
|
||||
<button class="filter-tool-btn" onclick="bukaModalFilterLayer()">⚙️</button>
|
||||
<button class="filter-tool-btn" onclick="bukaModalFilterLayer()"><i class='fa-solid fa-gear'></i></button>
|
||||
<span class="filter-label">Status SPBU:</span>
|
||||
<button class="filter-tool-btn" onclick="bukaModalFilterSPBU()">🔍</button>
|
||||
<button class="filter-tool-btn" onclick="bukaModalFilterSPBU()"><i class='fa-solid fa-filter'></i></button>
|
||||
</div>
|
||||
<div id="card-container" class="card-list-area"></div>
|
||||
</div>
|
||||
@@ -71,8 +73,8 @@
|
||||
|
||||
<?php include '../components/modals.php'; ?>
|
||||
|
||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()">✓ Selesai Gambar Jalan</button>
|
||||
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()">✓ Selesai Area Tanah</button>
|
||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()"><i class='fa-solid fa-check'></i> Selesai Gambar Jalan</button>
|
||||
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()"><i class='fa-solid fa-check'></i> Selesai Area Tanah</button>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
|
||||
+3
-1
@@ -737,4 +737,6 @@ input[type=range]::-webkit-slider-runnable-track {
|
||||
.auth-tab.active {
|
||||
background: var(--blue);
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
.btn-back-home { display: block; background: var(--navy); color: #A0AEC0; text-align: center; padding: 10px; text-decoration: none; font-weight: 600; font-size: 0.85rem; border-bottom: 1px solid rgba(255,255,255,0.1); transition: all 0.3s; }
|
||||
.btn-back-home:hover { background: #2a4365; color: #fff; }
|
||||
@@ -0,0 +1,285 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WebGIS Kota Pontianak - Portal Utama</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<style>
|
||||
:root {
|
||||
--primary: #2B6CB0;
|
||||
--secondary: #2C5282;
|
||||
--accent: #4FD1C5;
|
||||
--dark: #1A202C;
|
||||
--light: #F7FAFC;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(135deg, #0f2027 0%, #203a43 50%, #2c5364 100%);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--light);
|
||||
overflow-x: hidden;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/* Latar Belakang Animasi Geometris */
|
||||
.bg-pattern {
|
||||
position: fixed;
|
||||
top: 0; left: 0; width: 100vw; height: 100vh;
|
||||
background-image: radial-gradient(rgba(255, 255, 255, 0.1) 2px, transparent 2px);
|
||||
background-size: 30px 30px;
|
||||
z-index: -1;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Tekstur Kertas Elegan */
|
||||
.paper-texture {
|
||||
position: fixed;
|
||||
top: 0; left: 0; width: 100vw; height: 100vh;
|
||||
background-image: url('https://www.transparenttextures.com/patterns/paper.png');
|
||||
opacity: 0.4;
|
||||
z-index: -2;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.header-container {
|
||||
text-align: center;
|
||||
margin-bottom: 3rem;
|
||||
animation: fadeInDown 1s ease-out;
|
||||
}
|
||||
|
||||
.header-container h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(90deg, #63B3ED, #4FD1C5);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
margin-bottom: 0.5rem;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.header-container p {
|
||||
font-size: 1.2rem;
|
||||
color: #A0AEC0;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 2rem;
|
||||
width: 100%;
|
||||
max-width: 1100px;
|
||||
perspective: 1000px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
text-decoration: none;
|
||||
color: var(--light);
|
||||
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation: fadeInUp 0.8s ease-out backwards;
|
||||
}
|
||||
|
||||
/* Staggered animation */
|
||||
.card:nth-child(1) { animation-delay: 0.1s; }
|
||||
.card:nth-child(2) { animation-delay: 0.2s; }
|
||||
.card:nth-child(3) { animation-delay: 0.3s; }
|
||||
.card:nth-child(4) { animation-delay: 0.4s; }
|
||||
|
||||
.card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-10px) scale(1.02) rotateX(2deg);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
|
||||
border-color: var(--accent);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.card-number {
|
||||
font-size: 4rem;
|
||||
font-weight: 800;
|
||||
color: rgba(255, 255, 255, 0.05);
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: -10px;
|
||||
transition: color 0.4s;
|
||||
}
|
||||
|
||||
.card:hover .card-number {
|
||||
color: rgba(79, 209, 197, 0.2);
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.card p {
|
||||
color: #CBD5E0;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-btn {
|
||||
margin-top: auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(90deg, var(--primary), var(--secondary));
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.85rem;
|
||||
letter-spacing: 1px;
|
||||
transition: all 0.3s;
|
||||
border: none;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.card:hover .card-btn {
|
||||
background: linear-gradient(90deg, var(--accent), #319795);
|
||||
box-shadow: 0 4px 15px rgba(79, 209, 197, 0.4);
|
||||
transform: translateX(5px);
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 4rem;
|
||||
text-align: center;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding-top: 2rem;
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
animation: fadeIn 1s ease-out 1s backwards;
|
||||
}
|
||||
|
||||
.footer p {
|
||||
color: #A0AEC0;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.footer .highlight {
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@keyframes fadeInDown {
|
||||
from { opacity: 0; transform: translateY(-30px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from { opacity: 0; transform: translateY(30px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="paper-texture"></div>
|
||||
<div class="bg-pattern"></div>
|
||||
|
||||
<div class="header-container">
|
||||
<h1>WebGIS Pontianak</h1>
|
||||
<p>Evolusi Pemetaan Infrastruktur Spasial Terpusat. Silakan pilih iterasi arsitektur di bawah ini untuk memulai eksplorasi peta.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid-container">
|
||||
|
||||
<!-- Versi 001 -->
|
||||
<a href="001/" class="card">
|
||||
<span class="card-number">01</span>
|
||||
<div class="card-content">
|
||||
<h2><i class="fa-solid fa-map-location-dot" style="color: var(--accent);"></i> Iterasi V1</h2>
|
||||
<p>Versi pondasi awal pemetaan dasar. Menampilkan integrasi map dengan data SPBU sederhana menggunakan arsitektur lawas.</p>
|
||||
<div class="card-btn">Buka Peta</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Versi 002 -->
|
||||
<a href="002/" class="card">
|
||||
<span class="card-number">02</span>
|
||||
<div class="card-content">
|
||||
<h2><i class="fa-solid fa-eye" style="color: var(--accent);"></i> Iterasi V2</h2>
|
||||
<p>Fokus pada visualisasi murni. Menampilkan SPBU, Jaringan Jalan, dan Parsil Tanah secara keseluruhan tanpa distraksi fitur filter.</p>
|
||||
<div class="card-btn">Buka Peta</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Versi 003 -->
|
||||
<a href="003/" class="card">
|
||||
<span class="card-number">03</span>
|
||||
<div class="card-content">
|
||||
<h2><i class="fa-solid fa-layer-group" style="color: var(--accent);"></i> Iterasi V3</h2>
|
||||
<p>Memperkenalkan <i>Smart Filter</i> & <i>Layer Control</i>. Berinteraksi dengan data spasial dengan cara menyaring status secara real-time.</p>
|
||||
<div class="card-btn">Buka Peta</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Versi 004 -->
|
||||
<a href="004/" class="card">
|
||||
<span class="card-number">04</span>
|
||||
<div class="card-content">
|
||||
<h2><i class="fa-solid fa-cubes" style="color: var(--accent);"></i> Iterasi V4</h2>
|
||||
<p>Arsitektur Lanjutan. Dilengkapi dengan infrastruktur navigasi terpusat dan pemisahan logika backend API secara modular.</p>
|
||||
<div class="card-btn">Buka Peta</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>Proyek Akhir Mata Kuliah Sistem Informasi Geografis (SIG)</p>
|
||||
<p>Dikembangkan oleh <span class="highlight">Nelson Davey</span> | NIM: <span class="highlight">D1041231058</span></p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user