fix test editor UI and test completition UI
This commit is contained in:
@@ -3,42 +3,54 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="test-detail-page attempt-review-page">
|
||||
<p class="link-back"><a href="/tests">← к списку тестов</a></p>
|
||||
<h1 class="font-headline" style="font-size:1.35rem;margin-top:0;">Разбор: {{ review.testTitle }}</h1>
|
||||
{% set tl = review.timeLimit %}
|
||||
{% set timestr = 'без ограничения' if tl is none or tl == 0 else (tl|string ~ ' мин') %}
|
||||
{% set rm = review.resultMode or 'end' %}
|
||||
{% set res = 'сразу' if rm == 'immediate' else 'в конце' %}
|
||||
{% set hint = 'недоступны' if rm != 'immediate' else ('вкл' if review.hintsEnabled else 'выкл') %}
|
||||
<p class="text-sm text-muted" style="margin:0.35rem 0 0.75rem;line-height:1.45;">
|
||||
Порог: {{ review.passingThreshold }}% · Вопросов: {{ review.totalQuestions }} · Время: {{ timestr }} · Результат: {{ res }} · Подсказки: {{ hint }}
|
||||
</p>
|
||||
<p>
|
||||
Правильно: <strong>{{ review.correctCount }}</strong> из {{ review.totalQuestions }}
|
||||
({{ review.percent }}%). Порог: {{ review.passingThreshold }}%.
|
||||
{% if review.passed %}
|
||||
<span class="text-muted">Зачёт.</span>
|
||||
{% else %}
|
||||
<span class="error-text">Незачёт.</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
<header class="attempt-review-page__header">
|
||||
<p class="link-back attempt-review-page__back"><a href="/tests">← к списку тестов</a></p>
|
||||
<h1 class="attempt-review-page__title font-headline">Разбор: {{ review.testTitle }}</h1>
|
||||
{% set tl = review.timeLimit %}
|
||||
{% set timestr = 'без ограничения' if tl is none or tl == 0 else (tl|string ~ ' мин') %}
|
||||
{% set rm = review.resultMode or 'end' %}
|
||||
{% set res = 'сразу' if rm == 'immediate' else 'в конце' %}
|
||||
{% set hint = 'недоступны' if rm != 'immediate' else ('вкл' if review.hintsEnabled else 'выкл') %}
|
||||
<p class="attempt-review-page__params text-muted text-sm">
|
||||
Порог: {{ review.passingThreshold }}% · Вопросов: {{ review.totalQuestions }} · Время: {{ timestr }} · Результат: {{ res }} · Подсказки: {{ hint }}
|
||||
</p>
|
||||
<div class="attempt-review-score {% if review.passed %}attempt-review-score--pass{% else %}attempt-review-score--fail{% endif %}">
|
||||
<div class="attempt-review-score__main">
|
||||
<span class="attempt-review-score__label">Итог</span>
|
||||
<p class="attempt-review-score__value">
|
||||
Правильно <strong>{{ review.correctCount }}</strong> из {{ review.totalQuestions }}
|
||||
<span class="attempt-review-score__percent">({{ review.percent }}%)</span>
|
||||
</p>
|
||||
<p class="attempt-review-score__threshold">Порог зачёта: {{ review.passingThreshold }}%</p>
|
||||
</div>
|
||||
<span class="attempt-review-score__verdict">{% if review.passed %}Зачёт{% else %}Незачёт{% endif %}</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="attempts-card-list">
|
||||
<div class="attempt-review-page__list">
|
||||
{% for q in review.questions %}
|
||||
<article class="attempt-card">
|
||||
<div class="attempt-card__meta">
|
||||
<span>{{ 'Верно' if q.isUserCorrect else 'Ошибка' }}</span>
|
||||
<article class="attempt-card attempt-review-card">
|
||||
<div class="attempt-review-card__head">
|
||||
<span class="attempt-review-card__num">{{ loop.index }}</span>
|
||||
<span class="attempt-review-card__badge {% if q.isUserCorrect %}attempt-review-card__badge--ok{% else %}attempt-review-card__badge--bad{% endif %}">
|
||||
{{ 'Верно' if q.isUserCorrect else 'Ошибка' }}
|
||||
</span>
|
||||
</div>
|
||||
<p style="margin-top:.25rem;"><strong>{{ loop.index }}.</strong> {{ q.text }}</p>
|
||||
<ul class="attempt-review-options">
|
||||
<p class="attempt-review-card__question">{{ q.text }}</p>
|
||||
{% if q.aiHint %}
|
||||
<div class="attempt-review-hint">
|
||||
<span class="attempt-review-hint__label">Подсказка</span>
|
||||
<p class="attempt-review-hint__text">{{ q.aiHint }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<ul class="attempt-review-options" role="list">
|
||||
{% for o in q.options %}
|
||||
<li class="attempt-review-option
|
||||
{% if o.isCorrect %}attempt-review-option--correct{% endif %}
|
||||
{% if o.selected and not o.isCorrect %}attempt-review-option--wrong{% endif %}">
|
||||
<span class="attempt-review-option__text">
|
||||
{% if o.selected %}☑{% else %}☐{% endif %}
|
||||
{{ o.text }}
|
||||
{% if o.isCorrect %}<strong> (правильный)</strong>{% endif %}
|
||||
<span class="attempt-review-option__mark" aria-hidden="true">{% if o.selected %}☑{% else %}☐{% endif %}</span>
|
||||
<span class="attempt-review-option__body">{{ o.text }}{% if o.isCorrect %}<span class="attempt-review-option__tag">верный ответ</span>{% endif %}</span>
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
@@ -115,12 +115,14 @@
|
||||
class="form-input" style="width:90px;" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="mt-3 grid gap-2 sm:grid-cols-3 items-end">
|
||||
<label class="inline-flex items-center gap-2 min-h-9">
|
||||
<div class="template-multi-row mt-3">
|
||||
<label class="inline-flex items-start gap-2 min-h-9 w-full">
|
||||
<input id="template-global-multi" type="checkbox"
|
||||
class="rounded border-ink-300 text-brand-600 focus:ring-brand-500" />
|
||||
<span class="text-sm">Несколько правильных ответов (все вопросы)</span>
|
||||
class="rounded border-ink-300 text-brand-600 focus:ring-brand-500 mt-0.5 shrink-0" />
|
||||
<span class="text-sm leading-snug">Несколько правильных ответов (все вопросы)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="template-correct-range-row mt-2 flex flex-wrap items-end gap-3">
|
||||
<label class="block">
|
||||
<span class="form-label">Правильных: от</span>
|
||||
<input id="template-min-correct" type="number" min="1" max="8" step="1" value="1"
|
||||
@@ -151,7 +153,7 @@
|
||||
</span>
|
||||
</summary>
|
||||
<div class="cabinet-disclosure__body">
|
||||
<section class="rounded-2xl bg-brand-50/60 border border-brand-100 p-4 sm:p-5 test-detail-ai-panel">
|
||||
<section class="rounded-2xl bg-brand-50/60 border border-brand-100 test-detail-ai-panel editor-generation-panel">
|
||||
|
||||
{# ── Заполнить через ИИ по теме ──────────────────────────── #}
|
||||
<div class="question-editor-block question-editor-block--first">
|
||||
@@ -168,11 +170,21 @@
|
||||
Сгенерировать вопросы (ИИ)
|
||||
</button>
|
||||
</div>
|
||||
<ul class="editor-generation-panel__notes mt-2 text-xs text-ink-500 space-y-1 list-disc pl-4 leading-snug">
|
||||
<li>Если в параметрах включены подсказки — после генерации будут созданы и тексты подсказок (черновик сохранится автоматически).</li>
|
||||
<li>Если уже есть версия с заполненным тестом — после «Сгенерировать» и сохранения весь прежний текст останется в старой версии в блоке «Версии».</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{# ── Проверить и улучшить ─────────────────────────────────── #}
|
||||
<div class="question-editor-block">
|
||||
<h3 class="test-detail-subsection__title">Проверить и улучшить</h3>
|
||||
<p class="text-xs text-ink-500 leading-snug mb-2">
|
||||
<span class="font-medium text-ink-600">Проверить тест</span> — ИИ прочитает вопросы и варианты и вернёт краткий вердикт и список замечаний; черновик не меняется.
|
||||
</p>
|
||||
<p class="text-xs text-ink-500 leading-snug mb-3">
|
||||
<span class="font-medium text-ink-600">Предложить улучшение</span> — ИИ предложит правки по каждому вопросу (было → стало); вы отметите, что применить к черновику.
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button id="ai-check"
|
||||
class="btn btn-ghost" type="button" style="min-height:43px;">
|
||||
@@ -190,6 +202,9 @@
|
||||
{# ── Документ в вопросы ──────────────────────────────────── #}
|
||||
<div class="question-editor-block test-detail-subsection test-detail-subsection--import">
|
||||
<h3 class="test-detail-subsection__title">Документ в вопросы</h3>
|
||||
<p class="text-xs text-ink-500 leading-snug mb-2">
|
||||
<span class="font-medium text-ink-600">Сгенерировать из документа</span> — из файла извлекается текст; ИИ составляет вопросы по содержанию и шаблону из «Параметров» (число вопросов, вариантов, несколько верных и т.д.), с учётом поля «Пожелания», если оно заполнено. Перед заменой откроется предпросмотр: «Применить» подставит черновик вместо текущих вопросов; дальше сохраните тест на сервер — подсказки и версии ведут себя так же, как при генерации по теме.
|
||||
</p>
|
||||
<label id="ai-import-dropzone"
|
||||
class="import-dropzone mt-2 flex flex-col w-full items-center justify-center gap-1
|
||||
px-4 py-5 rounded-xl bg-white border-2 border-dashed border-ink-300/70
|
||||
@@ -223,7 +238,7 @@
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<p id="ai-status" class="mt-3 text-sm text-ink-500 min-h-[1.25rem]"></p>
|
||||
<p id="ai-status" class="editor-generation-panel__status text-sm text-ink-500"></p>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user