diff --git a/ROADMAP.md b/ROADMAP.md index 43f5a00..d9fdd59 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -21,20 +21,35 @@ --- -## Этап 1 — Курсы → Модули → Уроки (CRUD в админке) -**Цель:** могу создать полную структуру курса из браузера. +## Этап 1 — Курсы → Модули → Уроки (CRUD в админке) ✅ ЗАВЕРШЁН (07.04.2026) -- [ ] Prisma-схема: Course, Module, Lesson (с порядком, статусом published) -- [ ] Admin: список курсов, создать / редактировать / удалить курс -- [ ] Admin: список модулей внутри курса, drag-and-drop сортировка -- [ ] Admin: список уроков внутри модуля, drag-and-drop сортировка -- [ ] Admin: редактор урока с TipTap (заголовки, списки, цитаты, код, картинки, ссылки) -- [ ] Загрузка картинок в уроке → Hetzner Object Storage -- [ ] Поле для Kinescope ID в уроке (просто текстовое, без интеграции — это Этап 2) -- [ ] Публикация/скрытие курса и урока (черновик / опубликован) -- [ ] Управление доступом: выдать / забрать доступ к курсу для пользователя +- [x] Prisma-схема: Course, Module, Lesson (с порядком, статусом published) +- [x] Admin: список курсов, создать / редактировать / удалить курс +- [x] Admin: список модулей внутри курса, drag-and-drop сортировка +- [x] Admin: список уроков внутри модуля, drag-and-drop сортировка +- [x] Admin: редактор урока с TipTap (заголовки, списки, цитаты, код, картинки, ссылки) +- [x] Загрузка картинок в уроке → Hetzner Object Storage (second-brain-lms, Nuremberg) +- [x] Поле для Kinescope ID в уроке (просто текстовое, без интеграции — это Этап 2) +- [x] Публикация/скрытие курса и урока (черновик / опубликован) +- [x] Управление доступом: выдать / забрать доступ к курсу для пользователя +- [x] Дизайн в стиле Second Brain: Fira Mono, #F5F5F0, Aubade-карточки +- [x] Admin: таблица пользователей (/admin/users) -**Критерий готовности:** создаю курс «Obsidian PKM», добавляю 2 модуля, в каждом по 3 урока с текстом и картинкой, публикую. +--- + +--- + +## Этап 1.5 — Расширенное управление доступом (из emdesell) +**Цель:** способы выдачи доступа как в emdesell — ключи активации, срок доступа, категории. + +- [ ] **Ключи активации:** генерировать N одноразовых кодов для курса → ученик вводит код и получает доступ +- [ ] **Срок доступа:** поле `expiresAt` в `CourseEnrollment` + автоблокировка по дате +- [ ] **Категории курсов:** таблица `Category`, поле `categoryId` в `Course`, фильтрация в списке +- [ ] **Расширенный энролл:** Admin может дать доступ к нескольким курсам сразу (пакеты) +- [ ] **История доступа:** лог выдачи/отзыва доступа (кто, когда, каким методом) +- [ ] **Страница активации** для ученика: `/activate` — ввод кода → редирект на курс + +**Критерий готовности:** генерирую 10 ключей, отдаю ученику, ученик вводит — получает доступ с датой истечения через 3 месяца. --- diff --git a/src/app/(auth)/login/login-form.tsx b/src/app/(auth)/login/login-form.tsx index 95c229e..6511d21 100644 --- a/src/app/(auth)/login/login-form.tsx +++ b/src/app/(auth)/login/login-form.tsx @@ -39,9 +39,9 @@ export function LoginForm() { } return ( -