feat: complete WebGIS implementation with nominal bantuan and cache busting
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
// ================================================================
|
||||
// Dashboard Utama — WebGIS Peta Interaktif
|
||||
// ================================================================
|
||||
require_once __DIR__ . '/config/config.php';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= APP_NAME ?></title>
|
||||
<meta name="description" content="WebGIS interaktif untuk pemetaan sebaran penduduk miskin dan rumah ibadah dengan analisis spasial radius layanan.">
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css"/>
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<!-- Bootstrap Icons -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
|
||||
<!-- App CSS -->
|
||||
<link rel="stylesheet" href="<?= BASE_URL ?>/assets/css/app.css?v=<?= time() ?>">
|
||||
<!-- SweetAlert2 -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
<style>
|
||||
/* Extra inline for Leaflet.heat & routing indicator */
|
||||
.leaflet-routing-container { display: none !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-layout">
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════
|
||||
SIDEBAR
|
||||
══════════════════════════════════════════════════════════ -->
|
||||
<aside class="sidebar" id="sidebar">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="sidebar-header">
|
||||
<div class="sidebar-brand">
|
||||
<div class="brand-icon">🗺️</div>
|
||||
<div>
|
||||
<div class="brand-title"><?= APP_NAME ?></div>
|
||||
<div class="brand-sub">OpenStreetMap · Leaflet.js</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search -->
|
||||
<div class="search-box">
|
||||
<span class="search-icon">🔍</span>
|
||||
<input type="text" id="global-search" placeholder="Cari warga atau rumah ibadah...">
|
||||
</div>
|
||||
|
||||
<!-- Filter -->
|
||||
<div class="filter-row">
|
||||
<select class="filter-select" id="filter-status">
|
||||
<option value="">Semua Status</option>
|
||||
<option value="belum">Belum Dibantu</option>
|
||||
<option value="sudah">Sudah Dibantu</option>
|
||||
<option value="menunggu">Menunggu</option>
|
||||
</select>
|
||||
<select class="filter-select" id="filter-jenis">
|
||||
<option value="">Semua Ibadah</option>
|
||||
<option value="Masjid">Masjid</option>
|
||||
<option value="Musholla">Musholla</option>
|
||||
<option value="Gereja">Gereja</option>
|
||||
<option value="Katolik">Katolik</option>
|
||||
<option value="Pura">Pura</option>
|
||||
<option value="Vihara">Vihara</option>
|
||||
<option value="Klenteng">Klenteng</option>
|
||||
<option value="Lainnya">Lainnya</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- Filter Wilayah -->
|
||||
<div class="filter-row" style="margin-top:6px;">
|
||||
<select class="filter-select" id="filter-kecamatan" style="width:100%;">
|
||||
<option value="">Semua Kecamatan</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-row" style="margin-top:4px;">
|
||||
<select class="filter-select" id="filter-kelurahan" style="width:100%;">
|
||||
<option value="">Semua Kelurahan</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card blue">
|
||||
<div class="stat-num" id="stat-ibadah">0</div>
|
||||
<div class="stat-label">Rumah Ibadah</div>
|
||||
</div>
|
||||
<div class="stat-card yellow">
|
||||
<div class="stat-num" id="stat-miskin">0</div>
|
||||
<div class="stat-label">Total Warga</div>
|
||||
</div>
|
||||
<div class="stat-card green">
|
||||
<div class="stat-num" id="stat-sudah">0</div>
|
||||
<div class="stat-label">Sudah Dibantu</div>
|
||||
</div>
|
||||
<div class="stat-card red">
|
||||
<div class="stat-num" id="stat-belum">0</div>
|
||||
<div class="stat-label">Belum Dibantu</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background:rgba(34,197,94,0.1); border:1px solid rgba(34,197,94,0.2); border-radius:12px; padding:12px; margin-bottom:16px; display:flex; align-items:center; gap:12px;">
|
||||
<div style="font-size:24px; padding:8px; background:rgba(34,197,94,0.15); border-radius:8px;">💰</div>
|
||||
<div>
|
||||
<div id="stat-nominal" style="font-size:18px; font-weight:800; color:var(--green); font-family:'JetBrains Mono',monospace;">Rp 0</div>
|
||||
<div style="font-size:11px; color:var(--text2); margin-top:2px;">Total Bantuan Disalurkan</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tabs -->
|
||||
<div class="sidebar-tabs">
|
||||
<button class="tab-btn active" id="tab-ibadah" onclick="switchTab('ibadah')">
|
||||
🏛️ Rumah Ibadah <span class="count-badge" id="count-ibadah">0</span>
|
||||
</button>
|
||||
<button class="tab-btn" id="tab-miskin" onclick="switchTab('miskin')">
|
||||
👤 Penduduk <span class="count-badge" id="count-miskin">0</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- List Body -->
|
||||
<div class="sidebar-body" id="sidebar-body">
|
||||
<div id="list-ibadah">
|
||||
<div class="empty-state">
|
||||
<span class="empty-icon">🏛️</span>
|
||||
<div>Belum ada data rumah ibadah</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="list-miskin" style="display:none">
|
||||
<div class="empty-state">
|
||||
<span class="empty-icon">👤</span>
|
||||
<div>Belum ada data penduduk</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="sidebar-footer">
|
||||
<div class="sidebar-btn-row">
|
||||
<a href="<?= BASE_URL ?>/landing.php" class="btn-sm-action" title="Kembali ke pilih mode" style="text-decoration:none;text-align:center;">
|
||||
<i class="bi bi-house-fill"></i> Mode
|
||||
</a>
|
||||
<button class="btn-sm-action accent" onclick="window.open('<?= BASE_URL ?>/admin/', '_blank')">
|
||||
<i class="bi bi-grid"></i> Admin
|
||||
</button>
|
||||
<button class="btn-sm-action" onclick="refreshAll()" title="Refresh data">
|
||||
<i class="bi bi-arrow-clockwise"></i> Refresh
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════
|
||||
MAP CONTAINER
|
||||
══════════════════════════════════════════════════════════ -->
|
||||
<div class="map-wrap">
|
||||
<div id="map"></div>
|
||||
|
||||
<!-- Floating Toolbar -->
|
||||
<div class="map-toolbar" id="map-toolbar">
|
||||
<span class="toolbar-label">Tambah:</span>
|
||||
<button class="toggle-btn" id="toggle-ibadah" onclick="setMode('ibadah')">🏛️ Ibadah</button>
|
||||
<button class="toggle-btn" id="toggle-miskin" onclick="setMode('miskin')">👤 Penduduk</button>
|
||||
<div class="toolbar-divider"></div>
|
||||
<button class="toolbar-icon-btn" onclick="doLocate()" title="Lokasi Saya">📍</button>
|
||||
<button class="toolbar-icon-btn" id="btn-notif" onclick="toggleNotifPanel()" title="Notifikasi" style="position:relative;">
|
||||
🔔<span id="notif-badge" style="display:none;position:absolute;top:-4px;right:-4px;background:#ef4444;color:#fff;font-size:9px;font-weight:700;border-radius:50%;width:16px;height:16px;display:none;align-items:center;justify-content:center;">0</span>
|
||||
</button>
|
||||
<button class="toolbar-icon-btn" id="toggle-sidebar-btn" onclick="toggleSidebar()" title="Toggle Sidebar">☰</button>
|
||||
</div>
|
||||
|
||||
<!-- Notification Panel -->
|
||||
<div id="notif-panel" style="display:none;position:absolute;top:60px;right:16px;width:280px;background:var(--panel-bg,#1e2538);border:1px solid var(--border,rgba(255,255,255,.08));border-radius:12px;z-index:1000;box-shadow:0 8px 32px rgba(0,0,0,.4);overflow:hidden;">
|
||||
<div style="padding:12px 16px;border-bottom:1px solid rgba(255,255,255,.06);font-weight:700;font-size:13px;display:flex;justify-content:space-between;align-items:center;">
|
||||
🔔 Notifikasi
|
||||
<button onclick="toggleNotifPanel()" style="background:none;border:none;color:var(--text3,#666);cursor:pointer;font-size:16px;">✕</button>
|
||||
</div>
|
||||
<div id="notif-list" style="padding:12px 16px;font-size:12px;min-height:60px;"></div>
|
||||
</div>
|
||||
|
||||
<!-- Map Controls -->
|
||||
<div class="map-controls">
|
||||
<button class="map-ctrl-btn" onclick="map.zoomIn()" title="Zoom In">+</button>
|
||||
<button class="map-ctrl-btn" onclick="map.zoomOut()" title="Zoom Out">-</button>
|
||||
<button class="map-ctrl-btn" id="btn-heatmap" onclick="toggleHeatmap()" title="Heatmap">🔥</button>
|
||||
<button class="map-ctrl-btn" id="btn-layers" onclick="toggleBasemap()" title="Ganti Basemap">🗺️</button>
|
||||
</div>
|
||||
|
||||
<!-- Legend -->
|
||||
<div class="map-legend" id="map-legend">
|
||||
<div class="legend-title">Legenda</div>
|
||||
<div class="legend-item"><div class="legend-dot" style="background:#22c55e"></div> Sudah Dibantu</div>
|
||||
<div class="legend-item"><div class="legend-dot" style="background:#ef4444"></div> Belum Dibantu</div>
|
||||
<div class="legend-item"><div class="legend-dot" style="background:#f59e0b"></div> Menunggu Verif.</div>
|
||||
<div class="legend-item" style="margin-top:6px;">
|
||||
<div class="legend-rect" style="background:rgba(91,127,255,0.15);border:1px dashed #5b7fff"></div> Radius Layanan
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Location Bar -->
|
||||
<div class="loc-bar" id="loc-bar">
|
||||
📍 <strong id="loc-bar-addr">—</strong>
|
||||
<span id="loc-bar-coord" style="font-size:10px;opacity:0.6;"></span>
|
||||
</div>
|
||||
|
||||
</div><!-- .map-wrap -->
|
||||
|
||||
</div><!-- .app-layout -->
|
||||
|
||||
<!-- Toast -->
|
||||
<div id="toast"></div>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════
|
||||
MODAL: TAMBAH/EDIT RUMAH IBADAH
|
||||
══════════════════════════════════════════════════════════ -->
|
||||
<?php include __DIR__ . '/includes/modal_ibadah.php'; ?>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════
|
||||
MODAL: TAMBAH/EDIT PENDUDUK MISKIN
|
||||
══════════════════════════════════════════════════════════ -->
|
||||
<?php include __DIR__ . '/includes/modal_miskin.php'; ?>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════
|
||||
SCRIPTS
|
||||
══════════════════════════════════════════════════════════ -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.js"></script>
|
||||
<!-- Leaflet Heat -->
|
||||
<script src="https://unpkg.com/leaflet.heat@0.2.0/dist/leaflet-heat.js"></script>
|
||||
<!-- Leaflet Routing Machine -->
|
||||
<script src="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.min.js"></script>
|
||||
|
||||
<script>
|
||||
const BASE_URL = '<?= BASE_URL ?>';
|
||||
const MAP_LAT = <?= MAP_DEFAULT_LAT ?>;
|
||||
const MAP_LNG = <?= MAP_DEFAULT_LNG ?>;
|
||||
const MAP_ZOOM = <?= MAP_DEFAULT_ZOOM ?>;
|
||||
</script>
|
||||
|
||||
<script src="<?= BASE_URL ?>/assets/js/map.js?v=<?= time() ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user