Files
webgis_geospesial/kemiskinan/login.php
T

261 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 / Features Info -->
<div class="mt-8">
<h2 class="mb-4 flex items-center gap-2 text-sm font-bold text-white/90 uppercase tracking-wider">
<svg viewBox="0 0 24 24" fill="none" class="h-5 w-5 text-rose-300" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
</svg>
Sistem Pengamanan Tertutup
</h2>
<div class="flex flex-col gap-4 text-white/80 text-sm">
<div class="flex items-start gap-3">
<div class="mt-0.5 rounded-full bg-white/20 p-1"><svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"></path></svg></div>
<p><strong>Database Terpusat:</strong> Melacak data penduduk miskin berdasarkan NIK secara real-time.</p>
</div>
<div class="flex items-start gap-3">
<div class="mt-0.5 rounded-full bg-white/20 p-1"><svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"></path></svg></div>
<p><strong>Tracking Bantuan:</strong> Verifikasi silang penyaluran BLT dan PKH di berbagai wilayah.</p>
</div>
<div class="flex items-start gap-3">
<div class="mt-0.5 rounded-full bg-white/20 p-1"><svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"></path></svg></div>
<p><strong>Analisis Spasial:</strong> Pemetaan kantong kemiskinan untuk kebijakan tepat sasaran.</p>
</div>
</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="contoh@email.com atau username" 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>
<!-- Akun demo telah dinonaktifkan -->
<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>