diff --git a/package-lock.json b/package-lock.json
index 5e7eaba..52f5638 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,6 +21,7 @@
"@tiptap/extension-image": "^3.22.2",
"@tiptap/extension-link": "^3.22.2",
"@tiptap/extension-placeholder": "^3.22.2",
+ "@tiptap/extension-underline": "^3.22.2",
"@tiptap/pm": "^3.22.2",
"@tiptap/react": "^3.22.2",
"@tiptap/starter-kit": "^3.22.2",
diff --git a/package.json b/package.json
index bce00cd..11c5385 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@tiptap/extension-image": "^3.22.2",
"@tiptap/extension-link": "^3.22.2",
"@tiptap/extension-placeholder": "^3.22.2",
+ "@tiptap/extension-underline": "^3.22.2",
"@tiptap/pm": "^3.22.2",
"@tiptap/react": "^3.22.2",
"@tiptap/starter-kit": "^3.22.2",
diff --git a/src/app/admin/courses/[courseId]/modules/[moduleId]/lessons/[lessonId]/page.tsx b/src/app/admin/courses/[courseId]/modules/[moduleId]/lessons/[lessonId]/page.tsx
index f700e0d..abde314 100644
--- a/src/app/admin/courses/[courseId]/modules/[moduleId]/lessons/[lessonId]/page.tsx
+++ b/src/app/admin/courses/[courseId]/modules/[moduleId]/lessons/[lessonId]/page.tsx
@@ -12,19 +12,30 @@ interface Props {
export default async function LessonEditorPage({ params }: Props) {
const { courseId, moduleId, lessonId } = await params;
- const lesson = await prisma.lesson.findUnique({
- where: { id: lessonId },
- include: {
- files: { orderBy: { createdAt: "asc" } },
- homework: true,
- module: {
- include: { course: { select: { title: true, slug: true } } },
+ const [lesson, siblings] = await Promise.all([
+ prisma.lesson.findUnique({
+ where: { id: lessonId },
+ include: {
+ files: { orderBy: { createdAt: "asc" } },
+ homework: true,
+ module: {
+ include: { course: { select: { title: true, slug: true } } },
+ },
},
- },
- });
+ }),
+ prisma.lesson.findMany({
+ where: { moduleId },
+ orderBy: { order: "asc" },
+ select: { id: true, title: true },
+ }),
+ ]);
if (!lesson || lesson.moduleId !== moduleId) notFound();
+ const idx = siblings.findIndex((l) => l.id === lessonId);
+ const prevLesson = idx > 0 ? siblings[idx - 1] : null;
+ const nextLesson = idx < siblings.length - 1 ? siblings[idx + 1] : null;
+
return (
diff --git a/src/components/admin/lesson-editor.tsx b/src/components/admin/lesson-editor.tsx
index 44fa284..3982c8a 100644
--- a/src/components/admin/lesson-editor.tsx
+++ b/src/components/admin/lesson-editor.tsx
@@ -5,8 +5,10 @@ import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Image from "@tiptap/extension-image";
import Link from "@tiptap/extension-link";
+import Underline from "@tiptap/extension-underline";
import Placeholder from "@tiptap/extension-placeholder";
-import { Save, Eye, FileUp } from "lucide-react";
+import { Save, Eye, FileUp, ChevronLeft, ChevronRight } from "lucide-react";
+import { useRouter } from "next/navigation";
import { saveLesson } from "@/app/admin/courses/[courseId]/modules/[moduleId]/lessons/[lessonId]/actions";
interface LessonData {
@@ -17,17 +19,27 @@ interface LessonData {
published: boolean;
}
+interface SiblingLesson {
+ id: string;
+ title: string;
+}
+
export function LessonEditor({
lesson,
courseId,
moduleId,
courseSlug,
+ prevLesson,
+ nextLesson,
}: {
lesson: LessonData;
courseId: string;
moduleId: string;
courseSlug: string;
+ prevLesson?: SiblingLesson | null;
+ nextLesson?: SiblingLesson | null;
}) {
+ const router = useRouter();
const [title, setTitle] = useState(lesson.title);
const [kinescopeId, setKinescopeId] = useState(lesson.kinescopeId);
const [published, setPublished] = useState(lesson.published);
@@ -50,6 +62,7 @@ export function LessonEditor({
const editor = useEditor({
extensions: [
StarterKit,
+ Underline,
Image.configure({ inline: false }),
Link.configure({ openOnClick: false }),
Placeholder.configure({ placeholder: "Начните писать текст урока..." }),
@@ -108,6 +121,18 @@ export function LessonEditor({
input.click();
}, [editor]);
+ const addLink = useCallback(() => {
+ if (!editor) return;
+ const prev = editor.getAttributes("link").href as string | undefined;
+ const url = window.prompt("Ссылка:", prev ?? "https://");
+ if (url === null) return;
+ if (url === "") {
+ editor.chain().focus().unsetLink().run();
+ } else {
+ editor.chain().focus().setLink({ href: url, target: "_blank" }).run();
+ }
+ }, [editor]);
+
function handleSave() {
if (!editor) return;
startTransition(async () => {
@@ -122,44 +147,74 @@ export function LessonEditor({
});
}
+ function navigateTo(lessonId: string) {
+ router.push(`/admin/courses/${courseId}/modules/${moduleId}/lessons/${lessonId}`);
+ }
+
return (
{/* Header controls */}
-
-