93 lines
2.0 KiB
TypeScript
93 lines
2.0 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { requireUser } from "@/lib/auth/requireUser";
|
|
import { db } from "@/lib/prisma";
|
|
|
|
type ToggleLessonCompleteInput = {
|
|
courseSlug: string;
|
|
lessonId: string;
|
|
};
|
|
|
|
export async function toggleLessonComplete({ courseSlug, lessonId }: ToggleLessonCompleteInput) {
|
|
const user = await requireUser();
|
|
|
|
if (!user?.id) {
|
|
return { success: false, error: "Unauthorized" };
|
|
}
|
|
|
|
const lesson = await db.lesson.findUnique({
|
|
where: { id: lessonId },
|
|
select: {
|
|
id: true,
|
|
module: {
|
|
select: {
|
|
courseId: true,
|
|
course: {
|
|
select: {
|
|
slug: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!lesson || lesson.module.course.slug !== courseSlug) {
|
|
return { success: false, error: "Lesson not found" };
|
|
}
|
|
|
|
const enrollment = await db.enrollment.findUnique({
|
|
where: {
|
|
userId_courseId: {
|
|
userId: user.id,
|
|
courseId: lesson.module.courseId,
|
|
},
|
|
},
|
|
select: { id: true },
|
|
});
|
|
|
|
if (!enrollment) {
|
|
return { success: false, error: "Not enrolled in this course" };
|
|
}
|
|
|
|
const existingProgress = await db.userProgress.findUnique({
|
|
where: {
|
|
userId_lessonId: {
|
|
userId: user.id,
|
|
lessonId,
|
|
},
|
|
},
|
|
select: {
|
|
id: true,
|
|
isCompleted: true,
|
|
},
|
|
});
|
|
|
|
const nextCompleted = !existingProgress?.isCompleted;
|
|
|
|
if (existingProgress) {
|
|
await db.userProgress.update({
|
|
where: { id: existingProgress.id },
|
|
data: {
|
|
isCompleted: nextCompleted,
|
|
finishedAt: nextCompleted ? new Date() : null,
|
|
lastPlayedAt: new Date(),
|
|
},
|
|
});
|
|
} else {
|
|
await db.userProgress.create({
|
|
data: {
|
|
userId: user.id,
|
|
lessonId,
|
|
isCompleted: true,
|
|
finishedAt: new Date(),
|
|
},
|
|
});
|
|
}
|
|
|
|
revalidatePath(`/courses/${courseSlug}/learn`);
|
|
|
|
return { success: true, isCompleted: nextCompleted };
|
|
}
|