183 lines
9.0 KiB
PHP
183 lines
9.0 KiB
PHP
<?php
|
|
$notifications = $notifications ?? [];
|
|
$users = $users ?? [];
|
|
$totalActiveUsers = $totalActiveUsers ?? 0;
|
|
$data = $notifications['data'] ?? [];
|
|
?>
|
|
|
|
<div class="page-header">
|
|
<div class="page-header-left">
|
|
<h1 class="page-title">Notifications</h1>
|
|
<p class="page-subtitle">Send push notifications to Android app users</p>
|
|
</div>
|
|
<div class="page-header-right">
|
|
<button class="btn btn-primary" onclick="showSendModal()">
|
|
<i class="fas fa-paper-plane"></i> Send Notification
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Time</th>
|
|
<th>Type</th>
|
|
<th>Title</th>
|
|
<th>Message</th>
|
|
<th>Target</th>
|
|
<th>Read by</th>
|
|
<th style="width:60px">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($data)): ?>
|
|
<tr>
|
|
<td colspan="7" class="text-center text-muted">No notifications sent yet.</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($data as $note): ?>
|
|
<tr>
|
|
<td><?= htmlspecialchars($note['created_at'] ?? '') ?></td>
|
|
<td>
|
|
<span class="badge badge-<?= match($note['type'] ?? 'info') {
|
|
'success' => 'success',
|
|
'warning' => 'warning',
|
|
'error' => 'danger',
|
|
default => 'info',
|
|
} ?>">
|
|
<?= htmlspecialchars(ucfirst($note['type'] ?? 'info')) ?>
|
|
</span>
|
|
</td>
|
|
<td><strong><?= htmlspecialchars($note['title'] ?? '') ?></strong></td>
|
|
<td><?= htmlspecialchars(mb_substr($note['message'] ?? '', 0, 80)) ?><?= mb_strlen($note['message'] ?? '') > 80 ? '...' : '' ?></td>
|
|
<td><?= $note['user_id'] ? htmlspecialchars($note['target_username'] ?? "User #{$note['user_id']}") : '<em>All Users</em>' ?></td>
|
|
<td>
|
|
<?php if ($note['user_id']): ?>
|
|
<span class="status-badge <?= ($note['read_count'] ?? 0) > 0 ? 'status-online' : 'status-offline' ?>">
|
|
<?= ($note['read_count'] ?? 0) > 0 ? 'Read' : 'Unread' ?>
|
|
</span>
|
|
<?php else: ?>
|
|
<?php $rc = (int) ($note['read_count'] ?? 0); ?>
|
|
<span class="badge badge-<?= $rc >= $totalActiveUsers ? 'success' : ($rc > 0 ? 'warning' : 'secondary') ?>">
|
|
<?= $rc ?> / <?= $totalActiveUsers ?>
|
|
</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<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="showDeleteModal(<?= $note['id'] ?>, '<?= htmlspecialchars(addslashes($note['title'] ?? '')) ?>')"
|
|
style="color:var(--danger)">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<?php if (($notifications['total_pages'] ?? 1) > 1): ?>
|
|
<div class="pagination">
|
|
<?php for ($i = 1; $i <= $notifications['total_pages']; $i++): ?>
|
|
<a href="?page=<?= $i ?>" class="page-link <?= $i === ($notifications['page'] ?? 1) ? 'active' : '' ?>">
|
|
<?= $i ?>
|
|
</a>
|
|
<?php endfor; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal" id="notificationModal">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h3>Send Notification</h3>
|
|
<button class="modal-close" onclick="closeModal()">×</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="notificationForm">
|
|
<input type="hidden" name="_csrf_token" value="<?= $this->csrfToken() ?>">
|
|
|
|
<div class="form-group">
|
|
<label for="noteTitle">Title</label>
|
|
<input type="text" id="noteTitle" name="title" class="form-input" required maxlength="255"
|
|
placeholder="e.g. Maintenance scheduled">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="noteMessage">Message</label>
|
|
<textarea id="noteMessage" name="message" class="form-input" rows="4" required
|
|
placeholder="Notification content..."></textarea>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="noteType">Type</label>
|
|
<select id="noteType" name="type" class="form-select">
|
|
<option value="info">Info</option>
|
|
<option value="success">Success</option>
|
|
<option value="warning">Warning</option>
|
|
<option value="error">Error</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="noteUser">Send To</label>
|
|
<select id="noteUser" name="user_id" class="form-select">
|
|
<option value="">All Users (general notification)</option>
|
|
<?php foreach ($users['data'] as $u): ?>
|
|
<option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['username']) ?> (<?= htmlspecialchars($u['email']) ?>)</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<small class="form-hint">Leave as "All Users" to send to everyone.</small>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-secondary" onclick="closeModal()">Cancel</button>
|
|
<button class="btn btn-primary" onclick="sendNotification()">
|
|
<i class="fas fa-paper-plane"></i> Send
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Delete Confirmation Modal -->
|
|
<div class="modal" id="deleteModal" onclick="if (event.target === this) closeDeleteModal()">
|
|
<div class="modal-dialog" style="max-width: 400px;">
|
|
<div class="modal-header">
|
|
<h3><i class="fas fa-trash" style="color:var(--danger);margin-right:0.5rem"></i>Delete Notification</h3>
|
|
<button class="modal-close" onclick="closeDeleteModal()">×</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p style="margin-bottom:0.5rem;font-size:0.92rem">
|
|
Are you sure you want to delete this notification?
|
|
</p>
|
|
<p id="deleteModalTitle" style="font-size:0.88rem;color:var(--text-muted);background:var(--bg-tertiary);padding:0.5rem 0.75rem;border-radius:var(--radius-sm)"></p>
|
|
<p style="margin-top:0.75rem;font-size:0.82rem;color:var(--text-muted)">
|
|
This action cannot be undone. The notification will be removed for all users.
|
|
</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-secondary" onclick="closeDeleteModal()">Cancel</button>
|
|
<button class="btn btn-danger" id="deleteConfirmBtn" onclick="executeDelete()">
|
|
<i class="fas fa-trash"></i> Delete
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/assets/js/admin-notifications.js?v=<?= asset_version() ?>"></script>
|