# Предложение по редизайну страницы «Создание теста» **Ветка:** `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-сообщение об ошибке: ```ts // TestForm/index.tsx:244 setReviewText('Не удалось получить рекомендации. Проверьте API ключ в настройках.') ``` Заменяем на нейтральное: ```ts 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/ШАГИ/ШАГ_<дата>_.md` по факту выполнения. ## 5. Что **не** делаем в этой ветке - Не трогаем форму редактирования (`TestEdit`) — формально использует тот же `TestForm`, но эффект редизайна нужно отдельно проверить с уже заполненными вопросами и опциями версионирования. - Не меняем поведение `Form.List` валидации (минимум 7 вопросов / 3 варианта) — это отдельная история. - Не вводим drag-and-drop переупорядочивание вопросов. ## 6. Открытые вопросы для согласования 1. Нужно ли визуально подсвечивать мини-блок генерации (фон, бордер), чтобы он отличался от карточек вопросов? 2. После применения сгенерированных вопросов — нужно ли скрывать мини-блок, чтобы он не путал? 3. Лимиты «1…30 вопросов / 2…8 вариантов» — устраивают или нужны другие?