Files
lms-sb/src/app/curator/homework/[submissionId]/actions.ts
T
admins c64f393a7b Implement platform settings (Stage 9)
- Wire settings to actual platform behavior: maintenance mode, registration toggle,
  notification emails, curator feedback emails, email verification flag
- Add logo (logoUrl, showLogo) and social network links (YouTube, VK, Telegram) settings
- Show logo + school name dynamically in student layout header
- Add footer to student layout with org requisites and social links
- Register page: read settings server-side, validate terms checkbox with legal links
- Login page: show notice when redirected from closed registration
- Settings form: add Logo and Social Networks sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 15:31:10 +05:00

116 lines
3.3 KiB
TypeScript

"use server";
import { prisma } from "@/lib/prisma";
import { auth } from "@/lib/auth";
import { headers } from "next/headers";
import { revalidatePath } from "next/cache";
import { sendFeedbackReceivedEmail } from "@/lib/email";
import { getSetting, asBool } from "@/lib/settings";
async function requireCurator() {
const session = await auth.api.getSession({ headers: await headers() });
if (!session || (session.user.role !== "curator" && session.user.role !== "admin")) {
throw new Error("Forbidden");
}
return session;
}
export async function submitFeedback(
submissionId: string,
data: {
text: string;
files?: { name: string; url: string; size: number }[];
audioUrl?: string | null;
action: "approve" | "reject";
}
) {
const session = await requireCurator();
const status = data.action === "approve" ? "APPROVED" : "REJECTED";
const submission = await prisma.homeworkSubmission.findUnique({
where: { id: submissionId },
include: {
user: { select: { id: true, email: true, name: true } },
homework: {
include: {
lesson: {
select: {
title: true,
id: true,
module: { select: { course: { select: { slug: true } } } },
},
},
},
},
},
});
if (!submission) throw new Error("Submission not found");
await prisma.$transaction(async (tx) => {
await tx.homeworkFeedback.create({
data: {
submissionId,
curatorId: session.user.id,
text: data.text,
files: data.files ?? [],
audioUrl: data.audioUrl ?? null,
},
});
await tx.homeworkSubmission.update({
where: { id: submissionId },
data: { status, statusAt: new Date() },
});
if (status === "APPROVED") {
await tx.lessonProgress.upsert({
where: {
userId_lessonId: {
userId: submission.user.id,
lessonId: submission.homework.lesson.id,
},
},
create: {
userId: submission.user.id,
lessonId: submission.homework.lesson.id,
},
update: {},
});
}
});
const { lesson } = submission.homework;
const notifySetting = await getSetting("notifyStudentOnFeedback");
if (asBool(notifySetting)) {
const lessonUrl = `${process.env.BETTER_AUTH_URL ?? "https://school.second-brain.ru"}/courses/${lesson.module.course.slug}/lessons/${lesson.id}`;
await sendFeedbackReceivedEmail(
submission.user.email,
submission.user.name,
lesson.title,
data.text,
lessonUrl
);
}
revalidatePath("/curator/homework");
revalidatePath(`/curator/homework/${submissionId}`);
revalidatePath(`/courses/${lesson.module.course.slug}/lessons/${lesson.id}`);
revalidatePath(`/courses/${lesson.module.course.slug}`);
revalidatePath("/dashboard");
}
export async function setReviewing(submissionId: string) {
await requireCurator();
await prisma.homeworkSubmission.update({
where: { id: submissionId },
data: { status: "REVIEWING", statusAt: new Date() },
});
revalidatePath("/curator/homework");
revalidatePath(`/curator/homework/${submissionId}`);
}
export async function deleteSubmission(submissionId: string) {
await requireCurator();
await prisma.homeworkSubmission.delete({ where: { id: submissionId } });
revalidatePath("/curator/homework");
}