Files
2026-08-26 14:11:37 +07:00

226 lines
6.6 KiB
HTML

<script>
// Theme initialization (Anti-FOUC)
(function() {
var savedTheme = localStorage.getItem('audit_theme');
if (savedTheme === 'dark' || (!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.setAttribute('data-theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
}
})();
</script>
<style>
:root {
--bg-main: #f4f6f9;
--card-bg: #ffffff;
--text-main: #2b3445;
--text-muted: #7d879c;
--border-color: #e3e9ef;
--border-color-light: #f1f5f9;
--primary-color: #1976d2;
--hover-bg: #f8f9fa;
--input-bg: #ffffff;
--input-text: #2b3445;
--input-border: #ced4da;
--sub-tab-bg: #e3f2fd;
--sub-tab-text: #1565c0;
--sub-tab-border: #bbdefb;
--sub-tab-active-bg: #1565c0;
--sub-tab-active-text: #ffffff;
--empty-state-bg: #f8f9fa;
--table-header-bg: #f1f5f9;
--table-header-text: #475569;
--table-row-hover: #f8fafc;
--table-border: #e2e8f0;
--modal-bg: #ffffff;
--shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
--success-color: #2e7d32;
--success-bg: #e8f5e9;
--danger-color: #c62828;
--danger-bg: #ffebee;
--warning-color: #e65100;
--warning-bg: #fff3e0;
--info-color: #0277bd;
--info-bg: #e1f5fe;
}
[data-theme="dark"] {
--bg-main: #0f172a;
--card-bg: #1e293b;
--text-main: #f1f5f9;
--text-muted: #94a3b8;
--border-color: #334155;
--border-color-light: #1e293b;
--primary-color: #3b82f6;
--hover-bg: #334155;
--input-bg: #0f172a;
--input-text: #f1f5f9;
--input-border: #475569;
--sub-tab-bg: #1e293b;
--sub-tab-text: #e2e8f0;
--sub-tab-border: #334155;
--sub-tab-active-bg: #3b82f6;
--sub-tab-active-text: #ffffff;
--empty-state-bg: #1e293b;
--table-header-bg: #334155;
--table-header-text: #e2e8f0;
--table-row-hover: #1e293b;
--table-border: #334155;
--modal-bg: #1e293b;
--shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
--success-color: #4caf50;
--success-bg: rgba(76, 175, 80, 0.1);
--danger-color: #ef5350;
--danger-bg: rgba(244, 67, 54, 0.1);
--warning-color: #ff9800;
--warning-bg: rgba(255, 152, 0, 0.1);
--info-color: #29b6f6;
--info-bg: rgba(3, 169, 244, 0.1);
}
.global-header {
width: 100%;
background: linear-gradient(135deg, #1565c0 0%, #0d47a1 100%);
color: white;
padding: 10px 20px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
box-sizing: border-box;
position: fixed;
top: 0;
left: 0;
z-index: 1000;
}
/* Đẩy toàn bộ nội dung body xuống để không bị header che mất */
body {
margin-top: 60px !important;
background-color: var(--bg-main);
color: var(--text-main);
transition: background-color 0.3s ease, color 0.3s ease;
}
.header-logo {
font-weight: 700;
font-size: 18px;
display: flex;
align-items: center;
gap: 10px;
}
.header-logo span {
background: rgba(255, 255, 255, 0.2);
padding: 3px 8px;
border-radius: 5px;
font-size: 14px;
letter-spacing: 1px;
}
.header-user-info {
display: flex;
align-items: center;
gap: 15px;
font-size: 14px;
}
.header-user-details {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.header-user-name {
font-weight: 600;
}
.header-user-role {
font-size: 12px;
color: #bbdefb;
}
.header-action-btn {
background: rgba(255, 255, 255, 0.1);
color: white;
text-decoration: none;
padding: 6px 15px;
border-radius: 5px;
font-weight: 600;
transition: background 0.3s;
border: 1px solid rgba(255, 255, 255, 0.3);
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
}
.header-action-btn:hover {
background: rgba(255, 255, 255, 0.2);
color: white;
}
.theme-toggle-btn {
padding: 6px 10px;
font-size: 16px;
}
.header-guest {
background: rgba(255, 255, 255, 0.1);
padding: 6px 15px;
border-radius: 5px;
font-size: 14px;
}
</style>
<div class="global-header">
<div class="header-logo">
🛡️ Audit Hardening Tool <span>VNPT-MEDIA</span>
</div>
<div class="header-user-info">
<button id="themeToggleBtn" class="header-action-btn theme-toggle-btn" title="Chuyển đổi giao diện Sáng/Tối">
<span id="themeIcon">🌞</span>
</button>
{% if is_logged_in and user_info %}
<div class="header-user-details">
<span class="header-user-name">👤 {{ user_info.full_name or user_info.username }}</span>
{% if user_info.role %}
<span class="header-user-role">{{ user_info.role|upper }} {% if user_info.unit_name %} | {{ user_info.unit_name }}{% endif %}</span>
{% endif %}
</div>
<a href="{{ url_for('logout') }}" class="header-action-btn">🚪 Đăng xuất</a>
{% else %}
<div class="header-guest">
👤 Khách
</div>
{% endif %}
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const toggleBtn = document.getElementById('themeToggleBtn');
const themeIcon = document.getElementById('themeIcon');
function updateIcon() {
if (document.documentElement.getAttribute('data-theme') === 'dark') {
themeIcon.textContent = '🌙';
} else {
themeIcon.textContent = '🌞';
}
}
updateIcon();
toggleBtn.addEventListener('click', function() {
let currentTheme = document.documentElement.getAttribute('data-theme');
let newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('audit_theme', newTheme);
updateIcon();
});
});
</script>