Files
2026-06-13 12:01:09 +07:00

328 lines
13 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGIS — Spatial Data Management System</title>
<!-- Leaflet CSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<!-- Leaflet Draw CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css">
<!-- App CSS -->
<link rel="stylesheet" href="assets/css/style.css">
<script>
window.USER_ROLE = "<?= $_SESSION['role'] ?>";
window.USER_NAME = "<?= $_SESSION['username'] ?>";
</script>
</head>
<body class="role-<?= $_SESSION['role'] ?>">
<!-- ═══════════════════════ HEADER ═══════════════════════ -->
<header id="header">
<div class="logo">WEB<span>GIS</span></div>
<div class="tagline">Spatial Data Management System · KOTA PONTIANAK</div>
<div class="spacer"></div>
<div class="status-badge">● LIVE</div>
<div class="user-profile" style="margin-left: 20px; display: flex; gap: 10px; align-items: center; background: rgba(255,255,255,0.1); padding: 5px 15px; border-radius: 20px;">
<span style="font-weight: 600; color: #fff;"><?= htmlspecialchars(ucfirst($_SESSION['username'])) ?></span>
<span style="background: var(--primary); padding: 2px 8px; border-radius: 12px; font-size: 0.75rem; font-weight: bold; color: #fff;"><?= strtoupper($_SESSION['role']) ?></span>
<a href="logout.php" style="color: #ef4444; text-decoration: none; font-weight: bold; margin-left: 10px; font-size: 0.9rem;">Logout</a>
</div>
</header>
<!-- ═══════════════════════ MAIN APP ═══════════════════════ -->
<div id="app">
<!-- ───────── SIDEBAR ───────── -->
<aside id="sidebar">
<!-- Tab Navigation -->
<nav id="sidebar-tabs">
<button class="tab-btn active" data-tab="layers">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
LAYERS
</button>
<button class="tab-btn" data-tab="points">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="4"/><circle cx="12" cy="12" r="10" stroke-dasharray="2 3"/>
</svg>
POINTS
</button>
<button class="tab-btn" data-tab="roads">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M5 3v18M19 3v18M5 12h14"/>
</svg>
ROADS
</button>
<button class="tab-btn" data-tab="parcels">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="3" width="18" height="18" rx="2"/>
<path d="M9 3v18M3 9h18"/>
</svg>
PARCELS
</button>
<button class="tab-btn" data-tab="laporan">
📢 LAPORAN
</button>
</nav>
<!-- Tab Content -->
<div id="sidebar-content">
<!-- ════ LAYERS PANEL ════ -->
<div class="panel active" id="panel-layers">
<div class="section-title">⛽ SPBU — Gas Stations</div>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="spbu24" checked>
<div class="layer-swatch circle" style="background:#22c55e"></div>
<span class="layer-label">24 Hours SPBU</span>
<span class="layer-count" data-count-layer="spbu24">0</span>
</label>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="spbuNot" checked>
<div class="layer-swatch circle" style="background:#eab308"></div>
<span class="layer-label">Not 24 Hours SPBU</span>
<span class="layer-count" data-count-layer="spbuNot">0</span>
</label>
<div class="section-title">🕌 Other Points</div>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="mosque" checked>
<div class="layer-swatch circle" style="background:#a78bfa"></div>
<span class="layer-label">Mosques</span>
<span class="layer-count" data-count-layer="mosque">0</span>
</label>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="poor" checked>
<div class="layer-swatch circle" style="background:#f43f5e"></div>
<span class="layer-label">Poor Population Zones</span>
<span class="layer-count" data-count-layer="poor">0</span>
</label>
<div class="section-title">🛣️ Roads</div>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="national" checked>
<div class="layer-swatch" style="background:#ef4444"></div>
<span class="layer-label">National Road</span>
<span class="layer-count" data-count-layer="national">0</span>
</label>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="provincial" checked>
<div class="layer-swatch" style="background:#f97316"></div>
<span class="layer-label">Provincial Road</span>
<span class="layer-count" data-count-layer="provincial">0</span>
</label>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="district" checked>
<div class="layer-swatch" style="background:#3b82f6"></div>
<span class="layer-label">District Road</span>
<span class="layer-count" data-count-layer="district">0</span>
</label>
<div class="section-title">🗺️ Land Parcels</div>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="shm" checked>
<div class="layer-swatch" style="background:#10b981"></div>
<span class="layer-label">SHM — Freehold</span>
<span class="layer-count" data-count-layer="shm">0</span>
</label>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="hgb" checked>
<div class="layer-swatch" style="background:#6366f1"></div>
<span class="layer-label">HGB — Building Rights</span>
<span class="layer-count" data-count-layer="hgb">0</span>
</label>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="hgu" checked>
<div class="layer-swatch" style="background:#f59e0b"></div>
<span class="layer-label">HGU — Business Rights</span>
<span class="layer-count" data-count-layer="hgu">0</span>
</label>
<label class="layer-item">
<input type="checkbox" class="layer-cb" data-layer="hp" checked>
<div class="layer-swatch" style="background:#ec4899"></div>
<span class="layer-label">HP — Usage Rights</span>
<span class="layer-count" data-count-layer="hp">0</span>
</label>
</div>
<!-- ════ POINTS PANEL ════ -->
<div class="panel" id="panel-points">
<div class="info-box accent">
Click the map to place a point, then fill in the form.
</div>
<?php if ($_SESSION['role'] === 'admin'): ?>
<div class="btn-row" style="margin-top:0;margin-bottom:12px">
<button class="btn btn-primary btn-full" data-mode="point" onclick="enablePointAdd()">
Add Point on Map
</button>
<button
class="btn btn-secondary btn-full"
onclick="enableLaporanAdd()"
style="margin-top:8px">
📢 Laporkan Warga Miskin
</button>
</div>
<?php endif; ?>
<div class="section-title">All Points</div>
<div class="feature-list" id="point-list">
<div class="info-box">Loading…</div>
</div>
</div>
<!-- ════ ROADS PANEL ════ -->
<div class="panel" id="panel-roads">
<div class="info-box accent">
Draw a polyline on the map. Length is calculated automatically.
</div>
<?php if ($_SESSION['role'] === 'admin'): ?>
<div class="btn-row" style="margin-top:0;margin-bottom:12px">
<button class="btn btn-primary btn-full" data-mode="road" onclick="startAddRoad()">
✏️ Draw Road on Map
</button>
</div>
<?php endif; ?>
<div class="section-title">All Roads</div>
<div class="feature-list" id="road-list">
<div class="info-box">Loading…</div>
</div>
</div>
<!-- ════ PARCELS PANEL ════ -->
<div class="panel" id="panel-parcels">
<div class="info-box accent">
Draw a polygon on the map. Area is calculated automatically.
</div>
<?php if ($_SESSION['role'] === 'admin'): ?>
<div class="btn-row" style="margin-top:0;margin-bottom:12px">
<button class="btn btn-primary btn-full" data-mode="parcel" onclick="startAddParcel()">
🗺️ Draw Parcel on Map
</button>
</div>
<?php endif; ?>
<div class="section-title">All Parcels</div>
<div class="feature-list" id="parcel-list">
<div class="info-box">Loading…</div>
</div>
</div>
<!-- ════ LAPORAN PANEL ════ -->
<div class="panel" id="panel-laporan">
<div class="info-box accent">
Daftar laporan masyarakat yang menunggu verifikasi.
</div>
<div class="section-title">
Laporan Masyarakat
</div>
<div class="feature-list" id="laporan-list">
<div class="info-box">
Loading...
</div>
</div>
</div>
</div><!-- /sidebar-content -->
</aside>
<!-- ───────── MAP CONTAINER ───────── -->
<div id="map-container">
<!-- 🔥 PINDAH KE SINI -->
<div style="
position:absolute;
top:10px;
left:50px;
z-index:1000;
background:white;
padding:10px;
border-radius:8px;
box-shadow:0 2px 6px rgba(0,0,0,0.2);
">
Radius: <span id="radiusValue">500</span> m<br>
<input type="range" id="radiusSlider" min="100" max="2000" value="500">
</div>
<div id="map"></div>
<!-- Coordinates display -->
<div id="coords-display">0.000000, 0.000000</div>
<!-- Cancel draw hint (shown only during draw mode) -->
<div id="draw-hint" style="
display:none;
position:absolute;
top:12px;
left:50%;
transform:translateX(-50%);
z-index:500;
background:rgba(15,17,23,0.9);
border:1px solid var(--accent2);
color:var(--accent2);
border-radius:8px;
padding:6px 16px;
font-size:12px;
font-family:'Space Mono',monospace;
pointer-events:none;
">Press <strong>ESC</strong> to cancel</div>
</div>
</div><!-- /app -->
<!-- ═══════════════════════ STATS BAR ═══════════════════════ -->
<footer id="stats-bar">
<div class="stat-item">
<span class="stat-label">POINTS</span>
<span class="stat-val" id="stat-points">0</span>
</div>
<div class="stat-item">
<span class="stat-label">ROADS</span>
<span class="stat-val" id="stat-roads">0</span>
</div>
<div class="stat-item">
<span class="stat-label">PARCELS</span>
<span class="stat-val" id="stat-parcels">0</span>
</div>
<span style="margin-left:auto;color:var(--text-muted)">© WebGIS · OpenStreetMap</span>
</footer>
<!-- ═══════════════════════ MODAL ═══════════════════════ -->
<div id="modal-overlay">
<div id="modal"><!-- dynamically filled --></div>
</div>
<!-- ═══════════════════════ TOAST ═══════════════════════ -->
<div id="toast-container"></div>
<!-- ─── Leaflet JS ─── -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<!-- Leaflet Draw -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
<!-- Leaflet Geometry Util (for geodesic area calculation) -->
<script src="https://cdn.jsdelivr.net/npm/leaflet-geometryutil@0.10.3/src/leaflet.geometryutil.js"></script>
<!-- App JS -->
<script src="assets/js/app.js"></script>
</body>
</html>