Polish UX: auto-redirect on create, fix design consistency
- createModule now redirects to module page after creation - createLesson now redirects to lesson editor after creation - Regenerate Prisma client to fix missing types (category, accessLog, expiresAt) - Rewrite sortable-modules/lessons with Second Brain design tokens (remove amber/slate) - Rewrite lesson-editor toolbar and toggle with design tokens - Fix register page/form: replace amber theme with card-aubade design Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import { prisma } from "@/lib/prisma";
|
||||
import { headers } from "next/headers";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
async function requireAdmin() {
|
||||
const session = await auth.api.getSession({ headers: await headers() });
|
||||
@@ -17,8 +18,9 @@ export async function createModule(courseId: string, formData: FormData) {
|
||||
await requireAdmin();
|
||||
const title = formData.get("title") as string;
|
||||
const count = await prisma.module.count({ where: { courseId } });
|
||||
await prisma.module.create({ data: { courseId, title, order: count } });
|
||||
const mod = await prisma.module.create({ data: { courseId, title, order: count } });
|
||||
revalidatePath(`/admin/courses/${courseId}`);
|
||||
redirect(`/admin/courses/${courseId}/modules/${mod.id}`);
|
||||
}
|
||||
|
||||
export async function updateModule(moduleId: string, courseId: string, formData: FormData) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { prisma } from "@/lib/prisma";
|
||||
import { headers } from "next/headers";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
async function requireAdmin() {
|
||||
const session = await auth.api.getSession({ headers: await headers() });
|
||||
@@ -14,8 +15,9 @@ export async function createLesson(moduleId: string, courseId: string, formData:
|
||||
await requireAdmin();
|
||||
const title = formData.get("title") as string;
|
||||
const count = await prisma.lesson.count({ where: { moduleId } });
|
||||
await prisma.lesson.create({ data: { moduleId, title, order: count } });
|
||||
const lesson = await prisma.lesson.create({ data: { moduleId, title, order: count } });
|
||||
revalidatePath(`/admin/courses/${courseId}/modules/${moduleId}`);
|
||||
redirect(`/admin/courses/${courseId}/modules/${moduleId}/lessons/${lesson.id}`);
|
||||
}
|
||||
|
||||
export async function updateLesson(lessonId: string, courseId: string, moduleId: string, formData: FormData) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { notFound } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { SortableLessons } from "@/components/admin/sortable-lessons";
|
||||
|
||||
interface Props {
|
||||
@@ -23,22 +22,25 @@ export default async function ModulePage({ params }: Props) {
|
||||
|
||||
return (
|
||||
<div className="p-8 max-w-3xl">
|
||||
<nav className="text-sm text-slate-400 mb-6">
|
||||
<Link href="/admin/courses" className="hover:text-slate-600">Курсы</Link>
|
||||
<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:text-slate-600">{module.course.title}</Link>
|
||||
<Link href={`/admin/courses/${courseId}`} className="hover:underline">{module.course.title}</Link>
|
||||
<span className="mx-2">/</span>
|
||||
<span className="text-slate-700">{module.title}</span>
|
||||
<span style={{ color: "var(--foreground)" }}>{module.title}</span>
|
||||
</nav>
|
||||
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold text-slate-800">{module.title}</h1>
|
||||
<p className="text-slate-500 text-sm mt-0.5">{module.lessons.length} уроков</p>
|
||||
</div>
|
||||
<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="bg-white border border-slate-200 rounded-2xl p-6">
|
||||
<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} />
|
||||
</section>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user