Fifth Commit

This commit is contained in:
2026-06-13 12:01:09 +07:00
parent c150df3dc2
commit 899847d81c
12 changed files with 241 additions and 7 deletions
+39
View File
@@ -0,0 +1,39 @@
<?php
require_once 'config/db.php';
try {
$pdo = getDB();
// Create users table
$sql = "
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
role ENUM('admin', 'public') NOT NULL DEFAULT 'public',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
";
$pdo->exec($sql);
// Insert admin and public if not exists
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users");
$stmt->execute();
if ($stmt->fetchColumn() == 0) {
$insert = $pdo->prepare("INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)");
// admin / admin123
$insert->execute(['admin', password_hash('admin123', PASSWORD_BCRYPT), 'admin']);
// public / public123
$insert->execute(['public', password_hash('public123', PASSWORD_BCRYPT), 'public']);
echo "Users created successfully.\n";
} else {
echo "Users table already populated.\n";
}
} catch (PDOException $e) {
echo "Error: " . $e->getMessage() . "\n";
}
+11
View File
@@ -3,9 +3,20 @@
require_once __DIR__ . '/../config/db.php'; require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/helpers.php'; require_once __DIR__ . '/../config/helpers.php';
session_start();
if (!isset($_SESSION['user_id'])) {
jsonResponse(['error' => 'Unauthorized'], 401);
}
handlePreflight(); handlePreflight();
$method = getMethod(); $method = getMethod();
if ($method !== 'GET') {
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
jsonResponse(['error' => 'Forbidden: Admin access required'], 403);
}
}
$db = getDB(); $db = getDB();
switch ($method) { switch ($method) {
+11
View File
@@ -3,9 +3,20 @@
require_once __DIR__ . '/../config/db.php'; require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/helpers.php'; require_once __DIR__ . '/../config/helpers.php';
session_start();
if (!isset($_SESSION['user_id'])) {
jsonResponse(['error' => 'Unauthorized'], 401);
}
handlePreflight(); handlePreflight();
$method = getMethod(); $method = getMethod();
if ($method !== 'GET') {
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
jsonResponse(['error' => 'Forbidden: Admin access required'], 403);
}
}
$db = getDB(); $db = getDB();
switch ($method) { switch ($method) {
+11
View File
@@ -7,9 +7,20 @@
require_once __DIR__ . '/../config/db.php'; require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/helpers.php'; require_once __DIR__ . '/../config/helpers.php';
session_start();
if (!isset($_SESSION['user_id'])) {
jsonResponse(['error' => 'Unauthorized'], 401);
}
handlePreflight(); handlePreflight();
$method = getMethod(); $method = getMethod();
if ($method !== 'GET') {
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
jsonResponse(['error' => 'Forbidden: Admin access required'], 403);
}
}
$db = getDB(); $db = getDB();
switch ($method) { switch ($method) {
+11
View File
@@ -9,9 +9,20 @@
require_once __DIR__ . '/../config/db.php'; require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/helpers.php'; require_once __DIR__ . '/../config/helpers.php';
session_start();
if (!isset($_SESSION['user_id'])) {
jsonResponse(['error' => 'Unauthorized'], 401);
}
handlePreflight(); handlePreflight();
$method = getMethod(); $method = getMethod();
if ($method !== 'GET') {
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
jsonResponse(['error' => 'Forbidden: Admin access required'], 403);
}
}
$db = getDB(); $db = getDB();
switch ($method) { switch ($method) {
+11
View File
@@ -7,9 +7,20 @@
require_once __DIR__ . '/../config/db.php'; require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/helpers.php'; require_once __DIR__ . '/../config/helpers.php';
session_start();
if (!isset($_SESSION['user_id'])) {
jsonResponse(['error' => 'Unauthorized'], 401);
}
handlePreflight(); handlePreflight();
$method = getMethod(); $method = getMethod();
if ($method !== 'GET') {
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
jsonResponse(['error' => 'Forbidden: Admin access required'], 403);
}
}
$db = getDB(); $db = getDB();
switch ($method) { switch ($method) {
+6
View File
@@ -491,3 +491,9 @@ body {
*::-webkit-scrollbar { width: 4px; } *::-webkit-scrollbar { width: 4px; }
*::-webkit-scrollbar-track { background: transparent; } *::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; } *::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
/* ── Role-based visibility overrides ───────────────────────── */
body.role-public .feature-actions,
body.role-public .popup-actions {
display: none !important;
}
+4 -4
View File
@@ -3,11 +3,11 @@
// config/db.php — Database connection (PDO) // config/db.php — Database connection (PDO)
// ============================================================ // ============================================================
define('DB_HOST', 'vsw0wwo480kg8sooc0s00sow'); define('DB_HOST', 'localhost');
define('DB_PORT', '3306'); define('DB_PORT', '3306');
define('DB_NAME', 'Pemetaan_Kemiskinan'); define('DB_NAME', 'webgis_db');
define('DB_USER', 'mysql'); define('DB_USER', 'root');
define('DB_PASS', '4ZUbGM9LD8zcJuGz0xgGOvNkLrAtZiarqP0QSCrM6uYM5ZHGuMVm1xXu68ChfyRa'); define('DB_PASS', 'root123');
define('DB_CHARSET', 'utf8mb4'); define('DB_CHARSET', 'utf8mb4');
function getDB(): PDO { function getDB(): PDO {
+24 -2
View File
@@ -1,3 +1,10 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@@ -11,15 +18,24 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css">
<!-- App CSS --> <!-- App CSS -->
<link rel="stylesheet" href="assets/css/style.css"> <link rel="stylesheet" href="assets/css/style.css">
<script>
window.USER_ROLE = "<?= $_SESSION['role'] ?>";
window.USER_NAME = "<?= $_SESSION['username'] ?>";
</script>
</head> </head>
<body> <body class="role-<?= $_SESSION['role'] ?>">
<!-- ═══════════════════════ HEADER ═══════════════════════ --> <!-- ═══════════════════════ HEADER ═══════════════════════ -->
<header id="header"> <header id="header">
<div class="logo">WEB<span>GIS</span></div> <div class="logo">WEB<span>GIS</span></div>
<div class="tagline">Spatial Data Management System · Soreang, West Java</div> <div class="tagline">Spatial Data Management System · KOTA PONTIANAK</div>
<div class="spacer"></div> <div class="spacer"></div>
<div class="status-badge"> LIVE</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> </header>
<!-- ═══════════════════════ MAIN APP ═══════════════════════ --> <!-- ═══════════════════════ MAIN APP ═══════════════════════ -->
@@ -145,6 +161,7 @@
<div class="info-box accent"> <div class="info-box accent">
Click the map to place a point, then fill in the form. Click the map to place a point, then fill in the form.
</div> </div>
<?php if ($_SESSION['role'] === 'admin'): ?>
<div class="btn-row" style="margin-top:0;margin-bottom:12px"> <div class="btn-row" style="margin-top:0;margin-bottom:12px">
<button class="btn btn-primary btn-full" data-mode="point" onclick="enablePointAdd()"> <button class="btn btn-primary btn-full" data-mode="point" onclick="enablePointAdd()">
Add Point on Map Add Point on Map
@@ -160,6 +177,7 @@
</button> </button>
</div> </div>
<?php endif; ?>
<div class="section-title">All Points</div> <div class="section-title">All Points</div>
<div class="feature-list" id="point-list"> <div class="feature-list" id="point-list">
<div class="info-box">Loading…</div> <div class="info-box">Loading…</div>
@@ -171,11 +189,13 @@
<div class="info-box accent"> <div class="info-box accent">
Draw a polyline on the map. Length is calculated automatically. Draw a polyline on the map. Length is calculated automatically.
</div> </div>
<?php if ($_SESSION['role'] === 'admin'): ?>
<div class="btn-row" style="margin-top:0;margin-bottom:12px"> <div class="btn-row" style="margin-top:0;margin-bottom:12px">
<button class="btn btn-primary btn-full" data-mode="road" onclick="startAddRoad()"> <button class="btn btn-primary btn-full" data-mode="road" onclick="startAddRoad()">
✏️ Draw Road on Map ✏️ Draw Road on Map
</button> </button>
</div> </div>
<?php endif; ?>
<div class="section-title">All Roads</div> <div class="section-title">All Roads</div>
<div class="feature-list" id="road-list"> <div class="feature-list" id="road-list">
<div class="info-box">Loading…</div> <div class="info-box">Loading…</div>
@@ -187,11 +207,13 @@
<div class="info-box accent"> <div class="info-box accent">
Draw a polygon on the map. Area is calculated automatically. Draw a polygon on the map. Area is calculated automatically.
</div> </div>
<?php if ($_SESSION['role'] === 'admin'): ?>
<div class="btn-row" style="margin-top:0;margin-bottom:12px"> <div class="btn-row" style="margin-top:0;margin-bottom:12px">
<button class="btn btn-primary btn-full" data-mode="parcel" onclick="startAddParcel()"> <button class="btn btn-primary btn-full" data-mode="parcel" onclick="startAddParcel()">
🗺️ Draw Parcel on Map 🗺️ Draw Parcel on Map
</button> </button>
</div> </div>
<?php endif; ?>
<div class="section-title">All Parcels</div> <div class="section-title">All Parcels</div>
<div class="feature-list" id="parcel-list"> <div class="feature-list" id="parcel-list">
<div class="info-box">Loading…</div> <div class="info-box">Loading…</div>
+1 -1
View File
@@ -264,7 +264,7 @@
<p> <p>
Membantu identifikasi wilayah bantuan berdasarkan jangkauan radius masjid di Kota Pontianak dengan pendekatan presisi geospasial. Membantu identifikasi wilayah bantuan berdasarkan jangkauan radius masjid di Kota Pontianak dengan pendekatan presisi geospasial.
</p> </p>
<a href="dashboard.html" class="btn"> <a href="login.php" class="btn">
Masuk ke Dashboard GIS Masuk ke Dashboard GIS
</a> </a>
</div> </div>
+107
View File
@@ -0,0 +1,107 @@
<?php
session_start();
require_once 'config/db.php';
if (isset($_SESSION['user_id'])) {
header("Location: dashboard.php");
exit;
}
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
if ($username && $password) {
$pdo = getDB();
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? LIMIT 1");
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password_hash'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['role'] = $user['role'];
header("Location: dashboard.php");
exit;
} else {
$error = 'Username atau password salah!';
}
} else {
$error = 'Silakan isi username dan password!';
}
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SinergiSpasial | Login</title>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #0b0f19;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background-image: linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
background-size: 30px 30px;
}
.login-box {
background: rgba(20, 27, 45, 0.8);
backdrop-filter: blur(10px);
padding: 40px;
border-radius: 15px;
border: 1px solid rgba(255, 255, 255, 0.1);
width: 100%;
max-width: 400px;
text-align: center;
}
h2 { margin-top: 0; color: #00d2ff; }
.form-group { margin-bottom: 20px; text-align: left; }
label { display: block; margin-bottom: 8px; font-size: 0.9rem; color: #94a3b8; }
input {
width: 100%; padding: 12px;
border-radius: 8px; border: 1px solid rgba(255,255,255,0.2);
background: rgba(0,0,0,0.2); color: #fff; font-size: 1rem; box-sizing: border-box;
}
input:focus { outline: none; border-color: #00d2ff; }
button {
width: 100%; padding: 12px; background: linear-gradient(45deg, #3a7bd5, #00d2ff);
border: none; border-radius: 30px; color: #fff; font-size: 1rem; font-weight: 600; cursor: pointer;
}
.error { color: #f43f5e; margin-bottom: 20px; font-size: 0.9rem; }
.info { font-size: 0.8rem; color: #94a3b8; margin-top: 20px; }
</style>
</head>
<body>
<div class="login-box">
<h2>Login SinergiSpasial</h2>
<?php if ($error): ?><div class="error"><?= $error ?></div><?php endif; ?>
<form method="POST">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" required>
</div>
<button type="submit">Masuk ke Dashboard</button>
</form>
<div class="info">
<p>Akses Admin: <b>admin</b> / <b>admin123</b></p>
<p>Akses Publik: <b>public</b> / <b>public123</b></p>
</div>
</div>
</body>
</html>
+5
View File
@@ -0,0 +1,5 @@
<?php
session_start();
session_destroy();
header("Location: index.php");
exit;