UI rework: modal dialogs, inline lab editing, manual creation, content management
- Dashboard: real stats (groups, students, labs, average grade), labs/groups summary lists, no placeholder tile - Lab page: view + edit combined — metadata form in modal, condition rendered as markdown, per-level variant tables with add/edit/delete dialogs, level rename/delete, student level/variant selectors with group filter - Labs list: create-lab dialog with manual level entry (code; title lines) - Groups: create-group dialog, add-student dialog (auto password, toast card) - Content: public /learn reader is the single place; admin buttons (new article with chapter/section create-or-select, rename/delete chapters and sections, move articles between sections, import zip) appear for admins; removed separate 'Контент' admin section - Buttons use btn classes instead of nav-link - Favicon: generated SVG book icon - Security: CSRF synchronizer token interceptor (replaced spring-security in web which broke logback under nested jars), session regenerated on login, hardened session cookie, gateway actuator limited to health,info - Jackson 3: nullable-safe request DTOs for labs (FAIL_ON_NULL_FOR_PRIMITIVES) - academic: POST /labs (manual create with levels), level add/rename/delete, content chapters/sections CRUD, article create/move/delete endpoints
This commit is contained in:
@@ -4,24 +4,51 @@
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1 class="page-title">Панель преподавателя</h1>
|
||||
|
||||
<div class="grid grid-stats">
|
||||
<div class="card card-body"><p class="stat-title">Группы</p><p class="stat-value" th:text="${groupCount}">0</p></div>
|
||||
<div class="card card-body"><p class="stat-title">Студенты</p><p class="stat-value" th:text="${studentCount}">0</p></div>
|
||||
<div class="card card-body"><p class="stat-title">Лабораторные</p><p class="stat-value text-muted">скоро</p></div>
|
||||
<div class="card card-body"><p class="stat-title">Лабораторные</p><p class="stat-value" th:text="${labCount}">0</p>
|
||||
<p class="hint" th:if="${labCount > 0}">опубликовано: <span th:text="${publishedLabs}">0</span></p></div>
|
||||
<div class="card card-body"><p class="stat-title">Средний балл</p>
|
||||
<p class="stat-value" th:if="${avgGrade != null}" th:text="${#numbers.formatDecimal(avgGrade, 1, 2)}">—</p>
|
||||
<p class="stat-value text-muted" th:if="${avgGrade == null}">—</p></div>
|
||||
</div>
|
||||
<div class="mt-8">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="section-title">Группы</h2>
|
||||
<a th:href="@{/admin/groups}" class="text-sm">Все группы →</a>
|
||||
|
||||
<div class="grid grid-2 mt-8">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="section-title">Лабораторные</h2>
|
||||
<a th:href="@{/admin/labs}" class="text-sm">Все →</a>
|
||||
</div>
|
||||
<div class="card card-flush">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr th:each="lab : ${labs}">
|
||||
<td><a th:href="@{/admin/labs/{id}(id=${lab.id})}" th:text="|ЛР ${lab.number}. ${lab.title}|">—</a></td>
|
||||
<td class="text-muted" th:text="${lab.variantCount} + ' вар.'">—</td>
|
||||
</tr>
|
||||
<tr th:if="${#lists.isEmpty(labs)}"><td class="empty">Лабораторных нет.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card card-flush">
|
||||
<table>
|
||||
<thead><tr><th>Название</th><th>Студентов</th></tr></thead>
|
||||
<tbody>
|
||||
<tr th:each="group : ${groups}"><td><a th:href="@{/admin/groups/{id}(id=${group.id})}" th:text="${group.name}">—</a></td><td th:text="${group.studentCount}">0</td></tr>
|
||||
<tr th:if="${#lists.isEmpty(groups)}"><td colspan="2" class="empty">Групп пока нет.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="section-title">Группы</h2>
|
||||
<a th:href="@{/admin/groups}" class="text-sm">Все →</a>
|
||||
</div>
|
||||
<div class="card card-flush">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr th:each="group : ${groups}">
|
||||
<td><a th:href="@{/admin/groups/{id}(id=${group.id})}" th:text="${group.name}">—</a></td>
|
||||
<td class="text-muted" th:text="${group.studentCount} + ' студ.'">—</td>
|
||||
</tr>
|
||||
<tr th:if="${#lists.isEmpty(groups)}"><td class="empty">Групп нет.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user