d8be6d6d95
Prisma 7 wraps Json fields in proxy objects that RSC cannot serialize. Fix: select specific columns (exclude content) in module page, and JSON.parse/stringify lesson content before passing to client. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
import { prisma } from "@/lib/prisma";
|
||
import { notFound } from "next/navigation";
|
||
import Link from "next/link";
|
||
import { SortableLessons } from "@/components/admin/sortable-lessons";
|
||
|
||
interface Props {
|
||
params: Promise<{ courseId: string; moduleId: string }>;
|
||
}
|
||
|
||
export default async function ModulePage({ params }: Props) {
|
||
const { courseId, moduleId } = await params;
|
||
|
||
const [module, allModules] = await Promise.all([
|
||
prisma.module.findUnique({
|
||
where: { id: moduleId },
|
||
include: {
|
||
course: { select: { title: true } },
|
||
lessons: {
|
||
orderBy: { order: "asc" },
|
||
select: { id: true, title: true, order: true, published: true, kinescopeId: true },
|
||
},
|
||
},
|
||
}),
|
||
prisma.module.findMany({
|
||
where: { courseId, NOT: { id: moduleId } },
|
||
select: { id: true, title: true },
|
||
orderBy: { order: "asc" },
|
||
}),
|
||
]);
|
||
|
||
if (!module || module.courseId !== courseId) notFound();
|
||
|
||
return (
|
||
<div className="p-8 max-w-3xl">
|
||
<nav className="text-xs mb-6 uppercase tracking-widest" style={{ color: "var(--muted-foreground)" }}>
|
||
<Link href="/admin/courses" className="hover:underline">Курсы</Link>
|
||
<span className="mx-2">/</span>
|
||
<Link href={`/admin/courses/${courseId}`} className="hover:underline">{module.course.title}</Link>
|
||
<span className="mx-2">/</span>
|
||
<span style={{ color: "var(--foreground)" }}>{module.title}</span>
|
||
</nav>
|
||
|
||
<div className="mb-6">
|
||
<h1 className="text-2xl font-bold">{module.title}</h1>
|
||
<p className="text-sm mt-1" style={{ color: "var(--muted-foreground)" }}>
|
||
{module.lessons.length} {module.lessons.length === 1 ? "урок" : module.lessons.length < 5 ? "урока" : "уроков"}
|
||
</p>
|
||
</div>
|
||
|
||
<section className="card-aubade p-6">
|
||
<p className="text-xs font-bold uppercase tracking-widest mb-5" style={{ color: "var(--muted-foreground)" }}>
|
||
Уроки модуля
|
||
</p>
|
||
<SortableLessons
|
||
courseId={courseId}
|
||
moduleId={moduleId}
|
||
lessons={module.lessons}
|
||
otherModules={allModules}
|
||
/>
|
||
</section>
|
||
</div>
|
||
);
|
||
}
|