Initial commit: Setup Landing Page dan file pertemuan

This commit is contained in:
Romeo3
2026-06-09 13:50:00 +07:00
commit c94bc418ef
35 changed files with 8807 additions and 0 deletions
File diff suppressed because one or more lines are too long
+35
View File
@@ -0,0 +1,35 @@
<?php
session_start();
// Tolak akses jika bukan admin
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
http_response_code(403); // Status Forbidden
echo "Akses ditolak! Anda bukan operator.";
exit;
}
include 'koneksi.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$id = $_POST['id'];
$tabel = $_POST['tabel'];
// Daftar tabel yang diizinkan (untuk keamanan)
$allowed_tables = ['spbu_locations', 'jalan', 'parsil', 'rumah_ibadah', 'penduduk_miskin'];
if (in_array($tabel, $allowed_tables)) {
$stmt = $conn->prepare("DELETE FROM $tabel WHERE id = ?");
$stmt->bind_param("i", $id); // "i" karena ID sekarang adalah Integer
if ($stmt->execute()) {
echo "Data berhasil dihapus!";
} else {
echo "Gagal menghapus: " . $conn->error;
}
$stmt->close();
} else {
echo "Tabel tidak valid!";
}
$conn->close();
}
?>
+29
View File
@@ -0,0 +1,29 @@
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$lat = isset($_GET['lat']) ? floatval($_GET['lat']) : 0;
$lng = isset($_GET['lng']) ? floatval($_GET['lng']) : 0;
if (!$lat || !$lng) {
echo json_encode(['error' => 'Koordinat tidak valid']);
exit;
}
$url = "https://nominatim.openstreetmap.org/reverse?format=json&lat={$lat}&lon={$lng}&accept-language=id&zoom=18";
$context = stream_context_create([
'http' => [
'header' => "User-Agent: WebGIS-Pontianak/1.0\r\n",
'timeout' => 10
]
]);
$response = @file_get_contents($url, false, $context);
if ($response === false) {
echo json_encode(['error' => 'Gagal menghubungi Nominatim']);
exit;
}
echo $response;
+477
View File
@@ -0,0 +1,477 @@
<?php
session_start();
// Mengecek apakah user yang mengakses adalah admin/operator
$isAdmin = isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sistem WebGIS Terpadu — Kota Pontianak</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" />
<link
href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=DM+Mono:wght@400;500&display=swap"
rel="stylesheet">
<link rel="stylesheet" href="style.css">
<style>
</style>
</head>
<body>
<!-- ==============================
HEADER BAR
============================== -->
<div class="webgis-header">
<div class="header-brand">
<div class="brand-icon">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" />
</svg>
</div>
<div>
<div class="brand-name">WebGIS Terpadu</div>
<div class="brand-subtitle">Kota Pontianak</div>
</div>
</div>
<div class="header-divider"></div>
<!-- SEARCH BAR -->
<div class="search-wrapper">
<div class="search-bar">
<!-- Category Selector -->
<!-- Category Selector Custom -->
<div class="search-category-wrap" id="custom-select-wrap">
<!-- Ikon Garis Tiga (Asli) -->
<span class="search-category-icon">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.2">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 10h16M4 14h8" />
</svg>
</span>
<!-- Teks yang tampil -->
<div class="custom-select-trigger" id="custom-select-trigger">Semua Layer</div>
<input type="hidden" id="search-category" value="Semua">
<!-- Ikon Panah Bawah (Asli) -->
<span class="category-arrow">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
</svg>
</span>
<!-- Kotak Pilihan Dropdown yang Luas -->
<div class="custom-select-options" id="custom-select-options">
<div class="custom-option selected" data-value="Semua">Semua Layer</div>
<div class="custom-option" data-value="SPBU">SPBU</div>
<div class="custom-option" data-value="Jalan">Jaringan Jalan</div>
<div class="custom-option" data-value="Parsil">Parsil / Lahan</div>
<div class="custom-option" data-value="Rumah Ibadah">Rumah Ibadah</div>
</div>
</div>
<!-- Search Input -->
<div class="search-input-wrap">
<span class="search-icon">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</span>
<input type="text" id="search-input" placeholder="Cari nama lokasi, jalan, atau lahan..."
onkeyup="jalankanPencarian()" oninput="toggleClearBtn()" autocomplete="off">
<button class="search-clear-btn" id="search-clear" onclick="clearSearch()" title="Hapus pencarian">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
<!-- Dropdown Results -->
<div class="search-results" id="search-results"></div>
</div>
<!-- HEADER RIGHT TOOLS -->
<div class="header-tools">
<?php if ($isAdmin): ?>
<div class="user-profile-menu">
<button class="profile-trigger" id="profile-trigger" onclick="toggleProfileMenu(event)">
<img src="<?php echo htmlspecialchars($_SESSION['avatar']); ?>" class="profile-avatar" alt="Avatar">
<span class="profile-username"><?php echo htmlspecialchars($_SESSION['username']); ?></span>
<svg class="profile-chevron" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="profile-dropdown" id="profile-dropdown">
<div class="dropdown-user-info">
<div class="dropdown-username"><?php echo htmlspecialchars($_SESSION['username']); ?></div>
<div class="dropdown-role">Operator Wilayah</div>
</div>
<div class="dropdown-divider"></div>
<a href="logout.php" class="dropdown-item logout-link">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
<span>Logout</span>
</a>
</div>
</div>
<?php else: ?>
<a href="login.php" class="tool-btn auth-btn" title="Login Operator">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H7a3 3 0 01-3-3V7a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1" />
</svg>
<span>Login</span>
</a>
<?php endif; ?>
<div style="width: 1px; height: 20px; background: rgba(255,255,255,0.1); margin: 0 4px;"></div>
<div class="tool-btn" title="Status Koneksi">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0" />
</svg>
<div class="status-dot"></div>
</div>
<div class="tool-btn" title="Tentang Aplikasi">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
</div>
</div>
<!-- ==============================
SIDEBAR INPUT TERPUSAT
============================== -->
<!-- Toggle Button -->
<?php if ($isAdmin): ?>
<button class="sidebar-toggle" id="sidebar-toggle" title="Panel Input Data">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" />
</svg>
<span>Input Data</span>
</button>
<?php endif; ?>
<!-- Sidebar Panel -->
<div class="input-sidebar" id="input-sidebar">
<div class="sidebar-header">
<div class="sidebar-title">
<div class="sidebar-title-icon">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
</div>
<div>
<div class="sidebar-title-text">Input Data</div>
<div class="sidebar-title-sub">Tambah data ke peta</div>
</div>
</div>
<button class="sidebar-close" id="sidebar-close" title="Tutup">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<!-- Tab Navigation -->
<div class="sidebar-tabs">
<button class="stab active" data-tab="spbu" onclick="switchSidebarTab('spbu')">
<span class="stab-icon">⛽</span>
<span>SPBU</span>
</button>
<button class="stab" data-tab="jalan" onclick="switchSidebarTab('jalan')">
<span class="stab-icon">🛣️</span>
<span>Jalan</span>
</button>
<button class="stab" data-tab="parsil" onclick="switchSidebarTab('parsil')">
<span class="stab-icon">🏘️</span>
<span>Parsil</span>
</button>
<button class="stab" data-tab="ibadah" onclick="switchSidebarTab('ibadah')">
<span class="stab-icon">🕌</span>
<span>Ibadah</span>
</button>
<button class="stab" data-tab="penduduk" onclick="switchSidebarTab('penduduk')">
<span class="stab-icon">👥</span>
<span>Penduduk</span>
</button>
</div>
<!-- Scrollable Content -->
<div class="sidebar-body">
<!-- ===== TAB: SPBU ===== -->
<div class="stab-content active" id="tab-spbu">
<div class="step-guide">
<div class="step-badge">Langkah 1</div>
<p>Klik tombol <strong>Tandai Lokasi</strong>, lalu klik titik di peta untuk menentukan posisi SPBU.
</p>
</div>
<button class="btn-pick-location" id="btn-pick-spbu" onclick="activatePickMode('spbu')">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
Tandai Lokasi di Peta
</button>
<div class="coords-display" id="coords-spbu">
<span class="coords-label">Koordinat:</span>
<span class="coords-value" id="coords-spbu-val">Belum dipilih</span>
</div>
<div class="step-guide" style="margin-top:14px;">
<div class="step-badge">Langkah 2</div>
<p>Isi detail informasi SPBU di bawah ini.</p>
</div>
<div class="sfield">
<label class="sfield-label">Nama SPBU <span class="required">*</span></label>
<input type="text" id="sb_nama_spbu" class="sinput" placeholder="Contoh: SPBU Jl. Ahmad Yani">
</div>
<div class="sfield">
<label class="sfield-label">Nomor Telepon</label>
<input type="text" id="sb_nohp_spbu" class="sinput" placeholder="Contoh: 0561-xxxxxx">
</div>
<div class="sfield">
<label class="sfield-label">Status Operasional</label>
<select id="sb_kategori_spbu" class="sselect">
<option value="Ya">Buka 24 Jam</option>
<option value="Tidak">Reguler</option>
</select>
</div>
<button class="btn-save-sidebar" onclick="saveSPBUSidebar()">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
</svg>
Simpan SPBU
</button>
</div>
<!-- ===== TAB: JALAN ===== -->
<div class="stab-content" id="tab-jalan">
<div class="step-guide">
<div class="step-badge">Langkah 1</div>
<p>Klik tombol <strong>Gambar Jalur</strong>, lalu klik titik-titik di peta membentuk ruas jalan.
Klik dua kali untuk selesai.</p>
</div>
<button class="btn-pick-location btn-draw" id="btn-draw-jalan" onclick="activateDrawMode('polyline')">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
</svg>
Gambar Jalur di Peta
</button>
<div class="coords-display" id="coords-jalan">
<span class="coords-label">Status:</span>
<span class="coords-value" id="coords-jalan-val">Belum digambar</span>
</div>
<div class="step-guide" style="margin-top:14px;">
<div class="step-badge">Langkah 2</div>
<p>Isi detail informasi jalan di bawah ini.</p>
</div>
<div class="sfield">
<label class="sfield-label">Nama Jalan <span class="required">*</span></label>
<input type="text" id="sb_nama_jalan" class="sinput" placeholder="Contoh: Jl. Gajah Mada">
</div>
<div class="sfield">
<label class="sfield-label">Status Jalan</label>
<select id="sb_status_jalan" class="sselect">
<option value="Jalan Nasional">Jalan Nasional</option>
<option value="Jalan Provinsi">Jalan Provinsi</option>
<option value="Jalan Kabupaten">Jalan Kabupaten</option>
</select>
</div>
<div class="sfield">
<label class="sfield-label">Panjang Terukur</label>
<input type="text" id="sb_panjang_jalan" class="sinput" placeholder="Otomatis terisi" readonly>
</div>
<button class="btn-save-sidebar btn-teal" onclick="saveJalanSidebar()">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
</svg>
Simpan Jalan
</button>
</div>
<!-- ===== TAB: PARSIL ===== -->
<div class="stab-content" id="tab-parsil">
<div class="step-guide">
<div class="step-badge">Langkah 1</div>
<p>Klik tombol <strong>Gambar Parsil</strong>, lalu klik titik-titik untuk membentuk batas lahan.
Klik dua kali untuk selesai.</p>
</div>
<button class="btn-pick-location btn-purple" id="btn-draw-parsil" onclick="activateDrawMode('polygon')">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" />
</svg>
Gambar Area Parsil
</button>
<div class="coords-display" id="coords-parsil">
<span class="coords-label">Status:</span>
<span class="coords-value" id="coords-parsil-val">Belum digambar</span>
</div>
<div class="step-guide" style="margin-top:14px;">
<div class="step-badge">Langkah 2</div>
<p>Isi detail informasi lahan di bawah ini.</p>
</div>
<div class="sfield">
<label class="sfield-label">Nama Pemilik <span class="required">*</span></label>
<input type="text" id="sb_nama_parsil" class="sinput" placeholder="Contoh: Budi Santoso">
</div>
<div class="sfield">
<label class="sfield-label">Status Tanah</label>
<select id="sb_status_parsil" class="sselect">
<option value="SHM">SHM (Hak Milik)</option>
<option value="HGB">HGB (Guna Bangunan)</option>
<option value="HGU">HGU (Guna Usaha)</option>
<option value="HP">HP (Hak Pakai)</option>
</select>
</div>
<div class="sfield">
<label class="sfield-label">Luas Terukur</label>
<input type="text" id="sb_luas_parsil" class="sinput" placeholder="Otomatis terisi" readonly>
</div>
<button class="btn-save-sidebar btn-purple-solid" onclick="saveParsil_Sidebar()">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
</svg>
Simpan Parsil
</button>
</div>
<!-- ===== TAB: RUMAH IBADAH ===== -->
<div class="stab-content" id="tab-ibadah">
<div class="step-guide">
<div class="step-badge">Langkah 1</div>
<p>Klik tombol <strong>Tandai Lokasi</strong>, lalu klik titik di peta untuk menentukan posisi rumah
ibadah.</p>
</div>
<button class="btn-pick-location btn-amber" id="btn-pick-ibadah" onclick="activatePickMode('ibadah')">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
Tandai Lokasi di Peta
</button>
<div class="coords-display" id="coords-ibadah">
<span class="coords-label">Koordinat:</span>
<span class="coords-value" id="coords-ibadah-val">Belum dipilih</span>
</div>
<div class="step-guide" style="margin-top:14px;">
<div class="step-badge">Langkah 2</div>
<p>Isi nama rumah ibadah di bawah ini.</p>
</div>
<div class="sfield">
<label class="sfield-label">Nama Rumah Ibadah <span class="required">*</span></label>
<input type="text" id="sb_nama_ibadah" class="sinput" placeholder="Contoh: Masjid Raya Mujahidin">
</div>
<button class="btn-save-sidebar btn-amber-solid" onclick="saveRumahIbadahSidebar()">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
</svg>
Simpan Rumah Ibadah
</button>
</div>
<!-- ===== TAB: PENDUDUK MISKIN ===== -->
<div class="stab-content" id="tab-penduduk">
<div class="step-guide">
<div class="step-badge">Langkah 1</div>
<p>Klik tombol <strong>Tandai Lokasi</strong>, lalu klik titik di peta untuk menentukan posisi
tempat tinggal.</p>
</div>
<button class="btn-pick-location btn-red" id="btn-pick-penduduk" onclick="activatePickMode('penduduk')">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
Tandai Lokasi di Peta
</button>
<div class="coords-display" id="coords-penduduk">
<span class="coords-label">Koordinat:</span>
<span class="coords-value" id="coords-penduduk-val">Belum dipilih</span>
</div>
<div class="step-guide" style="margin-top:14px;">
<div class="step-badge">Langkah 2</div>
<p>Isi alamat dan nama kepala keluarga di bawah ini.</p>
</div>
<div class="sfield">
<label class="sfield-label">Alamat Lengkap <span class="required">*</span></label>
<textarea id="sb_alamat_penduduk" class="sinput" rows="3"
placeholder="Contoh: Jl. Sungai Raya Dalam Gg. Ceria No. 12" style="resize:none;"></textarea>
</div>
<div class="sfield">
<label class="sfield-label">Nama Kepala Keluarga <span class="required">*</span></label>
<input type="text" id="sb_nama_penduduk" class="sinput" placeholder="Contoh: Siti Rahayu">
</div>
<button class="btn-save-sidebar btn-red-solid" onclick="savePendudukSidebar()">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
</svg>
Simpan Penduduk
</button>
</div>
</div><!-- end sidebar-body -->
</div><!-- end input-sidebar -->
<!-- Overlay saat mode pilih lokasi aktif -->
<div class="pick-mode-overlay" id="pick-overlay">
<div class="pick-mode-banner">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5" />
</svg>
<span id="pick-overlay-text">Klik lokasi di peta...</span>
<button onclick="deactivatePickMode()">Batal</button>
</div>
</div>
<!-- MAP (DENGAN OFFSET HEADER) -->
<div id="map" style="padding-top: 56px; height: 100vh; box-sizing: border-box;"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@6/turf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet.heat@0.2.0/dist/leaflet-heat.js"></script>
<script>
// Variabel global untuk mendeteksi status admin di script.js
const IS_ADMIN = <?php echo $isAdmin ? 'true' : 'false'; ?>;
// Toggle dropdown menu profil pengguna
function toggleProfileMenu(e) {
e.stopPropagation();
var dropdown = document.getElementById('profile-dropdown');
if (dropdown) dropdown.classList.toggle('active');
}
// Tutup dropdown saat klik di luar area profil
document.addEventListener('click', function() {
var dropdown = document.getElementById('profile-dropdown');
if (dropdown) dropdown.classList.remove('active');
});
</script>
<script src="script.js"></script>
</body>
</html>
+48
View File
@@ -0,0 +1,48 @@
<?php
$host = "localhost";
$user = "root";
$pass = "";
$db = "webgis_db";
// Connect to MySQL server first
$conn = new mysqli($host, $user, $pass);
if ($conn->connect_error) {
die("Koneksi gagal: " . $conn->connect_error);
}
// Create database if not exists
$conn->query("CREATE DATABASE IF NOT EXISTS `$db` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;");
// Select database
$conn->select_db($db);
// Create users table
$sql_users = "CREATE TABLE IF NOT EXISTS `users` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(50) NOT NULL UNIQUE,
`password` VARCHAR(255) NOT NULL,
`avatar` VARCHAR(255) NOT NULL,
`role` VARCHAR(20) NOT NULL DEFAULT 'admin'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
if (!$conn->query($sql_users)) {
die("Gagal membuat tabel users: " . $conn->error);
}
// Seed default admin if empty
$check_empty = $conn->query("SELECT COUNT(*) as count FROM users");
$row = $check_empty->fetch_assoc();
if ($row['count'] == 0) {
$default_user = 'admin';
// Hashing password "admin123"
$default_pass = password_hash('admin123', PASSWORD_BCRYPT);
$default_avatar = 'https://ui-avatars.com/api/?name=Admin+Operator&background=1e40af&color=fff&bold=true&size=128';
$default_role = 'admin';
$stmt = $conn->prepare("INSERT INTO users (username, password, avatar, role) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $default_user, $default_pass, $default_avatar, $default_role);
$stmt->execute();
$stmt->close();
}
?>
+33
View File
@@ -0,0 +1,33 @@
<?php
include 'koneksi.php';
// Cek data apa yang diminta, jika kosong jadikan 'spbu' sebagai default
$jenis = isset($_GET['jenis']) ? $_GET['jenis'] : 'spbu';
if ($jenis == 'spbu') {
$sql = "SELECT * FROM spbu_locations";
} else if ($jenis == 'jalan') {
$sql = "SELECT * FROM jalan";
} else if ($jenis == 'parsil') {
$sql = "SELECT * FROM parsil";
} else if ($jenis == 'rumah_ibadah') {
$sql = "SELECT * FROM rumah_ibadah";
} else if ($jenis == 'penduduk_miskin') {
$sql = "SELECT * FROM penduduk_miskin";
} else {
die("Jenis data tidak ditemukan");
}
$result = $conn->query($sql);
$data = array();
if ($result && $result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$data[] = $row;
}
}
header('Content-Type: application/json');
echo json_encode($data);
$conn->close();
?>
+80
View File
@@ -0,0 +1,80 @@
<?php
session_start();
// Jika sudah login sebagai admin, tendang kembali ke index
if (isset($_SESSION['role']) && $_SESSION['role'] === 'admin') {
header("Location: index.php");
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
include 'koneksi.php';
// Query user from database
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? LIMIT 1");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
if ($result && $result->num_rows > 0) {
$user = $result->fetch_assoc();
// Check hashed password
if (password_verify($password, $user['password'])) {
$_SESSION['role'] = $user['role'];
$_SESSION['username'] = $user['username'];
$_SESSION['avatar'] = $user['avatar'];
header("Location: index.php");
exit;
}
}
$error = "Username atau password salah!";
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Operator - WebGIS Pontianak</title>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body class="login-body">
<div class="login-card">
<div class="login-logo">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" />
</svg>
</div>
<h2>Login Operator</h2>
<p>Masuk untuk mengelola data WebGIS</p>
<?php if (isset($error)): ?>
<div class="error-msg"><?php echo $error; ?></div>
<?php endif; ?>
<form method="POST" class="login-form">
<div class="sfield">
<label class="sfield-label">Username</label>
<input type="text" name="username" class="sinput" placeholder="Masukkan username..." required autofocus>
</div>
<div class="sfield">
<label class="sfield-label">Password</label>
<input type="password" name="password" class="sinput" placeholder="Masukkan password..." required>
</div>
<button type="submit" class="btn btn-save" style="width: 100%; margin-top: 8px;">Login ke Sistem</button>
</form>
<a href="index.php" class="back-link">← Kembali ke Peta</a>
</div>
</body>
</html>
+5
View File
@@ -0,0 +1,5 @@
<?php
session_start();
session_destroy(); // Menghapus semua sesi
header("Location: index.php");
exit;
+33
View File
@@ -0,0 +1,33 @@
<?php
session_start();
// Tolak akses jika bukan admin
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
http_response_code(403); // Status Forbidden
echo "Akses ditolak! Anda bukan operator.";
exit;
}
include 'koneksi.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$nama = $_POST['nama_spbu'];
$hp = $_POST['no_hp'];
$kategori = $_POST['kategori'];
$lat = $_POST['latitude'];
$lng = $_POST['longitude'];
// Perhatikan: id dihilangkan, tanda tanya hanya 5
$stmt = $conn->prepare("INSERT INTO spbu_locations (nama_spbu, no_hp, kategori, latitude, longitude) VALUES (?, ?, ?, ?, ?)");
// Perhatikan: huruf sssdd (5 huruf untuk 5 variabel)
$stmt->bind_param("sssdd", $nama, $hp, $kategori, $lat, $lng);
if ($stmt->execute()) {
echo "Data SPBU berhasil disimpan!";
} else {
echo "Gagal menyimpan data: " . $conn->error;
}
$stmt->close();
$conn->close();
}
+32
View File
@@ -0,0 +1,32 @@
<?php
session_start();
// Tolak akses jika bukan admin
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
http_response_code(403); // Status Forbidden
echo "Akses ditolak! Anda bukan operator.";
exit;
}
include 'koneksi.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$nama = $_POST['nama_jalan'];
$status = $_POST['status'];
$panjang = $_POST['panjang'];
$koordinat = $_POST['koordinat'];
// Perhatikan: id dihilangkan, tanda tanya hanya 4
$stmt = $conn->prepare("INSERT INTO jalan (nama_jalan, status, panjang, koordinat) VALUES (?, ?, ?, ?)");
// Perhatikan: huruf ssds (4 huruf untuk 4 variabel)
$stmt->bind_param("ssds", $nama, $status, $panjang, $koordinat);
if ($stmt->execute()) {
echo "Data Jalan berhasil disimpan!";
} else {
echo "Gagal: " . $conn->error;
}
$stmt->close();
$conn->close();
}
+32
View File
@@ -0,0 +1,32 @@
<?php
session_start();
// Tolak akses jika bukan admin
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
http_response_code(403); // Status Forbidden
echo "Akses ditolak! Anda bukan operator.";
exit;
}
include 'koneksi.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$nama = $_POST['nama_pemilik'];
$status = $_POST['status'];
$luas = $_POST['luas'];
$koordinat = $_POST['koordinat'];
// Perhatikan: id dihilangkan, tanda tanya hanya 4
$stmt = $conn->prepare("INSERT INTO parsil (nama_pemilik, status, luas, koordinat) VALUES (?, ?, ?, ?)");
// Perhatikan: huruf ssds (4 huruf untuk 4 variabel)
$stmt->bind_param("ssds", $nama, $status, $luas, $koordinat);
if ($stmt->execute()) {
echo "Data Parsil berhasil disimpan!";
} else {
echo "Gagal: " . $conn->error;
}
$stmt->close();
$conn->close();
}
+32
View File
@@ -0,0 +1,32 @@
<?php
session_start();
// Tolak akses jika bukan admin
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
http_response_code(403); // Status Forbidden
echo "Akses ditolak! Anda bukan operator.";
exit;
}
include 'koneksi.php';
// Ambil data dari metode POST
$nama = $_POST['nama'];
$alamat = $_POST['alamat'];
$latitude = $_POST['latitude'];
$longitude = $_POST['longitude'];
// Gunakan Prepared Statement untuk mencegah SQL Injection
$query = $conn->prepare("INSERT INTO penduduk_miskin (nama_kk, alamat, lat, lng) VALUES (?, ?, ?, ?)");
$query->bind_param("ssdd", $nama, $alamat, $latitude, $longitude);
// Eksekusi dan kirim respon ke Javascript
if ($query->execute()) {
echo "Data Penduduk Miskin berhasil disimpan!";
} else {
echo "Gagal menyimpan data: " . $conn->error;
}
$query->close();
$conn->close();
?>
+31
View File
@@ -0,0 +1,31 @@
<?php
session_start();
// Tolak akses jika bukan admin
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
http_response_code(403); // Status Forbidden
echo "Akses ditolak! Anda bukan operator.";
exit;
}
include 'koneksi.php';
// Ambil data dari metode POST
$nama = $_POST['nama'];
$latitude = $_POST['latitude'];
$longitude = $_POST['longitude'];
// Gunakan Prepared Statement untuk mencegah SQL Injection
$query = $conn->prepare("INSERT INTO rumah_ibadah (nama, lat, lng) VALUES (?, ?, ?)");
$query->bind_param("sdd", $nama, $latitude, $longitude);
// Eksekusi dan kirim respon ke Javascript
if ($query->execute()) {
echo "Data Rumah Ibadah berhasil disimpan!";
} else {
echo "Gagal menyimpan data: " . $conn->error;
}
$query->close();
$conn->close();
?>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+67
View File
@@ -0,0 +1,67 @@
<?php
session_start();
// Tolak akses jika bukan admin
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
http_response_code(403); // Status Forbidden
echo "Akses ditolak! Anda bukan operator.";
exit;
}
include 'koneksi.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$id = $_POST['id'];
$tabel = $_POST['tabel'];
$stmt = null;
if ($tabel == 'spbu_locations') {
$nama = $_POST['nama_spbu'];
$hp = $_POST['no_hp'];
$kategori = $_POST['kategori'];
$lat = $_POST['latitude'];
$lng = $_POST['longitude'];
$stmt = $conn->prepare("UPDATE spbu_locations SET nama_spbu=?, no_hp=?, kategori=?, latitude=?, longitude=? WHERE id=?");
$stmt->bind_param("sssddi", $nama, $hp, $kategori, $lat, $lng, $id);
} else if ($tabel == 'jalan') {
$nama = $_POST['nama_jalan']; $status = $_POST['status'];
$stmt = $conn->prepare("UPDATE jalan SET nama_jalan=?, status=? WHERE id=?");
$stmt->bind_param("ssi", $nama, $status, $id);
} else if ($tabel == 'parsil') {
$nama = $_POST['nama_pemilik']; $status = $_POST['status'];
$stmt = $conn->prepare("UPDATE parsil SET nama_pemilik=?, status=? WHERE id=?");
$stmt->bind_param("ssi", $nama, $status, $id);
} else if ($tabel == 'rumah_ibadah') {
$nama = $_POST['nama'];
$lat = $_POST['latitude'];
$lng = $_POST['longitude'];
$stmt = $conn->prepare("UPDATE rumah_ibadah SET nama=?, lat=?, lng=? WHERE id=?");
$stmt->bind_param("sddi", $nama, $lat, $lng, $id);
} else if ($tabel == 'penduduk_miskin') {
$nama = $_POST['nama'];
$alamat = $_POST['alamat'];
$lat = $_POST['latitude'];
$lng = $_POST['longitude'];
$stmt = $conn->prepare("UPDATE penduduk_miskin SET nama_kk=?, alamat=?, lat=?, lng=? WHERE id=?");
$stmt->bind_param("ssddi", $nama, $alamat, $lat, $lng, $id);
}
if ($stmt) {
if ($stmt->execute()) {
echo "Data berhasil diperbarui!";
} else {
echo "Gagal memperbarui: " . $conn->error;
}
$stmt->close();
} else {
echo "Tabel tidak valid!";
}
$conn->close();
}
?>