tambah fitur add tempat ibadah
This commit is contained in:
+204
-7
@@ -157,6 +157,25 @@
|
||||
z-index: 2000;
|
||||
}
|
||||
.toast.show { opacity: 1; transform: translateY(0); }
|
||||
.ibadah-map { height: 300px; position: relative; border-radius: var(--radius); overflow: hidden; border: 1px solid #dbe2ea; background: #eef2f7; }
|
||||
.coord-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
|
||||
.ibadah-badge-gereja-katolik { background: #ede9fe; color: #4c1d95; }
|
||||
.ibadah-badge-gpib { background: #dbeafe; color: #1e3a8a; }
|
||||
.ibadah-badge-gki { background: #cffafe; color: #164e63; }
|
||||
.ibadah-badge-hkbp { background: #dcfce7; color: #14532d; }
|
||||
.ibadah-badge-pentakosta { background: #ffedd5; color: #7c2d12; }
|
||||
.ibadah-pin {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 999px;
|
||||
background: #7c3aed;
|
||||
color: #fff;
|
||||
border: 3px solid #fff;
|
||||
box-shadow: 0 10px 22px rgba(15, 23, 42, .25);
|
||||
font-size: 16px;
|
||||
}
|
||||
@media (max-width: 980px) {
|
||||
.shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: relative; height: auto; }
|
||||
@@ -183,6 +202,7 @@
|
||||
<button data-section="keluarga">Data Keluarga</button>
|
||||
<button data-section="bantuan">Data Bantuan</button>
|
||||
<button data-section="kriteria">Kriteria SAW</button>
|
||||
<button data-section="ibadah">⛪ Tempat Ibadah</button>
|
||||
<button data-section="peta">Preview Peta</button>
|
||||
<a href="/poverty-map.html">Buka Peta Poverty</a>
|
||||
<a href="/admin.html">Admin SPBU</a>
|
||||
@@ -312,6 +332,46 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="ibadah">
|
||||
<article class="card">
|
||||
<div class="card-head"><h3>Form Tempat Ibadah</h3><button class="btn secondary small" id="resetIbadah">Reset</button></div>
|
||||
<div class="card-body">
|
||||
<form id="ibadahForm">
|
||||
<input type="hidden" id="id_ibadah" />
|
||||
<div class="form-grid">
|
||||
<label>Nama<input id="ibadah_nama" required /></label>
|
||||
<label>Jenis<select id="ibadah_jenis" required></select></label>
|
||||
<label>Alamat<input id="ibadah_alamat" required /></label>
|
||||
<label>Kelurahan<input id="ibadah_kelurahan" required /></label>
|
||||
<div class="full">
|
||||
<label>Koordinat dari Peta</label>
|
||||
<div id="ibadahMap" class="ibadah-map"></div>
|
||||
</div>
|
||||
<label>Lat<input id="ibadah_lat" type="number" step="any" readonly required /></label>
|
||||
<label>Lng<input id="ibadah_lng" type="number" step="any" readonly required /></label>
|
||||
<div class="full coord-actions">
|
||||
<button class="btn secondary small" id="toggleManualIbadah" type="button">✏️ Edit Manual</button>
|
||||
<button class="btn danger small" id="clearIbadahPin" type="button">× Hapus Pin</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="btn" id="ibadahSubmit" type="submit">Simpan Tempat Ibadah</button>
|
||||
<button class="btn secondary" id="cancelIbadahEdit" type="button" style="display:none">Batal Edit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</article>
|
||||
<article class="card">
|
||||
<div class="card-head"><h3>Daftar Tempat Ibadah</h3><span id="ibadahCount">0 data</span></div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead><tr><th>#</th><th>Nama</th><th>Jenis</th><th>Alamat</th><th>Kelurahan</th><th>Koordinat</th><th>Aksi</th></tr></thead>
|
||||
<tbody id="ibadahBody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="section" id="peta">
|
||||
<article class="card">
|
||||
<div class="card-head"><h3>Preview Peta Keluarga Prioritas</h3><span>Klik peta untuk mengisi koordinat form keluarga.</span></div>
|
||||
@@ -324,8 +384,11 @@
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script>
|
||||
const API = "/api/poverty";
|
||||
const state = { keluarga: [], bantuan: [], riwayat: [], kriteria: [], dashboard: null, analytics: null };
|
||||
const state = { keluarga: [], bantuan: [], riwayat: [], kriteria: [], ibadah: [], dashboard: null, analytics: null };
|
||||
const today = new Date().toISOString().slice(0, 10);
|
||||
const DEFAULT_CENTER = [-0.0263, 109.3425];
|
||||
const IBADAH_TYPES = ["Gereja Katolik", "GPIB", "GKI", "HKBP", "Pentakosta"];
|
||||
const mapsInitialized = { ibadah: false };
|
||||
const labels = {
|
||||
pekerjaan: { pengangguran: "Pengangguran", buruh_harian: "Buruh Harian", petani: "Petani", nelayan: "Nelayan", pedagang_kecil: "Pedagang Kecil", karyawan: "Karyawan", wiraswasta: "Wiraswasta", pns: "PNS", pensiunan: "Pensiunan", lainnya: "Lainnya" },
|
||||
pendidikan: { tidak_sekolah: "Tidak Sekolah", sd: "SD", smp: "SMP", sma: "SMA", diploma: "Diploma", sarjana: "Sarjana" },
|
||||
@@ -338,6 +401,7 @@
|
||||
const rp = (value) => new Intl.NumberFormat("id-ID", { style: "currency", currency: "IDR", maximumFractionDigits: 0 }).format(Number(value || 0));
|
||||
const fmt = (value) => value ? String(value).slice(0, 10) : "";
|
||||
const badgeClass = (kategori) => kategori === "Sangat Membutuhkan" ? "sangat" : kategori === "Membutuhkan" ? "butuh" : kategori === "Rentan" ? "rentan" : "mampu";
|
||||
const ibadahBadgeClass = (jenis) => `ibadah-badge-${String(jenis || "").toLowerCase().replace(/\s+/g, "-")}`;
|
||||
|
||||
async function api(path, options = {}) {
|
||||
const response = await fetch(`${API}${path}`, { headers: { "Content-Type": "application/json", ...(options.headers || {}) }, ...options });
|
||||
@@ -423,6 +487,87 @@
|
||||
`).join("") || `<tr><td colspan="5">Belum ada data kriteria.</td></tr>`;
|
||||
}
|
||||
|
||||
function renderIbadah() {
|
||||
el("ibadahCount").textContent = `${state.ibadah.length} data`;
|
||||
el("ibadahBody").innerHTML = state.ibadah.map((item, index) => `
|
||||
<tr>
|
||||
<td>${index + 1}</td>
|
||||
<td><strong>${esc(item.nama)}</strong></td>
|
||||
<td><span class="badge ${ibadahBadgeClass(item.jenis)}">${esc(item.jenis)}</span></td>
|
||||
<td>${esc(item.alamat)}</td>
|
||||
<td>${esc(item.kelurahan)}</td>
|
||||
<td>${Number(item.lat).toFixed(6)}, ${Number(item.lng).toFixed(6)}</td>
|
||||
<td><button class="btn secondary small" onclick="editIbadah(${item.id})">Edit</button> <button class="btn danger small" onclick="hapus('ibadah', ${item.id})">Hapus</button></td>
|
||||
</tr>
|
||||
`).join("") || `<tr><td colspan="7">Belum ada data tempat ibadah.</td></tr>`;
|
||||
}
|
||||
|
||||
let ibadahMap, ibadahMarker, ibadahManual = false;
|
||||
const ibadahIcon = L.divIcon({
|
||||
className: "",
|
||||
html: `<div class="ibadah-pin">⛪</div>`,
|
||||
iconSize: [32, 32],
|
||||
iconAnchor: [16, 32],
|
||||
});
|
||||
|
||||
function ensureIbadahMap() {
|
||||
if (mapsInitialized.ibadah) return;
|
||||
mapsInitialized.ibadah = true;
|
||||
ibadahMap = L.map("ibadahMap").setView(DEFAULT_CENTER, 12);
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 19, attribution: "© OpenStreetMap" }).addTo(ibadahMap);
|
||||
ibadahMap.on("click", (event) => setIbadahPin(event.latlng.lat, event.latlng.lng));
|
||||
setTimeout(() => ibadahMap.invalidateSize(), 80);
|
||||
}
|
||||
|
||||
function setIbadahFields(lat, lng) {
|
||||
el("ibadah_lat").value = Number(lat).toFixed(7);
|
||||
el("ibadah_lng").value = Number(lng).toFixed(7);
|
||||
}
|
||||
|
||||
function setIbadahPin(lat, lng, zoom = false) {
|
||||
const point = [Number(lat), Number(lng)];
|
||||
if (!Number.isFinite(point[0]) || !Number.isFinite(point[1])) return;
|
||||
ensureIbadahMap();
|
||||
setIbadahFields(point[0], point[1]);
|
||||
if (!ibadahMarker) {
|
||||
ibadahMarker = L.marker(point, { draggable: true, icon: ibadahIcon }).addTo(ibadahMap);
|
||||
ibadahMarker.on("dragend", () => {
|
||||
const latlng = ibadahMarker.getLatLng();
|
||||
setIbadahFields(latlng.lat, latlng.lng);
|
||||
});
|
||||
} else {
|
||||
ibadahMarker.setLatLng(point);
|
||||
}
|
||||
if (zoom) ibadahMap.setView(point, 15);
|
||||
}
|
||||
|
||||
function clearIbadahPin() {
|
||||
if (ibadahMarker) {
|
||||
ibadahMarker.remove();
|
||||
ibadahMarker = null;
|
||||
}
|
||||
el("ibadah_lat").value = "";
|
||||
el("ibadah_lng").value = "";
|
||||
}
|
||||
|
||||
function syncIbadahManualPin() {
|
||||
const lat = Number(el("ibadah_lat").value);
|
||||
const lng = Number(el("ibadah_lng").value);
|
||||
if (!Number.isFinite(lat) || !Number.isFinite(lng)) return;
|
||||
setIbadahPin(lat, lng, true);
|
||||
}
|
||||
|
||||
function ibadahPayload() {
|
||||
return {
|
||||
nama: el("ibadah_nama").value.trim(),
|
||||
jenis: el("ibadah_jenis").value,
|
||||
alamat: el("ibadah_alamat").value.trim(),
|
||||
kelurahan: el("ibadah_kelurahan").value.trim(),
|
||||
lat: Number(el("ibadah_lat").value),
|
||||
lng: Number(el("ibadah_lng").value),
|
||||
};
|
||||
}
|
||||
|
||||
let map, layer;
|
||||
function ensureMap() {
|
||||
if (map) return;
|
||||
@@ -449,11 +594,11 @@
|
||||
}
|
||||
|
||||
async function loadAll() {
|
||||
const [dashboard, analytics, keluarga, bantuan, riwayat, kriteria] = await Promise.all([
|
||||
api("/dashboard"), api("/analytics"), api("/keluarga"), api("/bantuan"), api("/riwayat-bantuan"), api("/kriteria")
|
||||
const [dashboard, analytics, keluarga, bantuan, riwayat, kriteria, ibadah] = await Promise.all([
|
||||
api("/dashboard"), api("/analytics"), api("/keluarga"), api("/bantuan"), api("/riwayat-bantuan"), api("/kriteria"), api("/ibadah")
|
||||
]);
|
||||
Object.assign(state, { dashboard, analytics, keluarga, bantuan, riwayat, kriteria });
|
||||
renderDashboard(); renderKeluarga(); renderBantuan(); renderKriteria();
|
||||
Object.assign(state, { dashboard, analytics, keluarga, bantuan, riwayat, kriteria, ibadah });
|
||||
renderDashboard(); renderKeluarga(); renderBantuan(); renderKriteria(); renderIbadah();
|
||||
}
|
||||
|
||||
function familyPayload() {
|
||||
@@ -486,6 +631,18 @@
|
||||
function resetBantuan() { el("bantuanForm").reset(); el("id_bantuan").value = ""; el("tanggal_bantuan").value = today; }
|
||||
function resetRiwayat() { el("riwayatForm").reset(); el("id_riwayat").value = ""; el("tanggal_diterima").value = today; }
|
||||
function resetKriteria() { el("kriteriaForm").reset(); el("id_kriteria").value = ""; }
|
||||
function resetIbadah() {
|
||||
el("ibadahForm").reset();
|
||||
el("id_ibadah").value = "";
|
||||
el("ibadah_lat").readOnly = true;
|
||||
el("ibadah_lng").readOnly = true;
|
||||
ibadahManual = false;
|
||||
el("toggleManualIbadah").textContent = "✏️ Edit Manual";
|
||||
el("ibadahSubmit").textContent = "Simpan Tempat Ibadah";
|
||||
el("cancelIbadahEdit").style.display = "none";
|
||||
clearIbadahPin();
|
||||
if (ibadahMap) ibadahMap.setView(DEFAULT_CENTER, 12);
|
||||
}
|
||||
|
||||
window.editKeluarga = (id) => {
|
||||
const item = state.keluarga.find((row) => row.id_keluarga === id);
|
||||
@@ -509,6 +666,22 @@
|
||||
if (!item) return;
|
||||
el("id_kriteria").value = id; el("kode").value = item.kode; el("nama_kriteria").value = item.nama_kriteria; el("bobot").value = item.bobot; el("atribut").value = item.atribut;
|
||||
};
|
||||
window.editIbadah = (id) => {
|
||||
const item = state.ibadah.find((row) => row.id === id);
|
||||
if (!item) return;
|
||||
document.querySelector('[data-section="ibadah"]').click();
|
||||
el("id_ibadah").value = id;
|
||||
el("ibadah_nama").value = item.nama;
|
||||
el("ibadah_jenis").value = item.jenis;
|
||||
el("ibadah_alamat").value = item.alamat;
|
||||
el("ibadah_kelurahan").value = item.kelurahan;
|
||||
el("ibadahSubmit").textContent = "Update Tempat Ibadah";
|
||||
el("cancelIbadahEdit").style.display = "inline-flex";
|
||||
setTimeout(() => {
|
||||
setIbadahPin(item.lat, item.lng, true);
|
||||
el("ibadah").scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
}, 100);
|
||||
};
|
||||
window.hapus = async (resource, id) => {
|
||||
if (!confirm("Hapus/nonaktifkan data ini?")) return;
|
||||
await api(`/${resource}/${id}`, { method: "DELETE" });
|
||||
@@ -522,7 +695,13 @@
|
||||
document.querySelectorAll(".section").forEach((item) => item.classList.remove("active"));
|
||||
button.classList.add("active");
|
||||
el(button.dataset.section).classList.add("active");
|
||||
setTimeout(() => map?.invalidateSize(), 80);
|
||||
setTimeout(() => {
|
||||
map?.invalidateSize();
|
||||
if (button.dataset.section === "ibadah") {
|
||||
ensureIbadahMap();
|
||||
ibadahMap?.invalidateSize();
|
||||
}
|
||||
}, 80);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -553,11 +732,28 @@
|
||||
await api(id ? `/kriteria/${id}` : "/kriteria", { method: id ? "PUT" : "POST", body: JSON.stringify(payload) });
|
||||
resetKriteria(); toast("Kriteria tersimpan."); await loadAll();
|
||||
});
|
||||
document.getElementById("ibadahForm").addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
const id = el("id_ibadah").value;
|
||||
await api(id ? `/ibadah/${id}` : "/ibadah", { method: id ? "PUT" : "POST", body: JSON.stringify(ibadahPayload()) });
|
||||
resetIbadah(); toast("Tempat ibadah tersimpan."); await loadAll();
|
||||
});
|
||||
|
||||
el("resetKeluarga").addEventListener("click", resetKeluarga);
|
||||
el("resetBantuan").addEventListener("click", resetBantuan);
|
||||
el("resetRiwayat").addEventListener("click", resetRiwayat);
|
||||
el("resetKriteria").addEventListener("click", resetKriteria);
|
||||
el("resetIbadah").addEventListener("click", resetIbadah);
|
||||
el("cancelIbadahEdit").addEventListener("click", resetIbadah);
|
||||
el("clearIbadahPin").addEventListener("click", clearIbadahPin);
|
||||
el("toggleManualIbadah").addEventListener("click", () => {
|
||||
ibadahManual = !ibadahManual;
|
||||
el("ibadah_lat").readOnly = !ibadahManual;
|
||||
el("ibadah_lng").readOnly = !ibadahManual;
|
||||
el("toggleManualIbadah").textContent = ibadahManual ? "🔒 Kunci Koordinat" : "✏️ Edit Manual";
|
||||
});
|
||||
el("ibadah_lat").addEventListener("blur", syncIbadahManualPin);
|
||||
el("ibadah_lng").addEventListener("blur", syncIbadahManualPin);
|
||||
el("familySearch").addEventListener("input", renderKeluarga);
|
||||
el("recalculateBtn").addEventListener("click", async () => { await api("/recalculate", { method: "POST" }); toast("SAW berhasil dihitung ulang."); await loadAll(); });
|
||||
|
||||
@@ -565,7 +761,8 @@
|
||||
fillOptions("pendidikan", labels.pendidikan);
|
||||
fillOptions("kondisi_rumah", labels.kondisi_rumah);
|
||||
fillOptions("kondisi_kesehatan", labels.kondisi_kesehatan);
|
||||
resetKeluarga(); resetBantuan(); resetRiwayat(); resetKriteria();
|
||||
el("ibadah_jenis").innerHTML = IBADAH_TYPES.map((jenis) => `<option value="${jenis}">${jenis}</option>`).join("");
|
||||
resetKeluarga(); resetBantuan(); resetRiwayat(); resetKriteria(); resetIbadah();
|
||||
loadAll().catch((error) => toast(error.message));
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -170,6 +170,19 @@
|
||||
z-index: 2000;
|
||||
}
|
||||
.toast.show { opacity: 1; transform: translateY(0); }
|
||||
.ibadah-legend { display: none; }
|
||||
.ibadah-legend.active { display: block; }
|
||||
.ibadah-map-marker {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 999px;
|
||||
color: white;
|
||||
border: 3px solid white;
|
||||
box-shadow: 0 10px 24px rgba(15, 23, 42, .28);
|
||||
font-size: 15px;
|
||||
}
|
||||
@media (max-width: 880px) {
|
||||
body { overflow: hidden; }
|
||||
.app { grid-template-columns: 1fr; }
|
||||
@@ -222,6 +235,7 @@
|
||||
<input id="searchInput" placeholder="Nama, alamat, atau wilayah" />
|
||||
</label>
|
||||
<label class="switch"><span>Heatmap persebaran</span><input id="heatToggle" type="checkbox" checked /></label>
|
||||
<label class="switch"><span>⛪ Tempat Ibadah</span><input id="ibadahToggle" type="checkbox" /></label>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
@@ -234,6 +248,17 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel ibadah-legend" id="ibadahLegendPanel">
|
||||
<h2>Legenda Tempat Ibadah</h2>
|
||||
<div class="legend">
|
||||
<span><i class="dot" style="background:#7c3aed"></i>Gereja Katolik</span>
|
||||
<span><i class="dot" style="background:#2563eb"></i>GPIB</span>
|
||||
<span><i class="dot" style="background:#0891b2"></i>GKI</span>
|
||||
<span><i class="dot" style="background:#16a34a"></i>HKBP</span>
|
||||
<span><i class="dot" style="background:#ea580c"></i>Pentakosta</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<h2>Statistik Wilayah</h2>
|
||||
<div id="areaStats"></div>
|
||||
@@ -262,11 +287,12 @@
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script>
|
||||
const API = "/api/poverty";
|
||||
const state = { rows: [], dashboard: null, markers: new Map() };
|
||||
const state = { rows: [], dashboard: null, markers: new Map(), ibadah: [], ibadahLoaded: false };
|
||||
const map = L.map("map", { zoomControl: true }).setView([-0.0263, 109.3425], 12);
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 19, attribution: "© OpenStreetMap" }).addTo(map);
|
||||
const markerLayer = L.layerGroup().addTo(map);
|
||||
const heatLayer = L.layerGroup().addTo(map);
|
||||
const ibadahLayer = L.layerGroup();
|
||||
|
||||
const el = (id) => document.getElementById(id);
|
||||
const esc = (value) => String(value ?? "").replace(/[&<>"']/g, (char) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[char]));
|
||||
@@ -274,6 +300,13 @@
|
||||
const score = (value) => Number(value || 0).toFixed(3);
|
||||
const badgeClass = (kategori) => kategori === "Sangat Membutuhkan" ? "sangat" : kategori === "Membutuhkan" ? "butuh" : kategori === "Rentan" ? "rentan" : "mampu";
|
||||
const color = (kategori) => kategori === "Sangat Membutuhkan" ? "#dc2626" : kategori === "Membutuhkan" ? "#f97316" : kategori === "Rentan" ? "#facc15" : "#22c55e";
|
||||
const ibadahColors = {
|
||||
"Gereja Katolik": "#7c3aed",
|
||||
GPIB: "#2563eb",
|
||||
GKI: "#0891b2",
|
||||
HKBP: "#16a34a",
|
||||
Pentakosta: "#ea580c",
|
||||
};
|
||||
|
||||
function toast(message) {
|
||||
el("toast").textContent = message;
|
||||
@@ -350,6 +383,47 @@
|
||||
`;
|
||||
}
|
||||
|
||||
function ibadahIcon(jenis) {
|
||||
const markerColor = ibadahColors[jenis] || "#64748b";
|
||||
return L.divIcon({
|
||||
className: "",
|
||||
html: `<div class="ibadah-map-marker" style="background:${markerColor}">⛪</div>`,
|
||||
iconSize: [30, 30],
|
||||
iconAnchor: [15, 30],
|
||||
popupAnchor: [0, -28],
|
||||
});
|
||||
}
|
||||
|
||||
function ibadahPopupHtml(item) {
|
||||
const markerColor = ibadahColors[item.jenis] || "#64748b";
|
||||
return `
|
||||
<div class="popup">
|
||||
<h3>${esc(item.nama)}</h3>
|
||||
<span class="badge" style="background:${markerColor}22;color:${markerColor};border:1px solid ${markerColor}44">${esc(item.jenis)}</span>
|
||||
<p style="margin-top:10px">${esc(item.alamat)}<br>${esc(item.kelurahan)}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderIbadahMarkers() {
|
||||
ibadahLayer.clearLayers();
|
||||
state.ibadah.forEach((item) => {
|
||||
const latlng = [Number(item.lat), Number(item.lng)];
|
||||
if (!Number.isFinite(latlng[0]) || !Number.isFinite(latlng[1])) return;
|
||||
L.marker(latlng, { icon: ibadahIcon(item.jenis) })
|
||||
.bindPopup(ibadahPopupHtml(item))
|
||||
.addTo(ibadahLayer);
|
||||
});
|
||||
}
|
||||
|
||||
async function loadIbadahLayer(force = false) {
|
||||
if (state.ibadahLoaded && !force) return;
|
||||
const payload = await fetchJson("/ibadah");
|
||||
state.ibadah = payload.data || [];
|
||||
state.ibadahLoaded = true;
|
||||
renderIbadahMarkers();
|
||||
}
|
||||
|
||||
function renderMarkers() {
|
||||
markerLayer.clearLayers();
|
||||
heatLayer.clearLayers();
|
||||
@@ -408,6 +482,22 @@
|
||||
|
||||
let debounce;
|
||||
["categoryFilter", "heatToggle"].forEach((id) => el(id).addEventListener("change", () => loadData().catch((error) => toast(error.message))));
|
||||
el("ibadahToggle").addEventListener("change", async () => {
|
||||
try {
|
||||
if (el("ibadahToggle").checked) {
|
||||
await loadIbadahLayer(true);
|
||||
ibadahLayer.addTo(map);
|
||||
el("ibadahLegendPanel").classList.add("active");
|
||||
} else {
|
||||
map.removeLayer(ibadahLayer);
|
||||
el("ibadahLegendPanel").classList.remove("active");
|
||||
}
|
||||
} catch (error) {
|
||||
el("ibadahToggle").checked = false;
|
||||
el("ibadahLegendPanel").classList.remove("active");
|
||||
toast(error.message);
|
||||
}
|
||||
});
|
||||
el("searchInput").addEventListener("input", () => {
|
||||
clearTimeout(debounce);
|
||||
debounce = setTimeout(() => loadData().catch((error) => toast(error.message)), 260);
|
||||
|
||||
Reference in New Issue
Block a user