"use server"; import { prisma } from "@/lib/prisma"; import { headers } from "next/headers"; import { auth } from "@/lib/auth"; import { sendCourseAccessEmail } from "@/lib/email"; import { revalidatePath } from "next/cache"; async function requireAdmin() { const session = await auth.api.getSession({ headers: await headers() }); if (!session || session.user.role !== "admin") throw new Error("Forbidden"); return session; } export async function grantCourseAccess( userId: string, courseId: string, expiresAt: Date | null ): Promise<{ ok: true } | { error: string }> { try { const session = await requireAdmin(); 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) return { error: "Пользователь не найден" }; if (!course) return { error: "Курс не найден" }; const existing = await prisma.courseEnrollment.findUnique({ where: { userId_courseId: { userId, courseId } }, }); await prisma.courseEnrollment.upsert({ where: { userId_courseId: { userId, courseId } }, update: { expiresAt }, create: { userId, courseId, expiresAt }, }); await prisma.accessLog.create({ data: { courseId, userId, action: "granted", method: "quick", grantedById: session.user.id, }, }); // Send email only on new enrollment (not on update) if (!existing) { await sendCourseAccessEmail(user.email, user.name ?? user.email, course.title).catch( (e) => console.error("[enroll-action] sendCourseAccessEmail:", e) ); } revalidatePath("/admin/users"); revalidatePath(`/admin/users/${userId}`); return { ok: true }; } catch (e) { console.error("[enroll-action] grantCourseAccess:", e); return { error: "Произошла ошибка. Попробуйте ещё раз." }; } } export async function getPublishedCourses(): Promise<{ id: string; title: string }[]> { await requireAdmin(); return prisma.course.findMany({ where: { published: true }, select: { id: true, title: true }, orderBy: { title: "asc" }, }); }