diff --git a/src/app/admin/courses/[courseId]/modules/[moduleId]/page.tsx b/src/app/admin/courses/[courseId]/modules/[moduleId]/page.tsx index 84a6f2c..f943ebc 100644 --- a/src/app/admin/courses/[courseId]/modules/[moduleId]/page.tsx +++ b/src/app/admin/courses/[courseId]/modules/[moduleId]/page.tsx @@ -10,13 +10,20 @@ interface Props { export default async function ModulePage({ params }: Props) { const { courseId, moduleId } = await params; - const module = await prisma.module.findUnique({ - where: { id: moduleId }, - include: { - course: { select: { title: true } }, - lessons: { orderBy: { order: "asc" } }, - }, - }); + const [module, allModules] = await Promise.all([ + prisma.module.findUnique({ + where: { id: moduleId }, + include: { + course: { select: { title: true } }, + lessons: { orderBy: { order: "asc" } }, + }, + }), + prisma.module.findMany({ + where: { courseId, NOT: { id: moduleId } }, + select: { id: true, title: true }, + orderBy: { order: "asc" }, + }), + ]); if (!module || module.courseId !== courseId) notFound(); @@ -41,7 +48,12 @@ export default async function ModulePage({ params }: Props) {

Уроки модуля

- + ); diff --git a/src/app/admin/courses/[courseId]/page.tsx b/src/app/admin/courses/[courseId]/page.tsx index 917ecdd..a49474b 100644 --- a/src/app/admin/courses/[courseId]/page.tsx +++ b/src/app/admin/courses/[courseId]/page.tsx @@ -4,6 +4,7 @@ import Link from "next/link"; import { CourseEditForm } from "@/components/admin/course-edit-form"; import { SortableModules } from "@/components/admin/sortable-modules"; import { EnrollmentManager } from "@/components/admin/enrollment-manager"; +import { CourseTree } from "@/components/admin/course-tree"; interface Props { params: Promise<{ courseId: string }>; @@ -18,7 +19,13 @@ export default async function CourseDetailPage({ params }: Props) { include: { modules: { orderBy: { order: "asc" }, - include: { _count: { select: { lessons: true } } }, + include: { + _count: { select: { lessons: true } }, + lessons: { + orderBy: { order: "asc" }, + select: { id: true, title: true, published: true, kinescopeId: true }, + }, + }, }, enrollments: { select: { userId: true, expiresAt: true }, @@ -73,6 +80,16 @@ export default async function CourseDetailPage({ params }: Props) { + {/* Course tree overview */} + {course.modules.length > 0 && ( +
+

+ Структура курса +

+ +
+ )} + {/* Access management */}

diff --git a/src/components/admin/sortable-modules.tsx b/src/components/admin/sortable-modules.tsx index 0f4cc29..07d23d4 100644 --- a/src/components/admin/sortable-modules.tsx +++ b/src/components/admin/sortable-modules.tsx @@ -22,6 +22,7 @@ import { createModule, deleteModule, updateModule, reorderModules } from "@/app/ interface Module { id: string; title: string; + description: string | null; order: number; _count: { lessons: number }; } @@ -29,6 +30,7 @@ interface Module { function SortableModule({ mod, courseId }: { mod: Module; courseId: string }) { const [editing, setEditing] = useState(false); const [editValue, setEditValue] = useState(mod.title); + const [editDesc, setEditDesc] = useState(mod.description ?? ""); const [pending, startTransition] = useTransition(); const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: mod.id }); @@ -69,31 +71,50 @@ function SortableModule({ mod, courseId }: { mod: Module; courseId: string }) { {editing ? ( -

- setEditValue(e.target.value)} - autoFocus - required - className="flex-1 px-2 py-1 text-sm" - style={{ border: "2px solid var(--foreground)", background: "var(--background)", outline: "none" }} + +
+ setEditValue(e.target.value)} + autoFocus + required + placeholder="Название модуля" + className="flex-1 px-2 py-1 text-sm" + style={{ border: "2px solid var(--foreground)", background: "var(--background)", outline: "none" }} + /> + + +
+