Files
webgis_geospesial/login.php
T

269 lines
14 KiB
PHP
Raw 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();
// Jika sudah login, redirect ke dashboard.php
if (isset($_SESSION['user_id'])) {
header('Location: dashboard.php');
exit;
}
include 'koneksi.php';
// Ambil pengaturan show_demo_accounts
$show_demo = 1; // default
try {
$stmt = $pdo->query("SELECT setting_value FROM settings WHERE setting_key = 'show_demo_accounts'");
if ($row = $stmt->fetch()) {
$show_demo = (int)$row['setting_value'];
}
} catch (Exception $e) {}
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? ''); // Bisa email atau username
$password = trim($_POST['password'] ?? '');
if ($username && $password) {
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? OR email = ?");
$stmt->execute([$username, $username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
// Cek status pending
if ($user['status'] === 'pending') {
$error = 'Akun Anda sedang menunggu persetujuan Admin.';
} else {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['role'] = $user['role'];
header('Location: dashboard.php');
exit;
}
} else {
$error = 'Email/Username atau password salah.';
}
} else {
$error = 'Silakan isi Email/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>Login WebGIS Pengentasan Kemiskinan</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['"Plus Jakarta Sans"', 'sans-serif'],
heading: ['"Plus Jakarta Sans"', 'sans-serif'],
mono: ['"JetBrains Mono"', 'monospace'],
},
colors: {
background: '#f8fafc',
foreground: '#0f172a',
primary: { DEFAULT: '#e11d48', foreground: '#ffffff' },
muted: { DEFAULT: '#f1f5f9', foreground: '#64748b' },
border: '#e2e8f0',
accent: '#e11d48',
}
}
}
}
</script>
<style>
.group-focus-within\:text-primary:focus-within { color: #e11d48; }
.focus-visible\:ring-primary\/20:focus-visible { --tw-ring-color: rgba(225, 29, 72, 0.2); }
.hover\:border-primary\/60:hover { border-color: rgba(225, 29, 72, 0.6); }
.focus-visible\:border-primary:focus-visible { border-color: #e11d48; }
/* Checkbox styling */
input[type="checkbox"]:checked {
background-color: #e11d48;
border-color: #e11d48;
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
}
/* Custom Pink Scrollbar */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #e11d48; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: #be123c; }
</style>
</head>
<body>
<?php if ($error): ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
Swal.fire({
icon: 'error',
title: 'Akses Ditolak',
text: '<?= htmlspecialchars($error) ?>',
confirmButtonColor: '#e11d48'
});
});
</script>
<?php endif; ?>
<main class="relative flex h-screen w-full items-center justify-center overflow-hidden font-sans text-foreground">
<!-- Full Screen Background Map -->
<img src="assets/img/map-bg.png" alt="Visualisasi peta analisis spasial" class="absolute inset-0 object-cover w-full h-full" onerror="this.src='https://images.unsplash.com/photo-1524661135-423995f22d0b?q=80&w=2074&auto=format&fit=crop'" />
<div aria-hidden="true" class="absolute inset-0 bg-gradient-to-br from-red-900/90 via-red-950/80 to-black/90"></div>
<div aria-hidden="true" class="absolute inset-0 opacity-10" style="background-image: linear-gradient(to right, white 1px, transparent 1px), linear-gradient(to bottom, white 1px, transparent 1px); background-size: 52px 52px;"></div>
<!-- Giant Card Container -->
<div class="relative z-10 flex w-[90%] max-w-5xl flex-col lg:flex-row overflow-hidden rounded-[2rem] border border-white/20 bg-white/10 shadow-2xl backdrop-blur-xl">
<!-- LEFT SECTION: Public Access -->
<div class="flex flex-col justify-between p-8 lg:w-1/2 lg:p-12">
<!-- Top / Brand -->
<div class="mb-8">
<div class="mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-white/15 ring-1 ring-white/30">
<svg viewBox="0 0 24 24" fill="none" class="h-6 w-6 text-white" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 21s-7-5.6-7-11a7 7 0 1 1 14 0c0 5.4-7 11-7 11Z" />
<circle cx="12" cy="10" r="2.5" />
</svg>
</div>
<h1 class="font-heading text-2xl font-bold tracking-tight text-white lg:text-3xl">WebGIS Geospasial</h1>
<p class="mt-2 text-sm leading-relaxed text-white/80">
Platform pemetaan cerdas untuk analisis spasial persebaran infrastruktur dan demografi kemiskinan.
</p>
</div>
<!-- Bottom / Public Shortcuts -->
<div>
<h2 class="mb-3 flex items-center gap-2 text-sm font-bold text-white/90">
<svg viewBox="0 0 24 24" fill="none" class="h-4.5 w-4.5 text-rose-300" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M2 12h4l2-9 5 18 3-10h4"></path>
</svg>
Project Kelas (Akses Publik):
</h2>
<div class="flex flex-col gap-3">
<a href="index.php?modul=spbu" class="group flex items-center gap-3 rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-sm font-bold text-white transition-all hover:-translate-y-0.5 hover:border-white/30 hover:bg-white/20">
<span class="text-xl transition-transform group-hover:scale-110">⛽</span>
Peta Lokasi SPBU
</a>
<a href="index.php?modul=tematik" class="group flex items-center gap-3 rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-sm font-bold text-white transition-all hover:-translate-y-0.5 hover:border-white/30 hover:bg-white/20">
<span class="text-xl transition-transform group-hover:scale-110">🗺️</span>
Peta Tematik
</a>
<a href="index.php?modul=digitasi" class="group flex items-center gap-3 rounded-xl border border-white/10 bg-white/5 px-4 py-3 text-sm font-bold text-white transition-all hover:-translate-y-0.5 hover:border-white/30 hover:bg-white/20">
<span class="text-xl transition-transform group-hover:scale-110">📐</span>
Digitasi Lahan Kota
</a>
</div>
</div>
</div>
<!-- RIGHT SECTION: Login Form -->
<div class="flex flex-col justify-center bg-white/95 p-8 lg:w-1/2 lg:p-12">
<div class="mb-6 text-center">
<h2 class="font-heading text-2xl font-bold tracking-tight text-foreground sm:text-3xl">Login Aplikasi Kemiskinan</h2>
<p class="mt-2 text-sm leading-relaxed text-muted-foreground">
Silakan masuk untuk mengakses pusat kendali data kemiskinan, memverifikasi bantuan, dan melihat statistik penduduk miskin.
</p>
</div>
<form action="login.php" method="POST" class="flex flex-col gap-4">
<!-- Input Email / Username -->
<div class="group">
<label for="username" class="mb-1 block text-xs font-semibold text-foreground group-focus-within:text-primary transition-colors">Email atau Username</label>
<div class="relative">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-muted-foreground group-focus-within:text-primary transition-colors">
<svg viewBox="0 0 24 24" fill="none" class="h-4.5 w-4.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path>
<circle cx="12" cy="7" r="4"></circle>
</svg>
</div>
<input type="text" id="username" name="username" class="block w-full rounded-lg border border-border bg-white py-2 pl-9 pr-3 text-sm transition-all focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 hover:border-primary/60" placeholder="admin" required autocomplete="username">
</div>
</div>
<!-- Input Password -->
<div class="group">
<label for="password" class="mb-1 block text-xs font-semibold text-foreground group-focus-within:text-primary transition-colors">Kata Sandi</label>
<div class="relative">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-muted-foreground group-focus-within:text-primary transition-colors">
<svg viewBox="0 0 24 24" fill="none" class="h-4.5 w-4.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg>
</div>
<input type="password" id="password" name="password" class="block w-full rounded-lg border border-border bg-white py-2 pl-9 pr-9 text-sm transition-all focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 hover:border-primary/60" placeholder="••••••••" required autocomplete="current-password">
<button type="button" id="togglePassword" class="absolute inset-y-0 right-0 flex items-center pr-3 text-muted-foreground hover:text-foreground focus:outline-none">
<svg id="eyeIcon" viewBox="0 0 24 24" fill="none" class="h-4 w-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
<circle cx="12" cy="12" r="3"></circle>
</svg>
</button>
</div>
</div>
<!-- Options -->
<div class="flex items-center justify-between mt-1">
<label class="flex items-center gap-2 cursor-pointer group">
<input type="checkbox" name="remember" class="h-3.5 w-3.5 rounded border-border text-primary shadow-sm focus:ring-primary focus:ring-offset-0">
<span class="text-xs font-medium text-muted-foreground group-hover:text-foreground transition-colors">Ingat saya</span>
</label>
<a href="#" class="text-xs font-semibold text-primary hover:text-primary/80">Lupa sandi?</a>
</div>
<!-- Submit -->
<button type="submit" class="group mt-2 flex h-10 items-center justify-center gap-2 rounded-lg bg-primary text-sm font-bold text-white shadow-md shadow-primary/25 transition-all hover:-translate-y-0.5 hover:bg-rose-700 hover:shadow-lg active:translate-y-0">
Masuk
<svg class="h-4 w-4 transition-transform group-hover:translate-x-1" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>
</button>
</form>
<div class="mt-4 text-center text-xs text-muted-foreground">
Belum punya akun? <a href="register.php" class="font-semibold text-primary hover:underline">Daftar sekarang</a>
</div>
<?php if ($show_demo === 1): ?>
<!-- Inline Demo Accounts -->
<div class="mt-5 flex items-center justify-center gap-2 text-xs">
<span class="font-medium text-muted-foreground">Isi Cepat Demo:</span>
<button type="button" onclick="fillDemo('admin', 'password')" class="rounded bg-rose-100 px-2 py-1 font-semibold text-rose-700 transition hover:bg-rose-200">👑 Admin</button>
<button type="button" onclick="fillDemo('petugas', 'password')" class="rounded bg-slate-100 px-2 py-1 font-semibold text-slate-700 transition hover:bg-slate-200">📝 Petugas</button>
<button type="button" onclick="fillDemo('guest', 'password')" class="rounded bg-slate-100 px-2 py-1 font-semibold text-slate-700 transition hover:bg-slate-200">👁️ Guest</button>
</div>
<?php endif; ?>
<p class="mt-8 text-center text-[10px] text-muted-foreground uppercase tracking-wider">
&copy; <script>document.write(new Date().getFullYear())</script> Kementerian Analisis Spasial
</p>
</div>
</div>
</main>
<script>
// Toggle Password Visibility
const toggleBtn = document.getElementById('togglePassword');
const passInput = document.getElementById('password');
const eyeIcon = document.getElementById('eyeIcon');
if (toggleBtn && passInput) {
toggleBtn.addEventListener('click', function() {
if (passInput.type === 'password') {
passInput.type = 'text';
eyeIcon.innerHTML = '<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line>';
} else {
passInput.type = 'password';
eyeIcon.innerHTML = '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle>';
}
});
}
function fillDemo(user, pass) {
document.getElementById('username').value = user;
document.getElementById('password').value = pass;
}
</script>
</body>
</html>