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() {
|
onAdd: function() {
|
||||||
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
||||||
container.innerHTML = `
|
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);
|
L.DomEvent.disableClickPropagation(container);
|
||||||
return container;
|
return container;
|
||||||
@@ -200,7 +200,7 @@ map.on('click', async function(e) {
|
|||||||
// --- UTILITAS & KOSMETIK MODAL ---
|
// --- UTILITAS & KOSMETIK MODAL ---
|
||||||
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
||||||
const toast = document.getElementById('toast-notification');
|
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);
|
setTimeout(() => { toast.classList.remove('show'); }, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,19 +355,19 @@ function renderSPBU() {
|
|||||||
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
||||||
marker.on('dragend', async function(e) {
|
marker.on('dragend', async function(e) {
|
||||||
const pos = e.target.getLatLng();
|
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
|
// Tunggu alamat baru dari satelit sebelum dikirim ke database
|
||||||
const alamatBaru = await dapatkanAlamat(pos.lat, pos.lng);
|
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' },
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ id: d.id, lat: pos.lat, lng: pos.lng, alamat: alamatBaru })
|
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 => {
|
}).then(res => res.ok ? res.json() : Promise.reject(res)).then(res => {
|
||||||
dataStore.spbu[d.id].latitude = pos.lat;
|
dataStore.spbu[d.id].latitude = pos.lat;
|
||||||
dataStore.spbu[d.id].longitude = pos.lng;
|
dataStore.spbu[d.id].longitude = pos.lng;
|
||||||
dataStore.spbu[d.id].alamat = alamatBaru;
|
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
|
renderSPBU(); // Gambar ulang untuk update text di Sidebar
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
alert("Gagal menyimpan posisi."); e.target.setLatLng([dataStore.spbu[d.id].latitude, dataStore.spbu[d.id].longitude]);
|
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,
|
lat: document.getElementById('spbu-lat').value,
|
||||||
lng: document.getElementById('spbu-lng').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) => {
|
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 };
|
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) => {
|
window.eksekusiHapus = (id) => {
|
||||||
if(!confirm("Hapus SPBU ini?")) return;
|
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 ---
|
// --- JALAN ---
|
||||||
@@ -475,15 +475,15 @@ window.muatDataJalan = () => {
|
|||||||
};
|
};
|
||||||
window.eksekusiSimpanJalan = () => {
|
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 };
|
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) => {
|
window.eksekusiUpdateJalan = (id) => {
|
||||||
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
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) => {
|
window.eksekusiHapusJalan = (id) => {
|
||||||
if(!confirm("Hapus jalur ini?")) return;
|
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 ---
|
// --- TANAH ---
|
||||||
@@ -494,15 +494,15 @@ window.muatDataTanah = () => {
|
|||||||
};
|
};
|
||||||
window.eksekusiSimpanTanah = () => {
|
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 };
|
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) => {
|
window.eksekusiUpdateTanah = (id) => {
|
||||||
const payload = { id: id, nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value };
|
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) => {
|
window.eksekusiHapusTanah = (id) => {
|
||||||
if(!confirm("Hapus parsil ini?")) return;
|
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([
|
Promise.all([
|
||||||
muatDataSPBU()
|
muatDataSPBU()
|
||||||
]).then(() => {
|
]).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 => {
|
}).catch(err => {
|
||||||
console.error("Kegagalan Fatal Jaringan:", 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="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
|
||||||
<link rel="stylesheet" href="../assets/style.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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="sidebar-container">
|
<div id="sidebar-container">
|
||||||
|
<a href="../" class="btn-back-home">⬅ Kembali ke Beranda</a>
|
||||||
<div id="sidebar-header">
|
<div id="sidebar-header">
|
||||||
WebGis-Pontianak
|
WebGis-Pontianak
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+17
-17
@@ -87,9 +87,9 @@ const RightToolbar = L.Control.extend({
|
|||||||
onAdd: function() {
|
onAdd: function() {
|
||||||
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
||||||
container.innerHTML = `
|
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>
|
||||||
<button class="tool-btn" id="btn-tool-jalan" title="Mode Jalan" onclick="toggleRoadMode()">🛣️</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()">🟩</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);
|
L.DomEvent.disableClickPropagation(container);
|
||||||
return container;
|
return container;
|
||||||
@@ -183,7 +183,7 @@ map.on('click', async function(e) {
|
|||||||
// --- UTILITAS & KOSMETIK MODAL ---
|
// --- UTILITAS & KOSMETIK MODAL ---
|
||||||
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
||||||
const toast = document.getElementById('toast-notification');
|
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);
|
setTimeout(() => { toast.classList.remove('show'); }, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,19 +337,19 @@ function renderSPBU() {
|
|||||||
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
||||||
marker.on('dragend', async function(e) {
|
marker.on('dragend', async function(e) {
|
||||||
const pos = e.target.getLatLng();
|
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
|
// Tunggu alamat baru dari satelit sebelum dikirim ke database
|
||||||
const alamatBaru = await dapatkanAlamat(pos.lat, pos.lng);
|
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' },
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ id: d.id, lat: pos.lat, lng: pos.lng, alamat: alamatBaru })
|
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 => {
|
}).then(res => res.ok ? res.json() : Promise.reject(res)).then(res => {
|
||||||
dataStore.spbu[d.id].latitude = pos.lat;
|
dataStore.spbu[d.id].latitude = pos.lat;
|
||||||
dataStore.spbu[d.id].longitude = pos.lng;
|
dataStore.spbu[d.id].longitude = pos.lng;
|
||||||
dataStore.spbu[d.id].alamat = alamatBaru;
|
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
|
renderSPBU(); // Gambar ulang untuk update text di Sidebar
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
alert("Gagal menyimpan posisi."); e.target.setLatLng([dataStore.spbu[d.id].latitude, dataStore.spbu[d.id].longitude]);
|
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,
|
lat: document.getElementById('spbu-lat').value,
|
||||||
lng: document.getElementById('spbu-lng').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) => {
|
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 };
|
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) => {
|
window.eksekusiHapus = (id) => {
|
||||||
if(!confirm("Hapus SPBU ini?")) return;
|
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 ---
|
// --- JALAN ---
|
||||||
@@ -455,15 +455,15 @@ window.muatDataJalan = () => {
|
|||||||
};
|
};
|
||||||
window.eksekusiSimpanJalan = () => {
|
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 };
|
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) => {
|
window.eksekusiUpdateJalan = (id) => {
|
||||||
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
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) => {
|
window.eksekusiHapusJalan = (id) => {
|
||||||
if(!confirm("Hapus jalur ini?")) return;
|
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 ---
|
// --- TANAH ---
|
||||||
@@ -474,15 +474,15 @@ window.muatDataTanah = () => {
|
|||||||
};
|
};
|
||||||
window.eksekusiSimpanTanah = () => {
|
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 };
|
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) => {
|
window.eksekusiUpdateTanah = (id) => {
|
||||||
const payload = { id: id, nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value };
|
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) => {
|
window.eksekusiHapusTanah = (id) => {
|
||||||
if(!confirm("Hapus parsil ini?")) return;
|
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(),
|
muatDataJalan(),
|
||||||
muatDataTanah()
|
muatDataTanah()
|
||||||
]).then(() => {
|
]).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 => {
|
}).catch(err => {
|
||||||
console.error("Kegagalan Fatal Jaringan:", 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="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="../assets/style.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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="sidebar-container">
|
<div id="sidebar-container">
|
||||||
|
<a href="../" class="btn-back-home">⬅ Kembali ke Beranda</a>
|
||||||
<div id="sidebar-header">
|
<div id="sidebar-header">
|
||||||
WebGis-Pontianak
|
WebGis-Pontianak
|
||||||
</div>
|
</div>
|
||||||
@@ -23,8 +25,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<?php include '../components/modals.php'; ?>
|
<?php include '../components/modals.php'; ?>
|
||||||
|
|
||||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()">✓ Selesai Gambar Jalan</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()">✓ Selesai Area Tanah</button>
|
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()"><i class='fa-solid fa-check'></i> Selesai Area Tanah</button>
|
||||||
|
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
|
|
||||||
|
|||||||
+17
-17
@@ -91,9 +91,9 @@ const RightToolbar = L.Control.extend({
|
|||||||
onAdd: function() {
|
onAdd: function() {
|
||||||
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
const container = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
||||||
container.innerHTML = `
|
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>
|
||||||
<button class="tool-btn" id="btn-tool-jalan" title="Mode Jalan" onclick="toggleRoadMode()">🛣️</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()">🟩</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);
|
L.DomEvent.disableClickPropagation(container);
|
||||||
return container;
|
return container;
|
||||||
@@ -198,7 +198,7 @@ map.on('click', async function(e) {
|
|||||||
// --- UTILITAS & KOSMETIK MODAL ---
|
// --- UTILITAS & KOSMETIK MODAL ---
|
||||||
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
function triggerToastNotification(pesan = "Aksi berhasil dieksekusi!") {
|
||||||
const toast = document.getElementById('toast-notification');
|
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);
|
setTimeout(() => { toast.classList.remove('show'); }, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,19 +353,19 @@ function renderSPBU() {
|
|||||||
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
// KUNCI: Reverse Geocoding saat Drag-and-Drop
|
||||||
marker.on('dragend', async function(e) {
|
marker.on('dragend', async function(e) {
|
||||||
const pos = e.target.getLatLng();
|
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
|
// Tunggu alamat baru dari satelit sebelum dikirim ke database
|
||||||
const alamatBaru = await dapatkanAlamat(pos.lat, pos.lng);
|
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' },
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ id: d.id, lat: pos.lat, lng: pos.lng, alamat: alamatBaru })
|
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 => {
|
}).then(res => res.ok ? res.json() : Promise.reject(res)).then(res => {
|
||||||
dataStore.spbu[d.id].latitude = pos.lat;
|
dataStore.spbu[d.id].latitude = pos.lat;
|
||||||
dataStore.spbu[d.id].longitude = pos.lng;
|
dataStore.spbu[d.id].longitude = pos.lng;
|
||||||
dataStore.spbu[d.id].alamat = alamatBaru;
|
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
|
renderSPBU(); // Gambar ulang untuk update text di Sidebar
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
alert("Gagal menyimpan posisi."); e.target.setLatLng([dataStore.spbu[d.id].latitude, dataStore.spbu[d.id].longitude]);
|
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,
|
lat: document.getElementById('spbu-lat').value,
|
||||||
lng: document.getElementById('spbu-lng').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) => {
|
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 };
|
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) => {
|
window.eksekusiHapus = (id) => {
|
||||||
if(!confirm("Hapus SPBU ini?")) return;
|
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 ---
|
// --- JALAN ---
|
||||||
@@ -473,15 +473,15 @@ window.muatDataJalan = () => {
|
|||||||
};
|
};
|
||||||
window.eksekusiSimpanJalan = () => {
|
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 };
|
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) => {
|
window.eksekusiUpdateJalan = (id) => {
|
||||||
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
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) => {
|
window.eksekusiHapusJalan = (id) => {
|
||||||
if(!confirm("Hapus jalur ini?")) return;
|
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 ---
|
// --- TANAH ---
|
||||||
@@ -492,15 +492,15 @@ window.muatDataTanah = () => {
|
|||||||
};
|
};
|
||||||
window.eksekusiSimpanTanah = () => {
|
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 };
|
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) => {
|
window.eksekusiUpdateTanah = (id) => {
|
||||||
const payload = { id: id, nama: document.getElementById('tanah-nama').value, status: document.getElementById('tanah-status').value };
|
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) => {
|
window.eksekusiHapusTanah = (id) => {
|
||||||
if(!confirm("Hapus parsil ini?")) return;
|
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(),
|
muatDataJalan(),
|
||||||
muatDataTanah()
|
muatDataTanah()
|
||||||
]).then(() => {
|
]).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 => {
|
}).catch(err => {
|
||||||
console.error("Kegagalan Fatal Jaringan:", 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="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
|
||||||
<link rel="stylesheet" href="../assets/style.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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="sidebar-container">
|
<div id="sidebar-container">
|
||||||
|
<a href="../" class="btn-back-home">⬅ Kembali ke Beranda</a>
|
||||||
<div id="sidebar-header">
|
<div id="sidebar-header">
|
||||||
WebGis-Pontianak
|
WebGis-Pontianak
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="filter-bar">
|
<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>
|
<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>
|
||||||
|
|
||||||
<div id="card-container" class="card-list-area">
|
<div id="card-container" class="card-list-area">
|
||||||
@@ -29,8 +31,8 @@
|
|||||||
|
|
||||||
<?php include '../components/modals.php'; ?>
|
<?php include '../components/modals.php'; ?>
|
||||||
|
|
||||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()">✓ Selesai Gambar Jalan</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()">✓ Selesai Area Tanah</button>
|
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()"><i class='fa-solid fa-check'></i> Selesai Area Tanah</button>
|
||||||
|
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
|
|
||||||
|
|||||||
+19
-19
@@ -86,7 +86,7 @@ async function dapatkanAlamat(lat, lng) {
|
|||||||
|
|
||||||
function triggerToastNotification(pesan) {
|
function triggerToastNotification(pesan) {
|
||||||
const toast = document.getElementById('toast-notification');
|
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);
|
setTimeout(() => { toast.classList.remove('show'); }, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ window.toggleKemiskinanMode = () => {
|
|||||||
const wasActive = state.isKemiskinanMode; resetAllModes();
|
const wasActive = state.isKemiskinanMode; resetAllModes();
|
||||||
if (!wasActive) {
|
if (!wasActive) {
|
||||||
state.isKemiskinanMode = true; const btn = document.getElementById('btn-add-kemiskinan');
|
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';
|
map.getContainer().style.cursor = 'none';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -198,7 +198,7 @@ const RightToolbar = L.Control.extend({
|
|||||||
options: { position: 'topright' },
|
options: { position: 'topright' },
|
||||||
onAdd: function() {
|
onAdd: function() {
|
||||||
const c = L.DomUtil.create('div', 'custom-leaflet-toolbar');
|
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;
|
L.DomEvent.disableClickPropagation(c); return c;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -382,13 +382,13 @@ function renderSPBU() {
|
|||||||
|
|
||||||
marker.on('dragend', async function(e) {
|
marker.on('dragend', async function(e) {
|
||||||
const pos = e.target.getLatLng();
|
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);
|
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 })
|
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 => {
|
}).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;
|
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]); });
|
}).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;
|
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) })
|
safeFetch('../otak_kemiskinan/api_update_gariskemiskinan.php', { nilai: parseInt(val) })
|
||||||
.then(res => {
|
.then(res => {
|
||||||
triggerToastNotification("✅ " + res.pesan);
|
triggerToastNotification("<i class='fa-solid fa-check'></i> " + res.pesan);
|
||||||
document.getElementById('input-garis-kemiskinan').value = "";
|
document.getElementById('input-garis-kemiskinan').value = "";
|
||||||
muatDataSemua();
|
muatDataSemua();
|
||||||
})
|
})
|
||||||
@@ -786,19 +786,19 @@ window.eksekusiUpdateGaris = () => {
|
|||||||
window.eksekusiSimpanBaru = () => {
|
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 };
|
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)
|
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.`));
|
.catch(err => alert(`Gagal menyimpan data.\nAlasan: ${err.message}\nPastikan nama dan lokasi file PHP Anda benar.`));
|
||||||
};
|
};
|
||||||
window.eksekusiUpdate = (id) => {
|
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 };
|
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)
|
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));
|
.catch(err => alert(err));
|
||||||
};
|
};
|
||||||
window.eksekusiHapus = (id) => {
|
window.eksekusiHapus = (id) => {
|
||||||
if(!confirm("Hapus SPBU ini?")) return;
|
if(!confirm("Hapus SPBU ini?")) return;
|
||||||
safeFetch('../otak_spbu/api_hapus.php', { id: id })
|
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));
|
.catch(err => alert(err));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -806,19 +806,19 @@ window.eksekusiHapus = (id) => {
|
|||||||
window.eksekusiSimpanJalan = () => {
|
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 };
|
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)
|
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));
|
.catch(err => alert(err));
|
||||||
};
|
};
|
||||||
window.eksekusiUpdateJalan = (id) => {
|
window.eksekusiUpdateJalan = (id) => {
|
||||||
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
const payload = { id: id, nama: document.getElementById('jalan-nama').value, status: document.getElementById('jalan-status').value };
|
||||||
safeFetch('../otak_jalan/api_update.php', payload)
|
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));
|
.catch(err => alert(err));
|
||||||
};
|
};
|
||||||
window.eksekusiHapusJalan = (id) => {
|
window.eksekusiHapusJalan = (id) => {
|
||||||
if(!confirm("Hapus jalur ini?")) return;
|
if(!confirm("Hapus jalur ini?")) return;
|
||||||
safeFetch('../otak_jalan/api_hapus.php', { id: id })
|
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));
|
.catch(err => alert(err));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -923,7 +923,7 @@ window.updatePendudukPopup = (id, popupRef) => {
|
|||||||
window.eksekusiHapusPenduduk = (id) => {
|
window.eksekusiHapusPenduduk = (id) => {
|
||||||
safeFetch('../otak_kemiskinan/api_hapus_penduduk.php', { id: id })
|
safeFetch('../otak_kemiskinan/api_hapus_penduduk.php', { id: id })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
triggerToastNotification("🗑️ Data Penduduk dihapus permanen.");
|
triggerToastNotification("<i class='fa-solid fa-trash'></i> Data Penduduk dihapus permanen.");
|
||||||
muatDataSemua();
|
muatDataSemua();
|
||||||
})
|
})
|
||||||
.catch(err => alert(err));
|
.catch(err => alert(err));
|
||||||
@@ -963,7 +963,7 @@ window.eksekusiSimpanLogBantuan = () => {
|
|||||||
safeFetch('../otak_kemiskinan/api_simpan_logbantuan.php', payload)
|
safeFetch('../otak_kemiskinan/api_simpan_logbantuan.php', payload)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
document.getElementById('modal-log-bantuan').style.display = 'none';
|
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));
|
.catch(err => alert("Gagal menyimpan log bantuan: " + err));
|
||||||
};
|
};
|
||||||
@@ -1023,7 +1023,7 @@ window.simpanIbadahPopup = (lat, lng, popupRef) => {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
map.closePopup(popupRef);
|
map.closePopup(popupRef);
|
||||||
resetAllModes();
|
resetAllModes();
|
||||||
triggerToastNotification("✅ Rumah Ibadah berhasil ditambahkan!");
|
triggerToastNotification("<i class='fa-solid fa-check'></i> Rumah Ibadah berhasil ditambahkan!");
|
||||||
muatDataSemua();
|
muatDataSemua();
|
||||||
})
|
})
|
||||||
.catch(err => alert("Gagal menyimpan data: " + err));
|
.catch(err => alert("Gagal menyimpan data: " + err));
|
||||||
@@ -1081,7 +1081,7 @@ window.updateIbadahPopup = (id, popupRef) => {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
map.closePopup(popupRef);
|
map.closePopup(popupRef);
|
||||||
resetAllModes();
|
resetAllModes();
|
||||||
triggerToastNotification("✅ Data Rumah Ibadah berhasil diperbarui.");
|
triggerToastNotification("<i class='fa-solid fa-check'></i> Data Rumah Ibadah berhasil diperbarui.");
|
||||||
muatDataSemua();
|
muatDataSemua();
|
||||||
})
|
})
|
||||||
.catch(err => alert("Gagal mengupdate data: " + err));
|
.catch(err => alert("Gagal mengupdate data: " + err));
|
||||||
@@ -1090,7 +1090,7 @@ window.updateIbadahPopup = (id, popupRef) => {
|
|||||||
window.eksekusiHapusIbadah = (id) => {
|
window.eksekusiHapusIbadah = (id) => {
|
||||||
safeFetch('../otak_kemiskinan/api_hapus_ibadah.php', { id: id })
|
safeFetch('../otak_kemiskinan/api_hapus_ibadah.php', { id: id })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
triggerToastNotification("🗑️ Rumah Ibadah dihapus permanen.");
|
triggerToastNotification("<i class='fa-solid fa-trash'></i> Rumah Ibadah dihapus permanen.");
|
||||||
muatDataSemua();
|
muatDataSemua();
|
||||||
})
|
})
|
||||||
.catch(err => alert(err));
|
.catch(err => alert(err));
|
||||||
@@ -1119,7 +1119,7 @@ window.muatDataSemua = () => {
|
|||||||
}).catch(e => console.warn("API Garis Kemiskinan Offline"))
|
}).catch(e => console.warn("API Garis Kemiskinan Offline"))
|
||||||
]).then(() => {
|
]).then(() => {
|
||||||
renderKemiskinan();
|
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="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
|
||||||
<link rel="stylesheet" href="../assets/style.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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="sidebar-container">
|
<div id="sidebar-container">
|
||||||
|
<a href="../" class="btn-back-home">⬅ Kembali ke Beranda</a>
|
||||||
<div id="sidebar-header">WebGis-Pontianak</div>
|
<div id="sidebar-header">WebGis-Pontianak</div>
|
||||||
<!-- Tab Navigasi -->
|
<!-- Tab Navigasi -->
|
||||||
<div class="sidebar-tabs">
|
<div class="sidebar-tabs">
|
||||||
@@ -20,7 +22,7 @@
|
|||||||
<!-- TAB 1: KEMISKINAN (BARU) -->
|
<!-- TAB 1: KEMISKINAN (BARU) -->
|
||||||
<div id="tab-kemiskinan" class="tab-content active">
|
<div id="tab-kemiskinan" class="tab-content active">
|
||||||
<div class="control-panel">
|
<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 -->
|
<!-- Input Garis Kemiskinan -->
|
||||||
<div class="add-marker-box" style="margin-bottom: 0; padding: 10px 12px;">
|
<div class="add-marker-box" style="margin-bottom: 0; padding: 10px 12px;">
|
||||||
<label>Batas Garis Kemiskinan (Rp):</label>
|
<label>Batas Garis Kemiskinan (Rp):</label>
|
||||||
@@ -31,14 +33,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Tombol Kelola Program Pelatihan -->
|
<!-- 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;">
|
<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>
|
</button>
|
||||||
<!-- Tombol Tambah Marker Modern -->
|
<!-- Tombol Tambah Marker Modern -->
|
||||||
<div class="modern-action-box">
|
<div class="modern-action-box">
|
||||||
<label>Mode Penambahan Data:</label>
|
<label>Mode Penambahan Data:</label>
|
||||||
<select id="pilihan-marker-baru" class="modern-select">
|
<select id="pilihan-marker-baru" class="modern-select">
|
||||||
<option value="ibadah">🕌 Pusat Radius (Rumah Ibadah)</option>
|
<option value="ibadah"><i class='fa-solid fa-mosque'></i> Pusat Radius (Rumah Ibadah)</option>
|
||||||
<option value="penduduk">🏠 Data Keluarga (Penduduk)</option>
|
<option value="penduduk"><i class='fa-solid fa-house-chimney-user'></i> Data Keluarga (Penduduk)</option>
|
||||||
</select>
|
</select>
|
||||||
<button class="btn-modern-add" id="btn-add-kemiskinan" onclick="toggleKemiskinanMode()">
|
<button class="btn-modern-add" id="btn-add-kemiskinan" onclick="toggleKemiskinanMode()">
|
||||||
<span class="icon">+</span> Aktifkan Kursor Marker
|
<span class="icon">+</span> Aktifkan Kursor Marker
|
||||||
@@ -59,9 +61,9 @@
|
|||||||
<!-- TAB 2: FILTER & SPBU (LAMA) -->
|
<!-- TAB 2: FILTER & SPBU (LAMA) -->
|
||||||
<div id="tab-filter" class="tab-content">
|
<div id="tab-filter" class="tab-content">
|
||||||
<div id="filter-bar">
|
<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>
|
<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>
|
||||||
<div id="card-container" class="card-list-area"></div>
|
<div id="card-container" class="card-list-area"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,8 +73,8 @@
|
|||||||
|
|
||||||
<?php include '../components/modals.php'; ?>
|
<?php include '../components/modals.php'; ?>
|
||||||
|
|
||||||
<button id="btn-selesai-jalan" onclick="selesaiGambarJalan()">✓ Selesai Gambar Jalan</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()">✓ Selesai Area Tanah</button>
|
<button id="btn-selesai-tanah" onclick="selesaiGambarTanah()"><i class='fa-solid fa-check'></i> Selesai Area Tanah</button>
|
||||||
|
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
|
|
||||||
|
|||||||
@@ -738,3 +738,5 @@ input[type=range]::-webkit-slider-runnable-track {
|
|||||||
background: var(--blue);
|
background: var(--blue);
|
||||||
color: var(--white);
|
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