feat: add resend notification action with push
This commit is contained in:
@@ -58,3 +58,20 @@ function confirmDelete(id, title) {
|
||||
})
|
||||
.catch(() => showToast('error', 'Failed to delete notification'));
|
||||
}
|
||||
|
||||
function confirmResend(id) {
|
||||
const csrf = document.querySelector('meta[name="csrf-token"]')?.content || '';
|
||||
fetch('/admin/notifications/' + id + '/resend', {
|
||||
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);
|
||||
})
|
||||
.catch(() => showToast('error', 'Failed to resend notification'));
|
||||
}
|
||||
|
||||
@@ -116,6 +116,7 @@ $router->group(['prefix' => 'admin', 'middleware' => [AuthMiddleware::class, Rol
|
||||
$router->get('/notifications', [AdminController::class, 'notifications']);
|
||||
$router->post('/notifications/send', [AdminController::class, 'sendNotification'], [CSRFMiddleware::class]);
|
||||
$router->post('/notifications/:id/delete', [AdminController::class, 'deleteNotification'], [CSRFMiddleware::class]);
|
||||
$router->post('/notifications/:id/resend', [AdminController::class, 'resendNotification'], [CSRFMiddleware::class]);
|
||||
|
||||
$router->get('/policies', [AdminController::class, 'policies']);
|
||||
$router->post('/policies', [AdminController::class, 'savePolicies'], [CSRFMiddleware::class]);
|
||||
|
||||
@@ -315,6 +315,41 @@ class AdminController
|
||||
$this->view->json(['success' => true, 'message' => 'Notification deleted.']);
|
||||
}
|
||||
|
||||
public function resendNotification(int $id): void
|
||||
{
|
||||
$this->requireSuperAdmin();
|
||||
|
||||
$notificationModel = new Notification();
|
||||
$note = $notificationModel->findById($id);
|
||||
|
||||
if (!$note) {
|
||||
$this->view->json(['success' => false, 'message' => 'Notification not found.'], 404);
|
||||
}
|
||||
|
||||
$title = $note['title'];
|
||||
$message = $note['message'];
|
||||
$type = $note['type'] ?? 'info';
|
||||
$userId = $note['user_id'] ? (int) $note['user_id'] : null;
|
||||
|
||||
$fcm = new FCMService();
|
||||
$pushResult = '';
|
||||
if ($userId) {
|
||||
$sent = $fcm->sendToUser($userId, $title, $message, $type, $id);
|
||||
$pushResult = $sent ? ' (push sent)' : ($fcm->isConfigured() ? ' (push failed)' : '');
|
||||
} else {
|
||||
$count = $fcm->sendToAll($title, $message, $type, $id);
|
||||
$pushResult = $fcm->isConfigured() ? " (push sent to {$count} devices)" : '';
|
||||
}
|
||||
|
||||
$this->auditService->log('notification_resent', 'notification', $id, [
|
||||
'title' => $title,
|
||||
'target' => $userId ? "user #{$userId}" : 'all users',
|
||||
'push' => $fcm->isConfigured() ? 'sent' : 'not_configured',
|
||||
]);
|
||||
|
||||
$this->view->json(['success' => true, 'message' => 'Notification resent successfully.' . $pushResult]);
|
||||
}
|
||||
|
||||
public function sendNotification(): void
|
||||
{
|
||||
$this->requireSuperAdmin();
|
||||
|
||||
@@ -67,11 +67,18 @@ $data = $notifications['data'] ?? [];
|
||||
<?php endif; ?>
|
||||
</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>
|
||||
<div style="display:flex;gap:0.25rem">
|
||||
<button class="btn btn-icon btn-xs" title="Resend"
|
||||
onclick="confirmResend(<?= $note['id'] ?>)"
|
||||
style="color:var(--info)">
|
||||
<i class="fas fa-redo"></i>
|
||||
</button>
|
||||
<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>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
Reference in New Issue
Block a user