Дорабоки интерфейса системы тестирования. Раздел 1 Шапка+Верхний brick

This commit is contained in:
Константин Лебединский
2026-04-29 14:55:43 +05:00
parent 1c4dacbc85
commit eff3fda5b0
34 changed files with 3339 additions and 576 deletions
+102 -69
View File
@@ -8,7 +8,7 @@
{# Tailwind CDN — на E1.0 этого достаточно. В Этапе 2/CI можно заменить на сборку. #}
<script src="https://cdn.tailwindcss.com"></script>
<script>
// Минимальная палитра в стиле кабинета HR. Без зависимостей от HR-репо.
// Палитра/типографика в стиле webapp-nginx (cabinet-theme).
tailwind.config = {
theme: {
extend: {
@@ -17,18 +17,19 @@
},
colors: {
brand: {
50: '#eef2ff',
100: '#e0e7ff',
500: '#6366f1',
600: '#4f46e5',
700: '#4338ca',
50: '#ecf7f6',
100: '#d9efec',
300: '#9bd7d0',
500: '#007168',
600: '#00645b',
700: '#00574f',
},
ink: {
900: '#0f172a',
700: '#334155',
500: '#64748b',
300: '#cbd5e1',
100: '#f1f5f9',
900: '#0d1b1d',
700: '#3d5357',
500: '#506965',
300: '#b9bc94',
100: '#f3f8f9',
},
},
},
@@ -39,7 +40,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap"
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Manrope:wght@600;700;800&display=swap"
rel="stylesheet"
/>
<link
@@ -50,65 +51,97 @@
<link rel="stylesheet" href="{{ url_for('static', filename='css/app.css') }}" />
{% block head %}{% endblock %}
</head>
<body class="min-h-screen bg-ink-100 text-ink-900 font-sans antialiased">
<header class="sticky top-0 z-30 bg-white/90 backdrop-blur border-b border-ink-300/60">
<div class="mx-auto max-w-6xl px-4 h-14 flex items-center justify-between">
<a href="{{ url_for('main.index') }}" class="flex items-center gap-2 font-semibold text-ink-900">
<span class="material-symbols-outlined text-brand-600">quiz</span>
<span>Тестирование</span>
</a>
<nav class="flex items-center gap-1 sm:gap-2 text-sm">
{% if current_user %}
<a href="{{ url_for('tests.tests_list_page') }}"
class="inline-flex items-center justify-center gap-1
min-w-10 min-h-10 px-2 sm:px-3 rounded-lg
text-ink-700 hover:bg-ink-100"
title="Каталог тестов" aria-label="Каталог тестов">
<span class="material-symbols-outlined text-base">list_alt</span>
<span class="hidden sm:inline">Тесты</span>
<body data-ui-variant="{{ ui_variant }}"
class="min-h-screen bg-ink-100 text-ink-900 font-sans antialiased ui-{{ ui_variant }}">
{% if ui_variant == 'legacy' %}
<div class="cabinet-app">
<header class="cabinet-header">
<div class="cabinet-header__inner">
<a href="{{ url_for('tests.tests_list_page') }}" class="cabinet-brand">
<img src="{{ url_for('static', filename='img/clinic-logo.png') }}"
alt="Логотип клиники" class="cabinet-brand__logo" />
<div>
<div class="cabinet-brand__title">Тестирование</div>
</div>
</a>
<a href="{{ url_for('settings.settings_page') }}"
class="inline-flex items-center justify-center gap-1
min-w-10 min-h-10 px-2 sm:px-3 rounded-lg
text-ink-700 hover:bg-ink-100"
title="Настройки" aria-label="Настройки">
<span class="material-symbols-outlined text-base">settings</span>
<span class="hidden sm:inline">Настройки</span>
</a>
<span class="hidden md:inline text-ink-500">
{{ current_user.full_name or current_user.login }}
<span class="text-ink-300">·</span>
<span class="text-brand-700">{{ current_user.role }}</span>
</span>
<form method="post" action="{{ url_for('auth.logout') }}" class="inline">
<button type="submit"
class="inline-flex items-center justify-center gap-1
min-w-10 min-h-10 px-2 sm:px-3 rounded-lg
text-ink-700 hover:bg-ink-100 transition"
title="Выйти" aria-label="Выйти">
<span class="material-symbols-outlined text-base">logout</span>
<span class="hidden sm:inline">Выйти</span>
</button>
</form>
{% else %}
<a href="{{ url_for('auth.login_page') }}"
class="inline-flex items-center gap-1 px-3 py-2 rounded-lg
text-brand-700 hover:bg-brand-50 transition min-h-10">
<span class="material-symbols-outlined text-base">login</span>
Войти
</a>
{% endif %}
</nav>
<div class="cabinet-header__actions">
{% if current_user %}
<span class="cabinet-user" title="{{ (current_user.full_name or current_user.login) ~ (' · ' ~ format_role(current_user.role) if format_role(current_user.role) else '') }}">
{{ format_name_short(current_user.full_name, current_user.login) }}
{% if format_role(current_user.role) %}<span class="cabinet-user__role"> · {{ format_role(current_user.role) }}</span>{% endif %}
</span>
<form method="post" action="{{ url_for('auth.logout') }}" class="inline">
<button type="submit" class="btn btn-ghost">Выйти</button>
</form>
{% else %}
<a href="{{ url_for('auth.login_page') }}" class="btn btn-ghost">Войти</a>
{% endif %}
</div>
</div>
</header>
<main class="cabinet-main">
{% block content scoped %}{% endblock %}
</main>
</div>
</header>
<main class="mx-auto max-w-6xl px-4 py-6">
{% block content %}{% endblock %}
</main>
<footer class="mx-auto max-w-6xl px-4 py-8 text-xs text-ink-500">
{% block footer %}testing-flask-app · Этап 1{% endblock %}
</footer>
{% else %}
<header class="sticky top-0 z-30 bg-white/90 backdrop-blur border-b border-ink-300/50">
<div class="mx-auto max-w-2xl px-4 h-14 flex items-center justify-between">
<a href="{{ url_for('main.index') }}" class="flex items-center gap-2 font-semibold text-ink-900">
<img src="{{ url_for('static', filename='img/clinic-logo.png') }}"
alt="Логотип клиники" class="h-7 w-7 object-contain" />
<span>Тестирование</span>
</a>
<nav class="flex items-center gap-1 sm:gap-2 text-sm">
{% if current_user %}
<a href="{{ url_for('tests.tests_list_page') }}"
class="inline-flex items-center justify-center gap-1
min-w-10 min-h-10 px-2 sm:px-3 rounded-lg
text-ink-700 hover:bg-ink-100"
title="Каталог тестов" aria-label="Каталог тестов">
<span class="material-symbols-outlined text-base">list_alt</span>
<span class="hidden sm:inline">Тесты</span>
</a>
<a href="{{ url_for('settings.settings_page') }}"
class="inline-flex items-center justify-center gap-1
min-w-10 min-h-10 px-2 sm:px-3 rounded-lg
text-ink-700 hover:bg-ink-100"
title="Настройки" aria-label="Настройки">
<span class="material-symbols-outlined text-base">settings</span>
<span class="hidden sm:inline">Настройки</span>
</a>
<span class="hidden md:inline text-ink-500">
{{ current_user.full_name or current_user.login }}
<span class="text-ink-300">·</span>
<span class="text-brand-700">{{ format_role(current_user.role) }}</span>
</span>
<form method="post" action="{{ url_for('auth.logout') }}" class="inline">
<button type="submit"
class="inline-flex items-center justify-center gap-1
min-w-10 min-h-10 px-2 sm:px-3 rounded-lg
text-ink-700 hover:bg-ink-100 transition"
title="Выйти" aria-label="Выйти">
<span class="material-symbols-outlined text-base">logout</span>
<span class="hidden sm:inline">Выйти</span>
</button>
</form>
{% else %}
<a href="{{ url_for('auth.login_page') }}"
class="inline-flex items-center gap-1 px-3 py-2 rounded-lg
text-brand-700 hover:bg-brand-50 transition min-h-10">
<span class="material-symbols-outlined text-base">login</span>
Войти
</a>
{% endif %}
</nav>
</div>
</header>
<main class="mx-auto max-w-2xl px-4 py-6">
{{ self.content() }}
</main>
<footer class="mx-auto max-w-2xl px-4 py-8 text-xs text-ink-500">
{% block footer %}testing-flask-app · Этап 1{% endblock %}
</footer>
{% endif %}
{% block scripts %}{% endblock %}
</body>