db->fetchOne(" SELECT (SELECT COUNT(*) FROM warga_miskin WHERE status = 'aktif') as total_warga, (SELECT COUNT(*) FROM rumah_ibadah WHERE is_active = 1) as total_ri, (SELECT COUNT(*) FROM laporan_masyarakat) as total_laporan, (SELECT COUNT(*) FROM histori_bantuan WHERE status = 'disalurkan') as total_bantuan, (SELECT COUNT(*) FROM warga_miskin WHERE is_blind_spot = 1) as total_blind_spot "); $this->view('public.beranda', ['title' => 'SINERGI - Sistem GIS Penanganan Kemiskinan', 'stats' => $stats], 'public'); } public function tentang(): void { $this->view('public.tentang', ['title' => 'Tentang Sistem - SINERGI'], 'public'); } public function kontak(): void { $this->view('public.kontak', ['title' => 'Kontak - SINERGI'], 'public'); } public function lapor(): void { $kecamatan = $this->db->fetchAll("SELECT * FROM kecamatan ORDER BY nama"); $this->view('public.lapor', [ 'title' => 'Lapor Cepat - SINERGI', 'kecamatan' => $kecamatan ], 'public'); } public function kirimLaporan(): void { if (!$this->verifyCsrf()) { $this->flash('error', 'Token tidak valid.'); $this->redirect(APP_URL . '/lapor'); } $namaWarga = trim($_POST['nama_warga'] ?? ''); $namaPelapor = trim($_POST['nama_pelapor'] ?? ''); $noHp = trim($_POST['no_hp_pelapor'] ?? ''); $alamat = trim($_POST['alamat_warga'] ?? ''); $idKelurahan = (int)($_POST['id_kelurahan'] ?? 0); $lat = (float)($_POST['lat'] ?? 0); $lng = (float)($_POST['lng'] ?? 0); $deskripsi = trim($_POST['deskripsi'] ?? ''); if (!$namaWarga || !$namaPelapor || !$alamat || !$idKelurahan || !$lat || !$lng) { $this->flash('error', 'Mohon lengkapi semua data yang wajib diisi.'); $this->redirect(APP_URL . '/lapor'); } $foto = null; if (!empty($_FILES['foto']['name'])) { $foto = $this->uploadFile($_FILES['foto'], 'laporan'); } $kode = generateKodeLaporan(); $this->db->insert('laporan_masyarakat', [ 'kode_laporan' => $kode, 'nama_pelapor' => $namaPelapor, 'no_hp_pelapor' => $noHp, 'nama_warga' => $namaWarga, 'alamat_warga' => $alamat, 'id_kelurahan' => $idKelurahan, 'lat' => $lat, 'lng' => $lng, 'deskripsi' => $deskripsi, 'foto' => $foto, 'status' => 'menunggu' ]); $this->flash('success', 'Laporan berhasil dikirim! Simpan kode laporan Anda.', ['kode_laporan' => $kode]); $this->redirect(APP_URL . '/lapor'); } public function cekLaporan(): void { $this->view('public.cek_laporan', ['title' => 'Cek Status Laporan - SINERGI'], 'public'); } public function proseCekLaporan(): void { $kode = strtoupper(trim($_POST['kode_laporan'] ?? '')); $laporan = null; if ($kode) { $laporan = $this->db->fetchOne( "SELECT l.*, k.nama as kelurahan, kec.nama as kecamatan FROM laporan_masyarakat l JOIN kelurahan k ON l.id_kelurahan = k.id JOIN kecamatan kec ON k.id_kecamatan = kec.id WHERE l.kode_laporan = ?", [$kode] ); } $this->view('public.cek_laporan', [ 'title' => 'Cek Status Laporan - SINERGI', 'laporan' => $laporan, 'kode' => $kode ], 'public'); } // API: Ambil kelurahan berdasarkan kecamatan public function apiKelurahan(int $id): void { $data = $this->db->fetchAll("SELECT id, nama FROM kelurahan WHERE id_kecamatan = ? ORDER BY nama", [$id]); $this->json($data); } // API: Data rumah ibadah untuk peta publik public function apiRumahIbadah(): void { $data = $this->db->fetchAll( "SELECT ri.id, ri.nama, ri.lat, ri.lng, ri.radius_meter, ri.alamat, ji.nama as jenis, k.nama as kelurahan FROM rumah_ibadah ri JOIN jenis_rumah_ibadah ji ON ri.id_jenis = ji.id JOIN kelurahan k ON ri.id_kelurahan = k.id WHERE ri.is_active = 1" ); $this->json($data); } // API: Data warga untuk peta publik (tanpa data sensitif) public function apiWargaPeta(): void { $data = $this->db->fetchAll( "SELECT w.lat, w.lng, w.status_kemiskinan, w.level_prioritas, w.is_blind_spot, k.nama as kelurahan, kec.nama as kecamatan FROM warga_miskin w JOIN kelurahan k ON w.id_kelurahan = k.id JOIN kecamatan kec ON k.id_kecamatan = kec.id WHERE w.status = 'aktif'" ); $this->json($data); } }