query("SELECT COUNT(*) c FROM penduduk")->fetch_assoc()['c']; $ibadah = $conn->query("SELECT COUNT(*) c FROM rumah_ibadah")->fetch_assoc()['c']; $bantuan = $conn->query("SELECT COUNT(*) c FROM bantuan")->fetch_assoc()['c']; jsonResponse(['kk'=>(int)$kk,'ibadah'=>(int)$ibadah,'bantuan'=>(int)$bantuan]); } // ── GET: cek sesi aktif ─────────────────────────────────── if ($method === 'GET' && $action === 'me') { if (!empty($_SESSION['user_id'])) { jsonResponse(['logged_in'=>true,'user'=>currentUser()]); } jsonResponse(['logged_in'=>false]); } // ── GET: logout ─────────────────────────────────────────── if ($method === 'GET' && $action === 'logout') { $_SESSION = []; session_destroy(); header('Location: ../login.php'); exit; } // ── GET: daftar pengurus pending (admin only) ───────────── if ($method === 'GET' && $action === 'pending_list') { requireLogin(['admin']); $res = $conn->query("SELECT id,nama_lengkap,username,no_hp,email,nama_ibadah,jenis_ibadah, latitude,longitude,alamat,kelurahan,kecamatan,radius,status,catatan_admin,created_at FROM pengurus_pending ORDER BY created_at DESC"); $data = []; while ($r = $res->fetch_assoc()) $data[] = $r; jsonResponse($data); } // ── GET: daftar rumah ibadah tersedia untuk pendaftar ───── if ($method === 'GET' && $action === 'ibadah_list') { $res = $conn->query("SELECT id, nama, jenis, alamat, kelurahan, kecamatan FROM rumah_ibadah ORDER BY nama"); $data = []; while ($r = $res->fetch_assoc()) $data[] = $r; jsonResponse($data); } // ── POST: login ─────────────────────────────────────────── if ($method === 'POST' && ($action === '' || $action === 'login')) { $raw = file_get_contents('php://input'); $d = json_decode($raw, true); if (!$d) $d = $_POST; $username = trim($d['username'] ?? ''); $password = $d['password'] ?? ''; $roleReq = $d['role'] ?? ''; if (!$username || !$password) { jsonResponse(['success'=>false,'error'=>'Username dan kata sandi wajib diisi.'], 400); } $uname = $conn->real_escape_string($username); $row = $conn->query( "SELECT * FROM users WHERE (username='$uname' OR no_hp='$uname') AND is_active=1 LIMIT 1" )->fetch_assoc(); $validPassword = $row && password_verify($password, $row['password_hash']); if (!$validPassword && $row && hash_equals((string)$row['password_hash'], (string)$password)) { $validPassword = true; $newHash = $conn->real_escape_string(password_hash($password, PASSWORD_DEFAULT)); $conn->query("UPDATE users SET password_hash='$newHash' WHERE id=".(int)$row['id']); } if (!$row || !$validPassword) { jsonResponse(['success'=>false,'error'=>'Username atau kata sandi salah.'], 401); } // Validasi role jika dipilih if ($roleReq && $row['role'] !== 'admin' && $row['role'] !== $roleReq) { $roleLabel = ['masyarakat'=>'Masyarakat','pengurus_ibadah'=>'Pengurus Ibadah','pemerintah'=>'Pemerintah']; jsonResponse(['success'=>false,'error'=>'Akun ini bukan akun '.($roleLabel[$roleReq] ?? $roleReq).'. Pilih tab yang sesuai.'], 403); } // Set session session_regenerate_id(true); $_SESSION['user_id'] = $row['id']; $_SESSION['nama'] = $row['nama_lengkap']; $_SESSION['role'] = $row['role']; $_SESSION['id_rumah_ibadah'] = $row['id_rumah_ibadah']; $_SESSION['id_penduduk'] = $row['id_penduduk']; $_SESSION['login_time'] = time(); $uid = (int)$row['id']; $conn->query("UPDATE users SET last_login=NOW() WHERE id=$uid"); logAktivitas($conn,'login','users',$uid,'Login dari '.$_SERVER['REMOTE_ADDR']); $redirectMap = [ 'admin' => 'dashboard/pengurus.php', 'pengurus_ibadah' => 'dashboard/pengurus.php', 'masyarakat' => 'dashboard/masyarakat.php', 'pemerintah' => 'dashboard/pemerintah.php', ]; $redirect = $redirectMap[$row['role']] ?? 'index.php'; jsonResponse(['success'=>true,'role'=>$row['role'],'redirect'=>$redirect,'nama'=>$row['nama_lengkap']]); } // ── POST: register masyarakat ───────────────────────────── if ($method === 'POST' && $action === 'register') { $raw = file_get_contents('php://input'); $d = json_decode($raw, true); if (!$d) $d = $_POST; $nama = trim($d['nama_lengkap'] ?? ''); $username = trim($d['username'] ?? ''); $no_hp = trim($d['no_hp'] ?? ''); $email = trim($d['email'] ?? ''); $password = $d['password'] ?? ''; $no_kk = trim($d['no_kk'] ?? ''); if (!$nama) jsonResponse(['success'=>false,'error'=>'Nama lengkap wajib diisi.'], 400); if (!$username) jsonResponse(['success'=>false,'error'=>'Username wajib diisi.'], 400); if (!$no_hp) jsonResponse(['success'=>false,'error'=>'Nomor HP wajib diisi.'], 400); if (!$password) jsonResponse(['success'=>false,'error'=>'Kata sandi wajib diisi.'], 400); if (strlen($username) < 4) jsonResponse(['success'=>false,'error'=>'Username minimal 4 karakter.'], 400); if (strlen($password) < 6) jsonResponse(['success'=>false,'error'=>'Kata sandi minimal 6 karakter.'], 400); if (preg_match('/\s/', $username)) jsonResponse(['success'=>false,'error'=>'Username tidak boleh mengandung spasi.'], 400); $uname_e = $conn->real_escape_string($username); $hp_e = $conn->real_escape_string($no_hp); $cekUser = $conn->query("SELECT id FROM users WHERE username='$uname_e' LIMIT 1")->fetch_assoc(); if ($cekUser) jsonResponse(['success'=>false,'error'=>'Username sudah digunakan, coba username lain.'], 409); $cekHp = $conn->query("SELECT id FROM users WHERE no_hp='$hp_e' LIMIT 1")->fetch_assoc(); if ($cekHp) jsonResponse(['success'=>false,'error'=>'Nomor HP sudah terdaftar.'], 409); $hash = password_hash($password, PASSWORD_DEFAULT); $nama_e = $conn->real_escape_string($nama); $email_e = $conn->real_escape_string($email); $hash_e = $conn->real_escape_string($hash); $id_penduduk = 'NULL'; if ($no_kk) { $kk_e = $conn->real_escape_string($no_kk); $kk = $conn->query("SELECT id FROM penduduk WHERE no_kk='$kk_e' LIMIT 1")->fetch_assoc(); if ($kk) $id_penduduk = (int)$kk['id']; } $sql = "INSERT INTO users (nama_lengkap, username, no_hp, email, password_hash, role, id_penduduk) VALUES ('$nama_e', '$uname_e', '$hp_e', '$email_e', '$hash_e', 'masyarakat', $id_penduduk)"; if ($conn->query($sql)) { $newId = $conn->insert_id; logAktivitas($conn,'register','users',$newId,"Daftar baru: $username"); jsonResponse(['success'=>true,'message'=>'Akun berhasil dibuat. Silakan login dengan username dan kata sandi Anda.']); } else { jsonResponse(['success'=>false,'error'=>'Gagal membuat akun: '.$conn->error], 500); } } // ── POST: register pengurus ibadah (langsung aktif, tanpa pending) ──────── if ($method === 'POST' && $action === 'register_pengurus') { $raw = file_get_contents('php://input'); $d = json_decode($raw, true); if (!$d) $d = $_POST; // Validasi bidang akun $nama = trim($d['nama_lengkap'] ?? ''); $username = trim($d['username'] ?? ''); $no_hp = trim($d['no_hp'] ?? ''); $email = trim($d['email'] ?? ''); $password = $d['password'] ?? ''; // Validasi bidang rumah ibadah $nama_ibadah = trim($d['nama_ibadah'] ?? ''); $jenis = $d['jenis_ibadah'] ?? 'Masjid'; $lat = (float)($d['latitude'] ?? 0); $lon = (float)($d['longitude'] ?? 0); $alamat = trim($d['alamat'] ?? ''); $kelurahan = trim($d['kelurahan'] ?? ''); $kecamatan = trim($d['kecamatan'] ?? ''); $radius = max(50, min(2000, (int)($d['radius'] ?? 300))); // Cek wajib if (!$nama) jsonResponse(['success'=>false,'error'=>'Nama lengkap wajib diisi.'], 400); if (!$username) jsonResponse(['success'=>false,'error'=>'Username wajib diisi.'], 400); if (!$no_hp) jsonResponse(['success'=>false,'error'=>'Nomor HP wajib diisi.'], 400); if (!$password) jsonResponse(['success'=>false,'error'=>'Kata sandi wajib diisi.'], 400); if (!$nama_ibadah) jsonResponse(['success'=>false,'error'=>'Nama rumah ibadah wajib diisi.'], 400); if (!$lat || !$lon) jsonResponse(['success'=>false,'error'=>'Lokasi rumah ibadah wajib ditentukan.'], 400); if (strlen($username) < 4) jsonResponse(['success'=>false,'error'=>'Username minimal 4 karakter.'], 400); if (strlen($password) < 6) jsonResponse(['success'=>false,'error'=>'Kata sandi minimal 6 karakter.'], 400); if (preg_match('/\s/', $username)) jsonResponse(['success'=>false,'error'=>'Username tidak boleh mengandung spasi.'], 400); $valid_jenis = ['Masjid','Gereja','Vihara','Pura','Klenteng','Lainnya']; if (!in_array($jenis, $valid_jenis)) $jenis = 'Masjid'; $uname_e = $conn->real_escape_string($username); $hp_e = $conn->real_escape_string($no_hp); // Cek duplikat di users if ($conn->query("SELECT id FROM users WHERE username='$uname_e' LIMIT 1")->fetch_assoc()) jsonResponse(['success'=>false,'error'=>'Username sudah digunakan.'], 409); if ($conn->query("SELECT id FROM users WHERE no_hp='$hp_e' LIMIT 1")->fetch_assoc()) jsonResponse(['success'=>false,'error'=>'Nomor HP sudah terdaftar.'], 409); // Siapkan data $hash = password_hash($password, PASSWORD_DEFAULT); $nama_e = $conn->real_escape_string($nama); $email_e = $conn->real_escape_string($email); $hash_e = $conn->real_escape_string($hash); $nibd_e = $conn->real_escape_string($nama_ibadah); $jenis_e = $conn->real_escape_string($jenis); $alamat_e = $conn->real_escape_string($alamat); $kel_e = $conn->real_escape_string($kelurahan); $kec_e = $conn->real_escape_string($kecamatan); // Buat rumah ibadah dan akun pengguna dalam transaksi agar atomic $conn->begin_transaction(); $ok = $conn->query("INSERT INTO rumah_ibadah (nama,jenis,kontak,email,latitude,longitude,alamat,kelurahan,kecamatan,radius) VALUES ('$nibd_e','$jenis_e','$hp_e','$email_e',$lat,$lon,'$alamat_e','$kel_e','$kec_e',$radius)"); if (!$ok) { $conn->rollback(); jsonResponse(['success'=>false,'error'=>'Gagal membuat rumah ibadah: '.$conn->error], 500); } $ibadahId = $conn->insert_id; $ok = $conn->query("INSERT INTO users (nama_lengkap,username,no_hp,email,password_hash,role,id_rumah_ibadah,is_active) VALUES ('$nama_e','$uname_e','$hp_e','$email_e','$hash_e','pengurus_ibadah',$ibadahId,1)"); if (!$ok) { $conn->rollback(); jsonResponse(['success'=>false,'error'=>'Gagal membuat akun pengurus: '.$conn->error], 500); } $userId = $conn->insert_id; $conn->commit(); logAktivitas($conn,'register_pengurus','users',$userId,"Pengurus baru langsung aktif: $username, ibadah $ibadahId"); jsonResponse([ 'success' => true, 'message' => 'Pendaftaran berhasil. Akun pengurus dan rumah ibadah telah dibuat dan aktif.', 'user_id' => (int)$userId, 'ibadah_id' => (int)$ibadahId ]); } // ── PUT: approve / reject pengurus pending (admin) ──────── if ($method === 'PUT' && $action === 'approve_pengurus') { requireLogin(['admin']); $d = json_decode(file_get_contents('php://input'), true); $id = (int)($d['id'] ?? 0); $status = $d['status'] ?? ''; // 'approved' | 'rejected' $catatan = $conn->real_escape_string($d['catatan'] ?? ''); if (!$id || !in_array($status, ['approved','rejected'])) jsonResponse(['success'=>false,'error'=>'Parameter tidak valid.'], 400); $pending = $conn->query("SELECT * FROM pengurus_pending WHERE id=$id AND status='pending' LIMIT 1")->fetch_assoc(); if (!$pending) jsonResponse(['success'=>false,'error'=>'Data pendaftaran tidak ditemukan.'], 404); if ($status === 'approved') { // Buat rumah ibadah baru $ni = $conn->real_escape_string($pending['nama_ibadah']); $ji = $conn->real_escape_string($pending['jenis_ibadah']); $hp = $conn->real_escape_string($pending['no_hp']); $em = $conn->real_escape_string($pending['email']); $al = $conn->real_escape_string($pending['alamat']); $ke = $conn->real_escape_string($pending['kelurahan']); $kc = $conn->real_escape_string($pending['kecamatan']); $lat = (float)$pending['latitude']; $lon = (float)$pending['longitude']; $rad = (int)$pending['radius']; $conn->query("INSERT INTO rumah_ibadah (nama,jenis,kontak,email,latitude,longitude,alamat,kelurahan,kecamatan,radius) VALUES ('$ni','$ji','$hp','$em',$lat,$lon,'$al','$ke','$kc',$rad)"); $ibadahId = $conn->insert_id; // Buat user pengurus $un = $conn->real_escape_string($pending['username']); $nm = $conn->real_escape_string($pending['nama_lengkap']); $pw = $conn->real_escape_string($pending['password_hash']); $eme = $conn->real_escape_string($pending['email']); $hpe = $conn->real_escape_string($pending['no_hp']); $conn->query("INSERT INTO users (nama_lengkap,username,no_hp,email,password_hash,role,id_rumah_ibadah,is_active) VALUES ('$nm','$un','$hpe','$eme','$pw','pengurus_ibadah',$ibadahId,1)"); $userId = $conn->insert_id; logAktivitas($conn,'approve_pengurus','pengurus_pending',$id,"Approved → user $userId, ibadah $ibadahId"); } $conn->query("UPDATE pengurus_pending SET status='$status', catatan_admin='$catatan' WHERE id=$id"); jsonResponse([ 'success' => true, 'message' => $status === 'approved' ? 'Pendaftaran disetujui. Akun dan rumah ibadah berhasil dibuat.' : 'Pendaftaran ditolak.' ]); } // Fallback jsonResponse(['error'=>'Endpoint tidak valid'], 404); ?>