12 KiB
Предложение по редизайну страницы «Создание теста»
Ветка: dev-new-design-page-createtest
Затронутые файлы: frontend/src/components/TestForm/index.tsx, frontend/src/pages/TestCreate/index.tsx (через общий компонент), частично frontend/src/api/llm.ts (расширение сигнатуры generate).
Бэкенд: менять не обязательно — у нас уже есть POST /api/llm/generate (см. backend/app/api/llm.py); нужно лишь принять параметры questions_count и answers_count.
1. Цель
Сделать форму создания теста читаемее: разбить «полотно» на три смысловые группы и чётко отделить редактируемое содержимое от служебных команд. Заодно — дать пользователю возможность сгенерировать тест сразу нужной формы, не нащёлкивая «+ вопрос» / «+ вариант» вручную.
2. Текущее состояние (что есть)
TestForm/index.tsx сейчас визуально устроен так:
┌─────────────────────────────────────────┐
│ ← Назад Заголовок │
├─────────────────────────────────────────┤
│ Card «Основные настройки» │
│ • название │
│ • описание │
│ • порог зачёта │
│ • таймер │
│ • разрешить возврат │
├─────────────────────────────────────────┤
│ [Сгенерировать с AI] [Проверить тест] │ ← вне карточек, между мета и вопросами
├─────────────────────────────────────────┤
│ Card «Вопрос 1» │
│ ... │
│ Card «Вопрос N» │
│ [+ Добавить вопрос] │
├─────────────────────────────────────────┤
│ [Создать тест] [Отмена] │
└─────────────────────────────────────────┘
Замечания:
- AI-кнопки висят «в воздухе» — не видно, к какой части формы они относятся.
- «Сгенерировать с AI» жёстко создаёт 7 вопросов (см.
TestForm/index.tsx:123—llmApi.generate(title.trim(), 7)), без выбора структуры. - В fallback-сообщении ошибки упоминается «API ключ в настройках» (
TestForm/index.tsx:244).
3. Что меняем
3.1. Три смысловых блока
| Блок | Содержит | Визуально |
|---|---|---|
| Метаинформация | название, описание, порог, таймер, навигация назад | Card title="Метаинформация" |
| Содержание | кнопка «Сгенерировать с AI», список вопросов, «+ Добавить вопрос» | Card title="Содержание" (вложенные карточки вопросов остаются) |
| Команды | «Создать тест», «Отмена», «Проверить тест» | блок Space снизу страницы |
Кнопка «Проверить тест» логически — это команда над всем тестом, поэтому переезжает в нижнюю панель команд. Кнопка «Сгенерировать с AI» становится первым элементом блока «Содержание» — у неё там естественное место (она формирует именно содержание).
3.2. Wireframe после редизайна
┌─────────────────────────────────────────┐
│ ← Назад Создание теста │
├─────────────────────────────────────────┤
│ Card «Метаинформация» │
│ • название │
│ • описание │
│ • порог зачёта │
│ • таймер │
│ • разрешить возврат │
├─────────────────────────────────────────┤
│ Card «Содержание» │
│ ┌─ AI-генерация ────────────────────┐ │
│ │ тема: [_________________] │ │
│ │ вопросов: [7] вариантов: [3] │ │
│ │ [🤖 Сгенерировать] │ │
│ └──────────────────────────────────┘ │
│ │
│ Card «Вопрос 1» ... │
│ Card «Вопрос N» ... │
│ [+ Добавить вопрос] │
├─────────────────────────────────────────┤
│ [Создать тест] [Проверить тест] [Отмена] │
└─────────────────────────────────────────┘
3.3. Форма AI-генерации с тремя полями
Внутри блока «Содержание» — компактный мини-блок (не модалка) с тремя полями:
| Поле | Тип | По умолчанию | Лимиты |
|---|---|---|---|
| Тема | Input |
значение title из метаинформации (auto-fill) |
непустая |
| Количество вопросов | InputNumber |
7 | 1…30 |
| Количество вариантов на вопрос | InputNumber |
3 | 2…8 |
Кнопка «Сгенерировать» запускает текущий поток handleGenerate (модалка-превью → «Применить все вопросы»), но передаёт оба числа в API. Превью показывает то же, что и сейчас.
Поведение существующих кнопок «Улучшить» и «Дистракторы» внутри карточки вопроса не меняется — они и так локальные.
3.4. Уход от текста про API-ключи
Единственное место в форме, где упоминается ключ, — fallback-сообщение об ошибке:
// TestForm/index.tsx:244
setReviewText('Не удалось получить рекомендации. Проверьте API ключ в настройках.')
Заменяем на нейтральное:
setReviewText('Не удалось получить рекомендации. Попробуйте позже или обратитесь к администратору.')
Сама страница Settings остаётся как есть — это её прямое назначение, и её редактируют только администраторы.
4. План работ (чек-лист для исполнителя)
- Backend (опционально, если ещё не принимает параметры): расширить схему
LLMGenerateRequestвbackend/app/schemas/llm.pyполямиquestions_count: int = 7,answers_count: int = 3; передать их в промпт сервисаapp/services/llm.py. - API-клиент: в
frontend/src/api/llm.tsобновить сигнатуруgenerate(topic, questionsCount, answersCount). - TestForm: обернуть текущий блок «Основные настройки» в
Card title="Метаинформация". - TestForm: создать новый
Card title="Содержание", в него поместить:- мини-блок AI-генерации (3 поля + кнопка),
- текущий
Form.Listвопросов с кнопкой «+ Добавить вопрос».
- TestForm: убрать текущий ряд из двух AI-кнопок между мета и вопросами; «Проверить тест» перенести в нижнюю панель команд рядом с «Создать»/«Отмена».
- TestForm: добавить локальный стейт
aiQuestionsCount,aiAnswersCount, инициализация: 7 / 3. - TestForm: в
handleGenerateпередавать оба числа; приПрименитьсоздавать соответствующее число пустых ответов в каждом вопросе (если бэк прислал меньше — добить пустыми, если больше — обрезать). - TestForm: заменить fallback-текст про API-ключ.
- Прогнать
docker compose up, проверить вручную: создание с дефолтами, генерация на 5 вопросов × 4 ответа, проверка теста, отмена. - Документ-шаг в
DOC/ШАГИ/ШАГ_<дата>_<NNN>.mdпо факту выполнения.
5. Что не делаем в этой ветке
- Не трогаем форму редактирования (
TestEdit) — формально использует тот жеTestForm, но эффект редизайна нужно отдельно проверить с уже заполненными вопросами и опциями версионирования. - Не меняем поведение
Form.Listвалидации (минимум 7 вопросов / 3 варианта) — это отдельная история. - Не вводим drag-and-drop переупорядочивание вопросов.
6. Открытые вопросы для согласования
- Нужно ли визуально подсвечивать мини-блок генерации (фон, бордер), чтобы он отличался от карточек вопросов?
- После применения сгенерированных вопросов — нужно ли скрывать мини-блок, чтобы он не путал?
- Лимиты «1…30 вопросов / 2…8 вариантов» — устраивают или нужны другие?