false, 'message' => 'Forbidden']); exit; } $stmtStats = $pdo->query(" SELECT status, COUNT(*) as jumlah FROM laporan_warga GROUP BY status "); $stats = []; while ($r = $stmtStats->fetch(PDO::FETCH_ASSOC)) { $stats[$r['status']] = (int)$r['jumlah']; } $stmtTotal = $pdo->query("SELECT COUNT(*) FROM laporan_warga"); echo json_encode(['success' => true, 'stats' => $stats, 'total' => (int)$stmtTotal->fetchColumn()]); exit; } // Filter berdasarkan role $where = []; $params = []; // Jika ada action=get_petugas if ($action === 'get_petugas') { if (!in_array($role, ['admin', 'petugas'])) { http_response_code(403); echo json_encode(['success' => false, 'message' => 'Forbidden']); exit; } $stmt = $pdo->query("SELECT username FROM users WHERE role = 'petugas' ORDER BY username ASC"); $petugas = $stmt->fetchAll(PDO::FETCH_COLUMN); echo json_encode(['success' => true, 'petugas' => $petugas]); exit; } if ($role === 'kontributor') { // Kontributor hanya lihat laporan milik sendiri $where[] = 'lw.pelapor_id = ?'; $params[] = $userId; } elseif ($role === 'koordinator') { // Koordinator lihat laporan dari wilayahnya + laporan milik sendiri $where[] = '(lw.pelapor_id = ? OR lw.koordinator_ibadah_id = ?)'; $params[] = $userId; $params[] = !empty($currentUser['rumah_ibadah_id']) ? (int)$currentUser['rumah_ibadah_id'] : 0; } elseif ($role === 'petugas') { // Petugas hanya lihat laporan yang ditugaskan ke mereka $where[] = 'lw.ditugaskan_ke = ?'; $params[] = $currentUser['username']; } // Admin: lihat semua // Filter status if (!empty($_GET['status'])) { $where[] = 'lw.status = ?'; $params[] = $_GET['status']; } // Filter prioritas if (!empty($_GET['prioritas'])) { $where[] = 'lw.prioritas = ?'; $params[] = $_GET['prioritas']; } $whereSql = $where ? 'WHERE ' . implode(' AND ', $where) : ''; $sql = " SELECT lw.*, rw.nama_kepala_keluarga, rw.kelurahan, rw.kecamatan, rw.kategori_kemiskinan, rw.status_bantuan, u.username AS pelapor_nama, u.role AS pelapor_role FROM laporan_warga lw JOIN rumah_warga rw ON rw.id = lw.rumah_warga_id JOIN users u ON u.id = lw.pelapor_id $whereSql ORDER BY lw.created_at DESC LIMIT 100 "; $stmt = $pdo->prepare($sql); $stmt->execute($params); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); // Summary counts for filter badges $stmtSummary = $pdo->query("SELECT status, COUNT(*) as n FROM laporan_warga GROUP BY status"); $summary = []; while ($r = $stmtSummary->fetch(PDO::FETCH_ASSOC)) { $summary[$r['status']] = (int)$r['n']; } $response = ['success' => true, 'data' => $data, 'summary' => $summary, 'total' => count($data)]; // Sertakan list petugas jika user admin if ($role === 'admin' || $role === 'petugas') { $stmtP = $pdo->query("SELECT username FROM users WHERE role = 'petugas' ORDER BY username ASC"); $response['petugas'] = $stmtP->fetchAll(PDO::FETCH_COLUMN); } echo json_encode($response); break; // ── POST: Buat laporan baru ────────────────────────────────────────── case 'POST': $currentUser = requireAuth(['koordinator', 'kontributor']); $input = json_decode(file_get_contents('php://input'), true) ?: $_POST; $rumahWargaId = (int)($input['rumah_warga_id'] ?? 0); $jenisLaporan = trim($input['jenis_laporan'] ?? ''); $deskripsi = trim($input['deskripsi'] ?? ''); // Penentuan prioritas otomatis berdasarkan jenis laporan $prioritasMap = [ 'warga_meninggal' => 'tinggi', 'warga_pindah' => 'tinggi', 'warga_mampu' => 'tinggi', 'data_ganda' => 'sedang', 'data_tidak_sesuai'=> 'sedang', 'lainnya' => 'rendah' ]; $prioritas = $prioritasMap[$jenisLaporan] ?? 'sedang'; if (!$rumahWargaId || !$jenisLaporan || !$deskripsi) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'Data tidak lengkap: rumah_warga_id, jenis_laporan, dan deskripsi wajib diisi.']); exit; } // Cek warga ada $stmtCek = $pdo->prepare("SELECT id, nama_kepala_keluarga FROM rumah_warga WHERE id = ?"); $stmtCek->execute([$rumahWargaId]); $warga = $stmtCek->fetch(); if (!$warga) { http_response_code(404); echo json_encode(['success' => false, 'message' => 'Data warga tidak ditemukan.']); exit; } // Cek apakah laporan duplikat dalam 7 hari terakhir $stmtDupCheck = $pdo->prepare(" SELECT id FROM laporan_warga WHERE rumah_warga_id = ? AND pelapor_id = ? AND status NOT IN ('selesai', 'ditolak') AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) "); $stmtDupCheck->execute([$rumahWargaId, $currentUser['id']]); if ($stmtDupCheck->fetch()) { http_response_code(409); echo json_encode(['success' => false, 'message' => 'Anda sudah membuat laporan untuk warga ini dalam 7 hari terakhir. Harap tunggu laporan sebelumnya diproses.']); exit; } $koordinatorIbadahId = !empty($currentUser['rumah_ibadah_id']) ? (int)$currentUser['rumah_ibadah_id'] : null; $stmtInsert = $pdo->prepare(" INSERT INTO laporan_warga (rumah_warga_id, pelapor_id, koordinator_ibadah_id, jenis_laporan, deskripsi, prioritas, status) VALUES (?, ?, ?, ?, ?, ?, 'pending') "); $stmtInsert->execute([ $rumahWargaId, $currentUser['id'], $koordinatorIbadahId, $jenisLaporan, $deskripsi, $prioritas, ]); echo json_encode([ 'success' => true, 'message' => 'Laporan berhasil dikirim. Admin akan meninjau laporan Anda segera.', 'id' => $pdo->lastInsertId() ]); break; case 'PUT': $currentUser = requireAuth(['admin', 'petugas']); $input = json_decode(file_get_contents('php://input'), true); if (!$input) $input = $_POST; $id = (int)($input['id'] ?? 0); $status = $input['status'] ?? ''; $catatanAdmin = trim($input['catatan_admin'] ?? ''); $ditugaskanKe = trim($input['ditugaskan_ke'] ?? ''); // Ambil dari old state $stmtDok = $pdo->prepare("SELECT dokumentasi FROM laporan_warga WHERE id = ?"); $stmtDok->execute([$id]); $oldDok = $stmtDok->fetchColumn(); $dokumentasi = trim($input['dokumentasi'] ?? $oldDok ?? ''); // Handle file upload if (isset($_FILES['dokumentasi_file']) && $_FILES['dokumentasi_file']['error'] === UPLOAD_ERR_OK) { $uploadDir = '../uploads/dokumentasi/'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0755, true); } $ext = strtolower(pathinfo($_FILES['dokumentasi_file']['name'], PATHINFO_EXTENSION)); $allowedExts = ['jpg', 'jpeg', 'png', 'pdf']; if (in_array($ext, $allowedExts)) { $filename = 'dok_' . $id . '_' . time() . '.' . $ext; $dest = $uploadDir . $filename; if (move_uploaded_file($_FILES['dokumentasi_file']['tmp_name'], $dest)) { $dokumentasi = 'uploads/dokumentasi/' . $filename; } } } $allowedStatus = ['pending', 'ditinjau', 'diproses', 'selesai', 'ditolak']; if (!$id || !in_array($status, $allowedStatus)) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'ID dan status valid wajib diisi.']); exit; } // Jika petugas, pastikan hanya bisa update dokumentasi, status, catatan. (ditugaskan_ke biarkan tetap) if ($currentUser['role'] === 'petugas') { $stmt = $pdo->prepare(" UPDATE laporan_warga SET status = ?, catatan_admin = ?, dokumentasi = ?, updated_at = NOW() WHERE id = ? AND ditugaskan_ke = ? "); $stmt->execute([$status, $catatanAdmin, $dokumentasi, $id, $currentUser['username']]); } else { // Admin bisa update semua $stmt = $pdo->prepare(" UPDATE laporan_warga SET status = ?, catatan_admin = ?, ditugaskan_ke = ?, dokumentasi = ?, updated_at = NOW() WHERE id = ? "); $stmt->execute([$status, $catatanAdmin, $ditugaskanKe ?: null, $dokumentasi, $id]); } $statusLabel = [ 'pending' => 'Menunggu', 'ditinjau' => 'Sedang Ditinjau', 'diproses' => 'Sedang Diproses', 'selesai' => 'Selesai', 'ditolak' => 'Ditolak', ]; echo json_encode([ 'success' => true, 'message' => 'Laporan berhasil diperbarui ke status: ' . ($statusLabel[$status] ?? $status) ]); break; // ── DELETE: Hapus laporan (admin only) ────────────────────────────── case 'DELETE': $currentUser = requireAuth(['admin']); $id = (int)($_GET['id'] ?? 0); if (!$id) { $input = json_decode(file_get_contents('php://input'), true); $id = (int)($input['id'] ?? 0); } if (!$id) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'ID laporan wajib diisi.']); exit; } $stmt = $pdo->prepare("DELETE FROM laporan_warga WHERE id = ?"); $stmt->execute([$id]); echo json_encode(['success' => true, 'message' => 'Laporan berhasil dihapus.']); break; default: http_response_code(405); echo json_encode(['error' => 'Method not allowed']); } } catch (Exception $e) { http_response_code(500); echo json_encode(['success' => false, 'message' => 'Kesalahan sistem: ' . $e->getMessage()]); }