diff --git a/poverty-mapping/index.html b/poverty-mapping/index.html
index 94b9fe4..3aeee19 100644
--- a/poverty-mapping/index.html
+++ b/poverty-mapping/index.html
@@ -875,8 +875,6 @@ async function openAdminDashboard(){
${escapeHtml(item.created_at || '')}
-
-
`).join('');
@@ -892,16 +890,25 @@ async function approvePendingUser(id){
const jr = await resp.json().catch(()=>null);
if(!resp.ok || !jr || !jr.success){ showToast('Gagal menyetujui user', 'error', 4000); return; }
showToast('User disetujui', 'success', 3000);
+ closePendingManagerDetail();
openAdminDashboard();
}catch(e){ console.error(e); showToast('Gagal menyetujui user', 'error', 4000); }
}
async function rejectPendingUser(id){
+ const reason = prompt("Masukkan alasan penolakan:");
+ if (reason === null) return; // user cancelled
+ const trimmedReason = reason.trim();
+ if (!trimmedReason) {
+ showToast("Alasan penolakan wajib diisi!", "error", 4000);
+ return;
+ }
try{
- const resp = await fetch('src/api/admin/reject_user.php', { method: 'POST', headers: buildHeaders(), body: JSON.stringify({ id: id }), credentials: 'same-origin' });
+ const resp = await fetch('src/api/admin/reject_user.php', { method: 'POST', headers: buildHeaders(), body: JSON.stringify({ id: id, reason: trimmedReason }), credentials: 'same-origin' });
const jr = await resp.json().catch(()=>null);
if(!resp.ok || !jr || !jr.success){ showToast('Gagal menolak user', 'error', 4000); return; }
showToast('User ditolak', 'success', 3000);
+ closePendingManagerDetail();
openAdminDashboard();
}catch(e){ console.error(e); showToast('Gagal menolak user', 'error', 4000); }
}
@@ -2413,6 +2420,10 @@ function openPendingManagerDetail(u){
Bukti Organisasi
${proofPreview}
+
+
+
+
`;
modal.classList.remove('hidden');
diff --git a/poverty-mapping/src/api/admin/reject_user.php b/poverty-mapping/src/api/admin/reject_user.php
index fa807e9..b06a022 100644
--- a/poverty-mapping/src/api/admin/reject_user.php
+++ b/poverty-mapping/src/api/admin/reject_user.php
@@ -1,21 +1,60 @@
query("ALTER TABLE users ADD COLUMN IF NOT EXISTS rejection_reason TEXT NULL");
+} catch(Exception $e){}
+
$data = json_decode(file_get_contents('php://input'), true);
$id = isset($data['id']) ? intval($data['id']) : 0;
if(!$id){ http_response_code(400); echo json_encode(['success'=>false,'error'=>'missing_id']); exit; }
-$st = $conn->prepare('UPDATE users SET status = "rejected", approved_by = ?, approved_at = NOW() WHERE id = ?');
+$reason = isset($data['reason']) ? trim($data['reason']) : '';
+
+// 1. Fetch user email and name first
+$email = null;
+$name = null;
+$uStmt = $conn->prepare("SELECT email, name FROM users WHERE id = ?");
+if($uStmt){
+ $uStmt->bind_param('i', $id);
+ $uStmt->execute();
+ $uRes = $uStmt->get_result();
+ $uRow = $uRes ? $uRes->fetch_assoc() : null;
+ if($uRow){
+ $email = $uRow['email'];
+ $name = $uRow['name'];
+ }
+ $uStmt->close();
+}
+
+// 2. Perform the update
+$st = $conn->prepare('UPDATE users SET status = "rejected", rejection_reason = ?, approved_by = ?, approved_at = NOW() WHERE id = ?');
if(!$st){ http_response_code(500); echo json_encode(['success'=>false,'error'=>$conn->error]); exit; }
$adminId = intval(get_current_user_info()['id']);
-$st->bind_param('ii', $adminId, $id);
+$st->bind_param('sii', $reason, $adminId, $id);
$res = $st->execute();
$st->close();
if(!$res){ http_response_code(500); echo json_encode(['success'=>false,'error'=>$conn->error]); exit; }
+// 3. Send email notification if user has email
+if($email){
+ try {
+ $subject = 'Pendaftaran Pengelola Ditolak - WebGIS';
+ $message = "Halo " . ($name ? $name : 'Pengelola') . ",\n\n" .
+ "Pendaftaran akun pengelola Anda pada sistem WebGIS Poverty Mapping tidak disetujui oleh administrator.\n\n" .
+ "Alasan penolakan:\n" . ($reason ? $reason : '-') . "\n\n" .
+ "Terima kasih.";
+ send_mail_notify($email, $subject, $message, false);
+ } catch (Exception $e) {
+ error_log("Failed to send rejection email: " . $e->getMessage());
+ }
+}
+
echo json_encode(['success'=>true]);
?>
diff --git a/poverty-mapping/src/api/auth/reject_manager.php b/poverty-mapping/src/api/auth/reject_manager.php
index 52ede6e..f0ad64a 100644
--- a/poverty-mapping/src/api/auth/reject_manager.php
+++ b/poverty-mapping/src/api/auth/reject_manager.php
@@ -1,15 +1,37 @@
false,'error'=>'forbidden']); exit; }
+// Ensure column exists
+try {
+ $conn->query("ALTER TABLE users ADD COLUMN IF NOT EXISTS rejection_reason TEXT NULL");
+} catch(Exception $e){}
+
$data = json_decode(file_get_contents('php://input'), true);
if(!$data || !isset($data['id'])){ http_response_code(400); echo json_encode(['success'=>false,'error'=>'missing_id']); exit; }
$id = intval($data['id']);
-$reason = isset($data['reason']) ? $data['reason'] : null;
+$reason = isset($data['reason']) ? trim($data['reason']) : '';
+
+// 1. Fetch user email and name first
+$email = null;
+$name = null;
+$uStmt = $conn->prepare("SELECT email, name FROM users WHERE id = ?");
+if($uStmt){
+ $uStmt->bind_param('i', $id);
+ $uStmt->execute();
+ $uRes = $uStmt->get_result();
+ $uRow = $uRes ? $uRes->fetch_assoc() : null;
+ if($uRow){
+ $email = $uRow['email'];
+ $name = $uRow['name'];
+ }
+ $uStmt->close();
+}
$st = $conn->prepare('UPDATE users SET status = ?, rejection_reason = ?, approved_by = ?, approved_at = NOW() WHERE id = ? AND role = "manager"');
if(!$st){ http_response_code(500); echo json_encode(['success'=>false,'error'=>$conn->error]); exit; }
@@ -17,5 +39,18 @@ $status = 'rejected'; $adminId = intval($admin['id']); $st->bind_param('ssii', $
$res = $st->execute(); $st->close();
if(!$res){ http_response_code(500); echo json_encode(['success'=>false,'error'=>$conn->error]); exit; }
+if($email){
+ try {
+ $subject = 'Pendaftaran Pengelola Ditolak - WebGIS';
+ $message = "Halo " . ($name ? $name : 'Pengelola') . ",\n\n" .
+ "Pendaftaran akun pengelola Anda pada sistem WebGIS Poverty Mapping tidak disetujui oleh administrator.\n\n" .
+ "Alasan penolakan:\n" . ($reason ? $reason : '-') . "\n\n" .
+ "Terima kasih.";
+ send_mail_notify($email, $subject, $message, false);
+ } catch (Exception $e) {
+ error_log("Failed to send rejection email: " . $e->getMessage());
+ }
+}
+
echo json_encode(['success'=>true]);
?>
\ No newline at end of file