Upload files to "/"

This commit is contained in:
2026-06-02 03:13:12 +00:00
parent 123425bf39
commit 9763625d13
+310
View File
@@ -0,0 +1,310 @@
<?php
session_start();
require_once __DIR__ . '/config/database.php';
$error = '';
$success = '';
$allowedRoles = ['masyarakat', 'rumah_ibadah', 'relawan'];
if (isset($_SESSION['user'])) {
header('Location: dashboard.php');
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$nama = trim($_POST['nama'] ?? '');
$email = strtolower(trim($_POST['email'] ?? ''));
$password = trim($_POST['password'] ?? '');
$passwordConfirm = trim($_POST['password_confirm'] ?? '');
$role = trim($_POST['role'] ?? 'masyarakat');
$kontak = trim($_POST['kontak'] ?? '');
$alamat = trim($_POST['alamat'] ?? '');
$namaInstansi = trim($_POST['nama_instansi'] ?? '');
$kategoriInstansi = trim($_POST['kategori_instansi'] ?? '');
$catatanPengajuan = trim($_POST['catatan_pengajuan'] ?? '');
$lat = trim($_POST['lat'] ?? '');
$lng = trim($_POST['lng'] ?? '');
if ($nama === '' || $email === '' || $password === '' || $passwordConfirm === '') {
$error = 'Nama, email, dan password wajib diisi.';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Format email tidak valid.';
} elseif (!in_array($role, $allowedRoles, true)) {
$error = 'Jenis akun tidak valid.';
} elseif (strlen($password) < 6) {
$error = 'Password minimal 6 karakter.';
} elseif ($password !== $passwordConfirm) {
$error = 'Konfirmasi password tidak sama.';
} elseif ($role === 'rumah_ibadah' && ($namaInstansi === '' || $kategoriInstansi === '' || $alamat === '' || $kontak === '')) {
$error = 'Untuk akun rumah ibadah, lengkapi nama rumah ibadah, kategori, alamat, dan kontak.';
} elseif ($role === 'rumah_ibadah' && ($lat === '' || $lng === '')) {
$error = 'Pilih titik lokasi rumah ibadah melalui peta, pencarian alamat, atau tombol gunakan lokasi saat ini.';
} elseif ($role === 'relawan' && ($kontak === '' || $alamat === '')) {
$error = 'Untuk akun relawan, nomor kontak dan wilayah/alamat domisili wajib diisi.';
} elseif (($lat !== '' && !is_numeric($lat)) || ($lng !== '' && !is_numeric($lng))) {
$error = 'Titik lokasi tidak valid. Silakan pilih ulang lokasi melalui peta.';
} else {
$stmt = $pdo->prepare('SELECT id FROM users WHERE email = ? LIMIT 1');
$stmt->execute([$email]);
$exists = $stmt->fetch();
if ($exists) {
$error = 'Email sudah terdaftar. Silakan gunakan email lain atau masuk dengan akun tersebut.';
} else {
$hash = password_hash($password, PASSWORD_DEFAULT);
$statusAkun = $role === 'masyarakat' ? 'Aktif' : 'Menunggu Verifikasi';
$kategoriFinal = $role === 'rumah_ibadah' ? $kategoriInstansi : null;
$namaInstansiFinal = $role === 'rumah_ibadah' ? $namaInstansi : ($role === 'relawan' ? 'Relawan Masyarakat' : null);
$stmt = $pdo->prepare('INSERT INTO users
(nama, email, password_hash, role, rumah_ibadah_id, status_akun, kontak, alamat, nama_instansi, kategori_instansi, catatan_pengajuan, lat, lng)
VALUES (?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?)');
$stmt->execute([
$nama,
$email,
$hash,
$role,
$statusAkun,
$kontak !== '' ? $kontak : null,
$alamat !== '' ? $alamat : null,
$namaInstansiFinal,
$kategoriFinal,
$catatanPengajuan !== '' ? $catatanPengajuan : null,
$lat !== '' ? $lat : null,
$lng !== '' ? $lng : null,
]);
$newUserId = (int)$pdo->lastInsertId();
if ($role === 'masyarakat') {
$_SESSION['user'] = [
'id' => $newUserId,
'nama' => $nama,
'email' => $email,
'role' => 'masyarakat',
'rumah_ibadah_id' => null,
'status_akun' => 'Aktif',
];
header('Location: dashboard.php');
exit;
}
$success = 'Pendaftaran berhasil dikirim. Akun kamu akan bisa digunakan setelah diverifikasi oleh administrator.';
$_POST = [];
}
}
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Daftar Akun - SIPANTAS</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="stylesheet" href="assets/css/landing.css">
<link rel="stylesheet" href="assets/css/responsive-fix.css">
</head>
<body class="login-page">
<main class="login-card register-card register-card-wide">
<div class="brand-badge">SIPANTAS</div>
<h1>Daftar Akun</h1>
<p>Pilih jenis akun. Akun resmi akan diperiksa sebelum aktif.</p>
<a class="login-back" href="index.php">← Kembali ke beranda</a>
<?php if ($error): ?>
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
<?php endif; ?>
<form method="POST" autocomplete="on">
<label>Jenis Akun</label>
<select name="role" id="registerRole" class="role-select-hidden" required>
<option value="masyarakat" <?= (($_POST['role'] ?? '') === 'masyarakat') ? 'selected' : '' ?>>Masyarakat</option>
<option value="rumah_ibadah" <?= (($_POST['role'] ?? '') === 'rumah_ibadah') ? 'selected' : '' ?>>Pengurus Rumah Ibadah</option>
<option value="relawan" <?= (($_POST['role'] ?? '') === 'relawan') ? 'selected' : '' ?>>Relawan Lapangan</option>
</select>
<div class="role-picker" aria-label="Pilih jenis akun">
<button type="button" class="role-card-option" data-role="masyarakat"><b>Masyarakat</b><span>Kirim usulan.</span></button>
<button type="button" class="role-card-option" data-role="rumah_ibadah"><b>Rumah Ibadah</b><span>Kelola layanan.</span></button>
<button type="button" class="role-card-option" data-role="relawan"><b>Relawan</b><span>Bantu validasi.</span></button>
</div>
<div class="info-box small-note" id="roleHint"></div>
<label>Nama Lengkap</label>
<input type="text" name="nama" placeholder="Masukkan nama lengkap" value="<?= htmlspecialchars($_POST['nama'] ?? '') ?>" required>
<label>Email</label>
<input type="email" name="email" placeholder="nama@email.com" value="<?= htmlspecialchars($_POST['email'] ?? '') ?>" required>
<div class="role-extra role-rumah-ibadah">
<label>Nama Rumah Ibadah</label>
<input type="text" name="nama_instansi" placeholder="Contoh: Masjid Al-Ikhlas" value="<?= htmlspecialchars($_POST['nama_instansi'] ?? '') ?>">
<label>Kategori Rumah Ibadah</label>
<select name="kategori_instansi">
<?php foreach (['Masjid','Gereja','Vihara','Klenteng','Pura','Lainnya'] as $kategori): ?>
<option value="<?= $kategori ?>" <?= (($_POST['kategori_instansi'] ?? '') === $kategori) ? 'selected' : '' ?>><?= $kategori ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="role-extra role-official">
<label>Nomor Kontak</label>
<input type="text" name="kontak" placeholder="Nomor HP/WhatsApp aktif" value="<?= htmlspecialchars($_POST['kontak'] ?? '') ?>">
<label id="alamatLabel">Alamat / Wilayah</label>
<textarea name="alamat" id="registerAlamat" placeholder="Masukkan alamat atau wilayah tugas"><?= htmlspecialchars($_POST['alamat'] ?? '') ?></textarea>
</div>
<div class="role-extra role-rumah-ibadah location-picker-box">
<label>Titik Lokasi Rumah Ibadah</label>
<div class="location-search-row">
<input type="text" id="registerAddressSearch" placeholder="Cari alamat/nama jalan, lalu klik Cari">
<button class="btn btn-secondary" type="button" id="btnSearchRegisterAddress">Cari</button>
</div>
<div id="registerMap" class="register-map"></div>
<div class="selected-location-text" id="registerLocationText">Belum ada titik dipilih.</div>
<button class="btn btn-secondary" type="button" id="btnRegisterLocation">Gunakan Lokasi Saat Ini</button>
<input type="hidden" name="lat" id="registerLat" value="<?= htmlspecialchars($_POST['lat'] ?? '') ?>">
<input type="hidden" name="lng" id="registerLng" value="<?= htmlspecialchars($_POST['lng'] ?? '') ?>">
</div>
<div class="role-extra role-official">
<label>Catatan Pengajuan</label>
<textarea name="catatan_pengajuan" placeholder="Contoh: pengurus bidang sosial / relawan kelurahan"><?= htmlspecialchars($_POST['catatan_pengajuan'] ?? '') ?></textarea>
</div>
<label>Password</label>
<input type="password" name="password" placeholder="Minimal 6 karakter" minlength="6" required>
<label>Konfirmasi Password</label>
<input type="password" name="password_confirm" placeholder="Ulangi password" minlength="6" required>
<button class="btn btn-primary" type="submit">Daftar</button>
</form>
<p class="auth-switch">Sudah punya akun? <a href="login.php">Masuk di sini</a>.</p>
</main>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
const roleSelect = document.getElementById('registerRole');
const roleHint = document.getElementById('roleHint');
const alamatLabel = document.getElementById('alamatLabel');
let registerMap = null;
let registerMarker = null;
function ensureRegisterMap() {
if (registerMap) {
setTimeout(() => registerMap.invalidateSize(), 120);
return;
}
registerMap = L.map('registerMap', { zoomControl: true }).setView([-0.0263, 109.3425], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; OpenStreetMap'
}).addTo(registerMap);
registerMap.on('click', e => setRegisterPoint(e.latlng.lat, e.latlng.lng, true));
setTimeout(() => registerMap.invalidateSize(), 180);
const savedLat = document.getElementById('registerLat').value;
const savedLng = document.getElementById('registerLng').value;
if (savedLat && savedLng) setRegisterPoint(savedLat, savedLng, false);
}
function setRegisterPoint(lat, lng, shouldReverse) {
lat = Number(lat);
lng = Number(lng);
document.getElementById('registerLat').value = lat.toFixed(7);
document.getElementById('registerLng').value = lng.toFixed(7);
document.getElementById('registerLocationText').textContent = `Titik terpilih: ${lat.toFixed(6)}, ${lng.toFixed(6)}`;
if (registerMarker) registerMap.removeLayer(registerMarker);
registerMarker = L.marker([lat, lng]).addTo(registerMap).bindPopup('Lokasi rumah ibadah').openPopup();
registerMap.setView([lat, lng], 16);
if (shouldReverse) fillRegisterAddress(lat, lng);
}
async function fillRegisterAddress(lat, lng) {
try {
const res = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`);
const data = await res.json();
if (data.display_name) document.getElementById('registerAlamat').value = data.display_name;
} catch (e) {}
}
async function searchRegisterAddress() {
const query = document.getElementById('registerAddressSearch').value.trim() || document.getElementById('registerAlamat').value.trim();
if (!query) return alert('Masukkan alamat yang ingin dicari.');
try {
const res = await fetch(`https://nominatim.openstreetmap.org/search?format=json&limit=1&q=${encodeURIComponent(query)}`);
const data = await res.json();
if (!data.length) return alert('Alamat tidak ditemukan. Coba cari dengan nama jalan/kecamatan yang lebih jelas.');
setRegisterPoint(data[0].lat, data[0].lon, false);
document.getElementById('registerAlamat').value = data[0].display_name || query;
} catch (e) {
alert('Pencarian alamat gagal. Coba pilih titik langsung pada peta.');
}
}
function updateRoleFields() {
const role = roleSelect.value;
document.querySelectorAll('.role-card-option').forEach(btn => btn.classList.toggle('active', btn.dataset.role === role));
document.querySelectorAll('.role-extra').forEach(el => el.style.display = 'none');
document.querySelectorAll('.role-extra input, .role-extra textarea, .role-extra select').forEach(el => el.required = false);
if (role === 'masyarakat') {
roleHint.textContent = 'Akun masyarakat dapat langsung digunakan untuk mengirim usulan.';
}
if (role === 'rumah_ibadah') {
roleHint.textContent = 'Pilih lokasi lewat peta atau pencarian alamat. Tidak perlu mengetik koordinat manual.';
document.querySelectorAll('.role-rumah-ibadah, .role-official').forEach(el => el.style.display = 'block');
document.querySelectorAll('input[name="nama_instansi"], select[name="kategori_instansi"], input[name="kontak"], textarea[name="alamat"]').forEach(el => el.required = true);
alamatLabel.textContent = 'Alamat Rumah Ibadah';
ensureRegisterMap();
}
if (role === 'relawan') {
roleHint.textContent = 'Akun relawan akan diperiksa sebelum bisa membantu validasi lapangan.';
document.querySelectorAll('.role-official').forEach(el => el.style.display = 'block');
document.querySelectorAll('input[name="kontak"], textarea[name="alamat"]').forEach(el => el.required = true);
alamatLabel.textContent = 'Wilayah / Domisili Relawan';
}
}
document.querySelectorAll('.role-card-option').forEach(btn => {
btn.addEventListener('click', () => {
roleSelect.value = btn.dataset.role;
updateRoleFields();
});
});
roleSelect.addEventListener('change', updateRoleFields);
updateRoleFields();
document.getElementById('btnSearchRegisterAddress')?.addEventListener('click', searchRegisterAddress);
document.getElementById('registerAddressSearch')?.addEventListener('keydown', e => {
if (e.key === 'Enter') {
e.preventDefault();
searchRegisterAddress();
}
});
document.getElementById('btnRegisterLocation')?.addEventListener('click', () => {
if (!navigator.geolocation) {
alert('Browser tidak mendukung fitur lokasi. Pilih titik langsung pada peta.');
return;
}
navigator.geolocation.getCurrentPosition(
pos => setRegisterPoint(pos.coords.latitude, pos.coords.longitude, true),
() => alert('Gagal mengambil lokasi. Izinkan akses lokasi atau pilih titik pada peta.')
);
});
</script>
</body>
</html>