108 lines
2.6 KiB
TypeScript
108 lines
2.6 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { requireUser } from "@/lib/auth/requireUser";
|
|
import { db } from "@/lib/prisma";
|
|
import { issueCertificateIfEligible } from "@/lib/certificates";
|
|
import { refreshStudyRecommendations } from "@/lib/recommendations";
|
|
|
|
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(),
|
|
},
|
|
});
|
|
}
|
|
|
|
const certificateResult = nextCompleted
|
|
? await issueCertificateIfEligible(user.id, lesson.module.courseId)
|
|
: { certificateId: null, certificateNumber: null, newlyIssued: false };
|
|
|
|
revalidatePath(`/courses/${courseSlug}/learn`);
|
|
revalidatePath("/my-courses");
|
|
revalidatePath("/profile");
|
|
await refreshStudyRecommendations(user.id);
|
|
|
|
return {
|
|
success: true,
|
|
isCompleted: nextCompleted,
|
|
certificateId: certificateResult.certificateId,
|
|
certificateNumber: certificateResult.certificateNumber,
|
|
newlyIssuedCertificate: certificateResult.newlyIssued,
|
|
};
|
|
}
|