Files
LogBoard/templates/error.html
Сергей Антропов e80f665470 feat: major improvements and fixes
- Fixed Docker permissions issue by running as root user
- Added DEBUG_MODE support with conditional Swagger docs and auto-reload
- Created start.sh script for conditional Uvicorn execution
- Removed verbose debug logs from WebSocket status endpoint
- Added comprehensive screenshots to documentation
- Enhanced help tooltip with full-screen modal design
- Added theme switcher to error page
- Updated documentation with local development and Docker benefits
- Fixed WebSocket status display issues
- Improved hotkey functionality and documentation
- Added detailed project descriptions for local dev and Docker users

Technical improvements:
- Dockerfile: removed appuser switch, simplified permissions
- docker-compose.yml: kept user: 0:0 for Docker socket access
- app.py: removed debug prints, added DEBUG_MODE support
- templates: enhanced UI/UX with better tooltips and themes
- docs: comprehensive updates with new screenshots and descriptions
2025-08-19 13:01:32 +03:00

327 lines
9.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ error_title }} - LogBoard+</title>
<style>
:root {
--bg: #1a1b26;
--fg: #c0caf5;
--panel: #24283b;
--border: #414868;
--accent: #7aa2f7;
--muted: #565a6e;
--ok: #9ece6a;
--warn: #e0af68;
--err: #f7768e;
--chip: #414868;
}
[data-theme="light"] {
--bg: #d5d6db;
--fg: #343b58;
--panel: #e1e2e7;
--border: #9699a3;
--accent: #34548a;
--muted: #9699a3;
--ok: #485e30;
--warn: #8f5e15;
--err: #8c4351;
--chip: #d5d6db;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: var(--bg);
color: var(--fg);
line-height: 1.6;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.3s ease, color 0.3s ease;
}
.error-container {
max-width: 600px;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
}
.error-icon {
font-size: 4rem;
margin-bottom: 1rem;
color: var(--err);
}
.error-code {
font-size: 3rem;
font-weight: bold;
color: var(--accent);
margin-bottom: 0.5rem;
}
.error-title {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 1rem;
color: var(--fg);
}
.error-message {
font-size: 1rem;
color: var(--muted);
margin-bottom: 2rem;
line-height: 1.6;
}
.error-details {
background: var(--panel);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
margin-bottom: 2rem;
text-align: left;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 0.9rem;
color: var(--muted);
}
.btn {
display: inline-block;
padding: 0.75rem 1.5rem;
background: var(--accent);
color: white;
text-decoration: none;
border-radius: 6px;
font-weight: 500;
transition: all 0.2s ease;
border: none;
cursor: pointer;
font-size: 1rem;
}
.btn:hover {
background: var(--accent);
opacity: 0.9;
transform: translateY(-1px);
}
.btn-secondary {
background: var(--chip);
color: var(--fg);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--border);
}
.btn-group {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
}
.theme-toggle {
position: fixed;
top: 1rem;
right: 1rem;
background: var(--panel);
border: 1px solid var(--border);
border-radius: 50%;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
font-size: 1.2rem;
color: var(--fg);
z-index: 1000;
}
.theme-toggle:hover {
background: var(--border);
transform: scale(1.1);
}
.theme-toggle:active {
transform: scale(0.95);
}
.auth-notice {
background: var(--warn);
color: var(--bg);
padding: 1rem;
border-radius: 6px;
margin-bottom: 1rem;
font-weight: 500;
}
.footer {
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid var(--border);
color: var(--muted);
font-size: 0.9rem;
}
.footer a {
color: var(--accent);
text-decoration: none;
}
.footer a:hover {
text-decoration: underline;
}
@media (max-width: 768px) {
.error-container {
padding: 1rem;
}
.error-code {
font-size: 2rem;
}
.error-title {
font-size: 1.25rem;
}
.btn-group {
flex-direction: column;
align-items: center;
}
.btn {
width: 100%;
max-width: 300px;
}
.theme-toggle {
top: 0.5rem;
right: 0.5rem;
width: 40px;
height: 40px;
font-size: 1rem;
}
}
</style>
</head>
<body>
<!-- Кнопка переключателя темы -->
<button class="theme-toggle" onclick="toggleTheme()" title="Переключить тему (Ctrl+T)">
🌙
</button>
<div class="error-container">
<div class="error-icon">
{% if error_code == 401 %}
🔐
{% elif error_code == 403 %}
🚫
{% elif error_code == 404 %}
🔍
{% elif error_code == 500 %}
⚠️
{% else %}
{% endif %}
</div>
<div class="error-code">{{ error_code }}</div>
<div class="error-title">{{ error_title }}</div>
{% if error_code == 401 %}
<div class="auth-notice">
🔐 Эта страница требует авторизации
</div>
{% elif error_code == 403 %}
<div class="auth-notice">
🚫 У вас нет прав для доступа к этой странице
</div>
{% endif %}
{% if error_code != 403 %}
<div class="error-message">
{{ error_message }}
</div>
{% endif %}
<div class="btn-group">
<a href="/" class="btn">На главную</a>
{% if error_code == 403 %}
<a href="/login" class="btn btn-secondary">Войти в систему</a>
{% endif %}
<button onclick="history.back()" class="btn btn-secondary">Назад</button>
</div>
<div class="footer">
<p>
LogBoard+ - Веб-панель для просмотра логов микросервисов<br>
Автор: <a href="https://devops.org.ru" target="_blank">Сергей Антропов</a>
</p>
</div>
</div>
<script>
// Автоматическое определение темы
const savedTheme = localStorage.getItem('lb_theme') || 'dark';
document.documentElement.setAttribute('data-theme', savedTheme);
// Функция для обновления иконки темы
function updateThemeIcon() {
const themeToggle = document.querySelector('.theme-toggle');
const currentTheme = document.documentElement.getAttribute('data-theme');
if (themeToggle) {
if (currentTheme === 'light') {
themeToggle.innerHTML = '🌙';
themeToggle.title = 'Переключить на темную тему (Ctrl+T)';
} else {
themeToggle.innerHTML = '☀️';
themeToggle.title = 'Переключить на светлую тему (Ctrl+T)';
}
}
}
// Переключатель темы
function toggleTheme() {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('lb_theme', newTheme);
// Обновляем иконку
updateThemeIcon();
}
// Добавляем обработчик клавиш для переключения темы (Ctrl+T)
document.addEventListener('keydown', function(e) {
if (e.ctrlKey && e.key === 't') {
e.preventDefault();
toggleTheme();
}
});
// Инициализируем иконку при загрузке страницы
document.addEventListener('DOMContentLoaded', function() {
updateThemeIcon();
});
</script>
</body>
</html>