This commit is contained in:
2026-07-20 14:46:07 +07:00
parent 476c41cf08
commit 4a159cad71
10 changed files with 2224 additions and 3 deletions

View File

@@ -55,6 +55,56 @@
</div>
<% } %>
<% if (currentUser && currentUser.role === 'Admin') { %>
<div id="systemNotificationModal" class="modal-backdrop" role="dialog" aria-modal="true" aria-labelledby="systemNotificationModalTitle">
<div class="modal-content">
<div class="modal-header">
<div>
<h3 id="systemNotificationModalTitle">Đăng thông báo hệ thống</h3>
<p>Thông báo sẽ được gửi tới tất cả tài khoản đang hoạt động.</p>
</div>
<button class="icon-button subtle" type="button" data-modal-close aria-label="Đóng">
<span class="material-symbols-outlined">close</span>
</button>
</div>
<form class="modal-form" data-system-notification-form>
<div class="form-stack">
<label class="form-field">
<span>Tiêu đề</span>
<input type="text" name="title" maxlength="200" required placeholder="Ví dụ: Hệ thống đã cập nhật phiên bản 1.2.0">
</label>
<label class="form-field">
<span>Mức độ</span>
<select name="severity" required>
<option value="info">Thông tin</option>
<option value="success">Cập nhật thành công</option>
<option value="warning">Quan trọng / bảo trì</option>
<option value="error">Khẩn cấp / sự cố</option>
</select>
</label>
<label class="form-field">
<span>Nội dung</span>
<textarea name="message" rows="6" maxlength="1000" required placeholder="Mô tả nội dung cập nhật, ảnh hưởng và việc người dùng cần thực hiện."></textarea>
<small>Tối đa 1000 ký tự. Không nhập mật khẩu, token hoặc thông tin nhạy cảm.</small>
</label>
<label class="form-field">
<span>Đường dẫn nội bộ (không bắt buộc)</span>
<input type="text" name="actionUrl" maxlength="1000" placeholder="Ví dụ: /applications hoặc /agent">
<small>Chỉ chấp nhận đường dẫn trong website bắt đầu bằng dấu /.</small>
</label>
</div>
<div class="modal-actions">
<button class="btn btn-secondary" type="button" data-modal-close>Hủy</button>
<button class="btn btn-primary" type="submit" data-system-notification-submit>
<span class="material-symbols-outlined">send</span>
Gửi cho mọi người
</button>
</div>
</form>
</div>
</div>
<% } %>
<script src="/vendor/notiflix/notiflix-<%= notiflixVersion %>.min.js"></script>
<script src="/js/app.js"></script>
</body>

View File

@@ -52,9 +52,52 @@
<button class="icon-button" type="button" title="Đồng bộ dữ liệu" data-refresh-page>
<span class="material-symbols-outlined">sync</span>
</button>
<button class="icon-button" type="button" title="Thông báo" data-toast="Chưa có thông báo mới">
<span class="material-symbols-outlined">notifications</span>
</button>
<div class="notification-center" data-notification-center>
<button
id="notificationButton"
class="icon-button notification-button"
type="button"
title="Thông báo"
aria-label="Mở thông báo"
aria-controls="notificationPanel"
aria-expanded="false"
data-notification-toggle
>
<span class="material-symbols-outlined">notifications</span>
<span class="notification-badge" data-notification-badge hidden>0</span>
</button>
<section id="notificationPanel" class="notification-panel" aria-label="Thông báo" hidden data-notification-panel>
<div class="notification-panel-header">
<div>
<strong>Thông báo</strong>
<span data-notification-summary>Đang tải...</span>
</div>
<button class="text-button" type="button" data-notification-read-all>Đánh dấu đã đọc</button>
</div>
<div class="notification-tabs" role="tablist" aria-label="Lọc thông báo">
<button class="active" type="button" role="tab" aria-selected="true" data-notification-filter="all">Tất cả</button>
<button type="button" role="tab" aria-selected="false" data-notification-filter="unread">Chưa đọc</button>
</div>
<div class="notification-list" data-notification-list></div>
<div class="notification-empty" data-notification-empty hidden>
<span class="material-symbols-outlined">notifications_none</span>
<strong>Chưa có thông báo</strong>
<span>Các cập nhật quan trọng sẽ xuất hiện tại đây.</span>
</div>
<% if (currentUser.role === 'Admin') { %>
<div class="notification-panel-footer">
<button class="btn btn-primary" type="button" data-modal-open="systemNotificationModal">
<span class="material-symbols-outlined">campaign</span>
Đăng thông báo hệ thống
</button>
</div>
<% } %>
</section>
</div>
<% if (currentUser.role === 'User') { %>
<button class="profile-chip profile-chip-button" type="button" title="Cập nhật thông tin cá nhân" aria-label="Cập nhật thông tin cá nhân" data-modal-open="profileModal">
<span class="profile-avatar"><%= currentUser.name.charAt(0) %></span>