"use server"; 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"; import { sendCourseAccessEmail } from "@/lib/email"; async function requireAdmin() { const session = await auth.api.getSession({ headers: await headers() }); if (!session || session.user.role !== "admin") throw new Error("Forbidden"); return session; } // ── Modules ────────────────────────────────────────────────────────────────── 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 } }); 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) { await requireAdmin(); const title = formData.get("title") as string; await prisma.module.update({ where: { id: moduleId }, data: { title } }); revalidatePath(`/admin/courses/${courseId}`); } export async function deleteModule(moduleId: string, courseId: string) { await requireAdmin(); await prisma.module.delete({ where: { id: moduleId } }); revalidatePath(`/admin/courses/${courseId}`); } export async function reorderModules(courseId: string, orderedIds: string[]) { await requireAdmin(); await Promise.all( orderedIds.map((id, index) => prisma.module.update({ where: { id }, data: { order: index } }) ) ); revalidatePath(`/admin/courses/${courseId}`); } // ── Enrollment ─────────────────────────────────────────────────────────────── export async function grantAccess( courseId: string, userId: string, expiresAt?: string | null, note?: string ) { const session = await requireAdmin(); await prisma.courseEnrollment.upsert({ where: { userId_courseId: { userId, courseId } }, update: { expiresAt: expiresAt ? new Date(expiresAt) : null }, create: { userId, courseId, expiresAt: expiresAt ? new Date(expiresAt) : null }, }); await prisma.accessLog.create({ data: { courseId, userId, action: "granted", method: "manual", grantedById: session.user.id, note: note || null, }, }); // Send email notification const [user, course] = await Promise.all([ prisma.user.findUnique({ where: { id: userId }, select: { email: true, name: true } }), prisma.course.findUnique({ where: { id: courseId }, select: { title: true } }), ]); if (user && course) { await sendCourseAccessEmail(user.email, user.name, course.title); } revalidatePath(`/admin/courses/${courseId}`); } export async function revokeAccess(courseId: string, userId: string, note?: string) { const session = await requireAdmin(); await prisma.courseEnrollment.delete({ where: { userId_courseId: { userId, courseId } }, }); await prisma.accessLog.create({ data: { courseId, userId, action: "revoked", method: "manual", grantedById: session.user.id, note: note || null, }, }); revalidatePath(`/admin/courses/${courseId}`); }