feat: add delete notification button with confirmation in admin notifications
This commit is contained in:
@@ -38,3 +38,23 @@ function sendNotification() {
|
|||||||
btn.innerHTML = '<i class="fas fa-paper-plane"></i> Send';
|
btn.innerHTML = '<i class="fas fa-paper-plane"></i> Send';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function confirmDelete(id, title) {
|
||||||
|
if (!confirm('Delete notification "' + title + '"? This action cannot be undone.')) return;
|
||||||
|
|
||||||
|
const csrf = document.querySelector('meta[name="csrf-token"]')?.content || '';
|
||||||
|
fetch('/admin/notifications/' + id + '/delete', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
'X-CSRF-Token': csrf,
|
||||||
|
},
|
||||||
|
body: '_csrf_token=' + encodeURIComponent(csrf),
|
||||||
|
})
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
showToast(data.success ? 'success' : 'error', data.message);
|
||||||
|
if (data.success) location.reload();
|
||||||
|
})
|
||||||
|
.catch(() => showToast('error', 'Failed to delete notification'));
|
||||||
|
}
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ $router->group(['prefix' => 'admin', 'middleware' => [AuthMiddleware::class, Rol
|
|||||||
$router->post('/app-version', [AdminController::class, 'appVersion'], [CSRFMiddleware::class]);
|
$router->post('/app-version', [AdminController::class, 'appVersion'], [CSRFMiddleware::class]);
|
||||||
$router->get('/notifications', [AdminController::class, 'notifications']);
|
$router->get('/notifications', [AdminController::class, 'notifications']);
|
||||||
$router->post('/notifications/send', [AdminController::class, 'sendNotification'], [CSRFMiddleware::class]);
|
$router->post('/notifications/send', [AdminController::class, 'sendNotification'], [CSRFMiddleware::class]);
|
||||||
|
$router->post('/notifications/:id/delete', [AdminController::class, 'deleteNotification'], [CSRFMiddleware::class]);
|
||||||
|
|
||||||
$router->get('/policies', [AdminController::class, 'policies']);
|
$router->get('/policies', [AdminController::class, 'policies']);
|
||||||
$router->post('/policies', [AdminController::class, 'savePolicies'], [CSRFMiddleware::class]);
|
$router->post('/policies', [AdminController::class, 'savePolicies'], [CSRFMiddleware::class]);
|
||||||
|
|||||||
@@ -295,6 +295,26 @@ class AdminController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteNotification(int $id): void
|
||||||
|
{
|
||||||
|
$this->requireSuperAdmin();
|
||||||
|
|
||||||
|
$notificationModel = new Notification();
|
||||||
|
$note = $notificationModel->findById($id);
|
||||||
|
|
||||||
|
if (!$note) {
|
||||||
|
$this->view->json(['success' => false, 'message' => 'Notification not found.'], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$notificationModel->delete($id);
|
||||||
|
|
||||||
|
$this->auditService->log('notification_deleted', 'notification', $id, [
|
||||||
|
'title' => $note['title'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->view->json(['success' => true, 'message' => 'Notification deleted.']);
|
||||||
|
}
|
||||||
|
|
||||||
public function sendNotification(): void
|
public function sendNotification(): void
|
||||||
{
|
{
|
||||||
$this->requireSuperAdmin();
|
$this->requireSuperAdmin();
|
||||||
|
|||||||
@@ -143,4 +143,10 @@ class Notification
|
|||||||
$result = $this->db->fetch("SELECT COUNT(*) as total FROM users WHERE status = 'active'");
|
$result = $this->db->fetch("SELECT COUNT(*) as total FROM users WHERE status = 'active'");
|
||||||
return (int) ($result['total'] ?? 0);
|
return (int) ($result['total'] ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete(int $id): void
|
||||||
|
{
|
||||||
|
$this->db->delete('notifications', 'id = ?', [$id]);
|
||||||
|
$this->db->delete('notification_reads', 'notification_id = ?', [$id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,12 +29,13 @@ $data = $notifications['data'] ?? [];
|
|||||||
<th>Message</th>
|
<th>Message</th>
|
||||||
<th>Target</th>
|
<th>Target</th>
|
||||||
<th>Read by</th>
|
<th>Read by</th>
|
||||||
|
<th style="width:60px">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php if (empty($data)): ?>
|
<?php if (empty($data)): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center text-muted">No notifications sent yet.</td>
|
<td colspan="7" class="text-center text-muted">No notifications sent yet.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($data as $note): ?>
|
<?php foreach ($data as $note): ?>
|
||||||
@@ -65,6 +66,13 @@ $data = $notifications['data'] ?? [];
|
|||||||
</span>
|
</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-icon btn-xs" title="Delete"
|
||||||
|
onclick="confirmDelete(<?= $note['id'] ?>, '<?= htmlspecialchars(addslashes($note['title'] ?? '')) ?>')"
|
||||||
|
style="color:var(--danger)">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user