132 lines
6.1 KiB
Twig
Executable File
132 lines
6.1 KiB
Twig
Executable File
<!DOCTYPE html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{{ title }} - Система мониторинга</title>
|
|
<!-- Bootstrap 5 CSS -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<!-- Font Awesome 6 -->
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<!-- Favicon -->
|
|
<link rel="icon" type="image/png" href="/favicon.png">
|
|
|
|
<style>
|
|
.csrf-field {
|
|
display: none;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container-fluid">
|
|
{% if session.username %}
|
|
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
|
|
<div class="container">
|
|
<a class="navbar-brand" href="/">
|
|
<i class="fas fa-server"></i> Система мониторинга
|
|
</a>
|
|
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
|
|
<div class="collapse navbar-collapse" id="navbarNav">
|
|
<ul class="navbar-nav me-auto">
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/"><i class="fas fa-tachometer-alt"></i> Дашборд</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/groups"><i class="fas fa-layer-group"></i> Группы серверов</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/servers"><i class="fas fa-server"></i> Серверы</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/alerts"><i class="fas fa-bell"></i> Аллерты</a>
|
|
</li>
|
|
{% if session.role == 'admin' %}
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle" href="#" id="adminDropdown" role="button" data-bs-toggle="dropdown">
|
|
<i class="fas fa-cog"></i> Администрирование
|
|
</a>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="/admin/users"><i class="fas fa-users"></i> Пользователи</a></li>
|
|
<li><a class="dropdown-item" href="/admin/notifications"><i class="fas fa-bell"></i> Уведомления</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="/admin/defaults"><i class="fas fa-sliders-h"></i> Дефолтные параметры</a></li>
|
|
</ul>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
|
|
<ul class="navbar-nav">
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
<i class="fas fa-user-circle"></i> {{ session.username|default('Гость') }}
|
|
</a>
|
|
<ul class="dropdown-menu dropdown-menu-end">
|
|
<li><a class="dropdown-item" href="/logout"><i class="fas fa-sign-out-alt"></i> Выйти</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
{% endif %}
|
|
|
|
<main class="container mt-4">
|
|
{% if session.flash_message is defined and session.flash_message %}
|
|
<div class="alert alert-{{ session.flash_type == "error" ? "danger" : (session.flash_type == "warning" ? "warning" : "success") }} alert-dismissible fade show mb-3" role="alert">
|
|
{{ session.flash_message|nl2br }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% block content %}{% endblock %}
|
|
</main>
|
|
|
|
{% if session.username %}
|
|
<footer class="footer mt-5 py-3 bg-light">
|
|
<div class="container text-center">
|
|
<span class="text-muted">© {{ 'now'|date('Y') }} Система мониторинга серверов</span>
|
|
</div>
|
|
</footer>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Bootstrap 5 JS Bundle with Popper -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
|
|
<!-- Auto-add CSRF tokens to all POST forms via AJAX -->
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Get CSRF tokens from API endpoint
|
|
fetch('/csrf-token')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
// Add tokens to all POST forms
|
|
document.querySelectorAll('form[method="post"]').forEach(function(form) {
|
|
// Add name field
|
|
var nameInput = document.createElement('input');
|
|
nameInput.type = 'hidden';
|
|
nameInput.name = data.name_key;
|
|
nameInput.value = data.name;
|
|
form.appendChild(nameInput);
|
|
|
|
// Add value field
|
|
var valueInput = document.createElement('input');
|
|
valueInput.type = 'hidden';
|
|
valueInput.name = data.value_key;
|
|
valueInput.value = data.value;
|
|
form.appendChild(valueInput);
|
|
});
|
|
})
|
|
.catch(error => {
|
|
console.error('Failed to get CSRF tokens:', error);
|
|
});
|
|
});
|
|
</script>
|
|
<!-- Bootstrap 5 JS -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
</body>
|
|
</html> |