Files
webgis_geospesial/register.php
T
2026-06-11 13:17:31 +07:00

309 lines
17 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';
// Konfigurasi Google OAuth (DUMMY/HARUS DIISI OLEH USER)
define('GOOGLE_CLIENT_ID', '575444350307-likfkam3fkppn8rjl8044uppdm4ovf35.apps.googleusercontent.com');
define('GOOGLE_CLIENT_SECRET', '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');
define('GOOGLE_REDIRECT_URI', 'http://localhost/webgis/register.php');
$sweetAlertScript = '';
// Proses Google OAuth Callback
if (isset($_GET['code'])) {
$code = $_GET['code'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://oauth2.googleapis.com/token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'client_id' => GOOGLE_CLIENT_ID,
'client_secret' => GOOGLE_CLIENT_SECRET,
'redirect_uri' => GOOGLE_REDIRECT_URI,
'grant_type' => 'authorization_code',
'code' => $code
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$token_data = json_decode($response, true);
if (isset($token_data['access_token'])) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.googleapis.com/oauth2/v3/userinfo");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . $token_data['access_token']]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$user_data = json_decode(curl_exec($ch), true);
curl_close($ch);
if (isset($user_data['email'])) {
$email = $user_data['email'];
$name = $user_data['name'];
$state_role = $_GET['state'] ?? 'guest';
$role = in_array($state_role, ['guest', 'petugas']) ? $state_role : 'guest';
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? OR username = ?");
$stmt->execute([$email, $email]);
$existing_user = $stmt->fetch();
if ($existing_user) {
if ($existing_user['status'] === 'pending') {
$sweetAlertScript = "Swal.fire({icon: 'warning', title: 'Menunggu Persetujuan', text: 'Akun Anda sedang menunggu persetujuan Admin.', confirmButtonColor: '#e11d48'});";
} else {
$_SESSION['user_id'] = $existing_user['id'];
$_SESSION['username'] = $existing_user['username'];
$_SESSION['role'] = $existing_user['role'];
header('Location: dashboard.php');
exit;
}
} else {
$status = ($role === 'petugas') ? 'pending' : 'active';
$username = explode('@', $email)[0] . rand(100,999);
$stmt = $pdo->prepare("INSERT INTO users (username, email, nama_lengkap, password, role, status, auth_provider) VALUES (?, ?, ?, ?, ?, ?, 'google')");
$stmt->execute([$username, $email, $name, password_hash(bin2hex(random_bytes(8)), PASSWORD_DEFAULT), $role, $status]);
if ($role === 'petugas') {
$sweetAlertScript = "Swal.fire({icon: 'success', title: 'Pendaftaran Berhasil', text: 'Pendaftaran via Google berhasil. Akun Anda menunggu persetujuan Admin.', confirmButtonColor: '#e11d48'}).then(() => { window.location.href = 'login.php'; });";
} else {
$_SESSION['user_id'] = $pdo->lastInsertId();
$_SESSION['username'] = $username;
$_SESSION['role'] = 'guest';
header('Location: dashboard.php');
exit;
}
}
}
} else {
$sweetAlertScript = "Swal.fire({icon: 'error', title: 'Google Login Gagal', text: 'Terjadi kesalahan kredensial OAuth.', confirmButtonColor: '#e11d48'});";
}
}
// Proses Registrasi Lokal
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['register'])) {
$nama_lengkap = trim($_POST['nama_lengkap'] ?? '');
$email = trim($_POST['email'] ?? '');
$password = trim($_POST['password'] ?? '');
$role = trim($_POST['role'] ?? 'guest');
if ($nama_lengkap && $email && $password && in_array($role, ['guest', 'petugas'])) {
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = ? OR username = ?");
$stmt->execute([$email, $email]);
if ($stmt->fetch()) {
$sweetAlertScript = "Swal.fire({icon: 'error', title: 'Registrasi Gagal', text: 'Email tersebut sudah terdaftar.', confirmButtonColor: '#e11d48'});";
} else {
$status = ($role === 'petugas') ? 'pending' : 'active';
$username = explode('@', $email)[0] . rand(100,999);
$stmt = $pdo->prepare("INSERT INTO users (username, email, nama_lengkap, password, role, status, auth_provider) VALUES (?, ?, ?, ?, ?, ?, 'local')");
if ($stmt->execute([$username, $email, $nama_lengkap, password_hash($password, PASSWORD_DEFAULT), $role, $status])) {
if ($role === 'petugas') {
$sweetAlertScript = "Swal.fire({icon: 'success', title: 'Pendaftaran Berhasil', text: 'Pendaftaran berhasil. Menunggu persetujuan Admin.', confirmButtonColor: '#e11d48'}).then(() => { window.location.href = 'login.php'; });";
} else {
$sweetAlertScript = "Swal.fire({icon: 'success', title: 'Pendaftaran Berhasil', text: 'Akun Anda aktif, silakan masuk ke sistem.', confirmButtonColor: '#e11d48'}).then(() => { window.location.href = 'login.php'; });";
}
} else {
$sweetAlertScript = "Swal.fire({icon: 'error', title: 'Gagal', text: 'Terjadi kesalahan sistem internal.', confirmButtonColor: '#e11d48'});";
}
}
} else {
$sweetAlertScript = "Swal.fire({icon: 'warning', title: 'Data Belum Lengkap', text: 'Harap lengkapi semua bidang yang tersedia.', confirmButtonColor: '#e11d48'});";
}
}
// URL OAuth Google
$google_auth_url = "https://accounts.google.com/o/oauth2/v2/auth?client_id=" . GOOGLE_CLIENT_ID . "&redirect_uri=" . urlencode(GOOGLE_REDIRECT_URI) . "&response_type=code&scope=email%20profile";
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register 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',
}
}
}
}
</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; }
::-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 ($sweetAlertScript): ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
<?= $sweetAlertScript ?>
});
</script>
<?php endif; ?>
<main class="flex h-screen w-full overflow-hidden bg-background font-sans text-foreground">
<!-- Left: hero / map -->
<section class="relative hidden w-1/2 overflow-hidden lg:block">
<img src="assets/img/map-bg.png" alt="Visualisasi peta" 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/85 via-red-800/80 to-rose-900/90"></div>
<div aria-hidden="true" class="absolute inset-0 opacity-[0.06]" style="background-image: linear-gradient(to right, white 1px, transparent 1px), linear-gradient(to bottom, white 1px, transparent 1px); background-size: 52px 52px;"></div>
<div class="relative z-10 flex h-full flex-col justify-between p-12 xl:p-16">
<div class="flex items-center gap-2.5">
<div class="flex h-9 w-9 items-center justify-center rounded-xl bg-white/15 backdrop-blur-sm ring-1 ring-white/25">
<svg viewBox="0 0 24 24" fill="none" class="h-5 w-5 text-white" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<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>
<div>
<h1 class="font-heading text-sm font-bold tracking-wide text-white shadow-sm">WebGIS Geospasial</h1>
<p class="text-[11px] font-medium text-white/70 uppercase tracking-wider">Kementerian Analisis Spasial</p>
</div>
</div>
<div>
<h2 class="font-heading text-4xl font-bold leading-tight tracking-tight text-white xl:text-5xl">
Bergabung Bersama <br> Komunitas <span class="text-rose-200">Spasial</span>
</h2>
<p class="mt-4 max-w-md leading-relaxed text-rose-100/90 text-sm xl:text-base">
Jadilah bagian dari inisiatif digital pemetaan wilayah, dan ikut serta dalam evaluasi kemiskinan berbasis data geospasial.
</p>
</div>
</div>
</section>
<!-- Right: Register Form -->
<section class="flex w-full lg:w-1/2 h-full overflow-y-auto p-6">
<div class="w-full max-w-sm sm:max-w-md m-auto">
<!-- Header -->
<div class="mb-8 mt-10 lg:mt-0">
<h2 class="font-heading text-2xl font-bold tracking-tight text-foreground sm:text-3xl">Buat Akun Baru</h2>
<p class="mt-2 text-sm text-muted-foreground">Isi data di bawah ini untuk membuat akun WebGIS Anda.</p>
</div>
<!-- Card -->
<div class="rounded-2xl border border-white/60 bg-white/70 p-6 shadow-[0_8px_30px_rgb(0,0,0,0.04)] backdrop-blur-xl sm:p-8">
<!-- Google Auth Button -->
<button type="button" onclick="startGoogleAuth()" class="flex h-11 w-full items-center justify-center gap-3 rounded-xl border border-border bg-white text-sm font-semibold text-foreground shadow-sm hover:bg-gray-50 transition-colors mb-6">
<svg width="20" height="20" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" fill="#4285F4"/>
<path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/>
<path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/>
<path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/>
</svg>
Daftar dengan Google
</button>
<div class="relative flex items-center mb-6">
<div class="flex-grow border-t border-border"></div>
<span class="flex-shrink-0 mx-4 text-xs text-muted-foreground uppercase tracking-wider font-semibold">atau dengan email</span>
<div class="flex-grow border-t border-border"></div>
</div>
<form action="register.php" method="POST" class="flex flex-col gap-4">
<input type="hidden" name="register" value="1">
<!-- Input Nama -->
<div class="group">
<label for="nama_lengkap" class="mb-1.5 block text-sm font-semibold text-foreground group-focus-within:text-primary transition-colors">
Nama Lengkap
</label>
<div class="relative">
<input type="text" id="nama_lengkap" name="nama_lengkap" class="block w-full rounded-xl border border-border bg-white py-2.5 px-3 text-sm text-foreground transition-all focus:outline-none focus-visible:border-primary focus-visible:ring-4 focus-visible:ring-primary/20 hover:border-primary/60" placeholder="John Doe" required>
</div>
</div>
<!-- Input Email -->
<div class="group">
<label for="email" class="mb-1.5 block text-sm font-semibold text-foreground group-focus-within:text-primary transition-colors">
Alamat Email
</label>
<div class="relative">
<input type="email" id="email" name="email" class="block w-full rounded-xl border border-border bg-white py-2.5 px-3 text-sm text-foreground transition-all focus:outline-none focus-visible:border-primary focus-visible:ring-4 focus-visible:ring-primary/20 hover:border-primary/60" placeholder="john@example.com" required>
</div>
</div>
<!-- Input Password -->
<div class="group">
<label for="password" class="mb-1.5 block text-sm font-semibold text-foreground group-focus-within:text-primary transition-colors">
Kata Sandi
</label>
<div class="relative">
<input type="password" id="password" name="password" class="block w-full rounded-xl border border-border bg-white py-2.5 px-3 pr-10 text-sm text-foreground transition-all focus:outline-none focus-visible:border-primary focus-visible:ring-4 focus-visible:ring-primary/20 hover:border-primary/60" placeholder="••••••••" required>
</div>
</div>
<!-- Input Role -->
<div class="group">
<label for="role" class="mb-1.5 block text-sm font-semibold text-foreground group-focus-within:text-primary transition-colors">
Daftar Sebagai
</label>
<div class="relative">
<select id="role" name="role" class="block w-full rounded-xl border border-border bg-white py-2.5 px-3 text-sm text-foreground transition-all focus:outline-none focus-visible:border-primary focus-visible:ring-4 focus-visible:ring-primary/20 hover:border-primary/60 appearance-none" required>
<option value="guest">Guest (Pengunjung Umum)</option>
<option value="petugas">Petugas (Verifikator Lapangan)</option>
</select>
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-3 text-muted-foreground">
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
</div>
</div>
</div>
<!-- Submit -->
<button type="submit" class="group mt-3 flex h-12 items-center justify-center gap-2 rounded-xl bg-primary text-sm font-semibold text-white shadow-lg shadow-primary/25 transition-all duration-300 hover:-translate-y-0.5 hover:bg-rose-700 hover:shadow-xl hover:shadow-primary/35 active:translate-y-0">
Daftar Sekarang
</button>
</form>
<div class="mt-6 text-center text-sm text-muted-foreground">
Sudah punya akun? <a href="login.php" class="font-semibold text-primary hover:underline">Masuk di sini</a>
</div>
</div>
<p class="mt-6 text-center text-xs text-muted-foreground">
&copy; <script>document.write(new Date().getFullYear())</script> WebGIS Geospasial &middot; Kementerian Analisis Spasial
</p>
</div>
</section>
</main>
<script>
function startGoogleAuth() {
const role = document.getElementById('role').value;
window.location.href = "<?= $google_auth_url ?>" + "&state=" + encodeURIComponent(role);
}
</script>
</body>
</html>