CHanged Event admin layout

This commit is contained in:
PxlLoewe
2025-03-10 18:11:28 -07:00
parent 77b266e0bf
commit c01e618a56
17 changed files with 918 additions and 170 deletions

View File

@@ -2,6 +2,8 @@ import { getMoodleCourseCompletionStatus, getMoodleUserById } from "./moodle";
import { CronJob } from "cron";
import { prisma } from "@repo/db";
import { eventCompleted } from "@repo/ui/helper";
import { sendCourseCompletedEmail } from "modules/mail";
import { handleParticipantFinished } from "modules/event";
const syncMoodleIds = async () => {
try {
@@ -57,7 +59,7 @@ const updateParticipantMoodleResults = async () => {
);
if (quizzResult?.completionstatus?.completed === true) {
await prisma.participant.update({
return prisma.participant.update({
where: {
id: p.id,
},
@@ -65,7 +67,7 @@ const updateParticipantMoodleResults = async () => {
finisherMoodleCurseCompleted: true,
statusLog: {
push: {
event: "Finisher course completed",
event: "Moodle-Kurs abgeschlossen",
timestamp: new Date(),
user: "system",
},
@@ -77,33 +79,40 @@ const updateParticipantMoodleResults = async () => {
);
};
export const checkedFinishedParticipants = async () => {
export const checkFinishedParticipants = async () => {
console.log("Checking finished participants");
const participantsPending = await prisma.participant.findMany({
where: {
finished: false,
completetionWorkflowFinished: false,
},
include: {
Event: true,
User: true,
},
});
participantsPending.forEach(async (p) => {
if (!p.User) return;
if (!p.User.moodleId) return;
const completed = eventCompleted(p.Event, p);
if (!completed) return;
handleParticipantFinished(p.Event, p, p.User);
});
};
CronJob.from({ cronTime: "0 * * * *", onTick: syncMoodleIds, start: true });
CronJob.from({
cronTime: "*/5 * * * *",
cronTime: "*/1 * * * *",
onTick: async () => {
console.log("Updating participant moodle results");
await updateParticipantMoodleResults();
await checkFinishedParticipants();
},
start: true,
});
updateParticipantMoodleResults();
const debug = async () => {
await updateParticipantMoodleResults();
await checkFinishedParticipants();
};
debug();

View File

@@ -1,4 +1,5 @@
import { Event, Participant, prisma, User } from "@repo/db";
import { sendCourseCompletedEmail } from "modules/mail";
export const handleParticipantFinished = async (
event: Event,
@@ -11,9 +12,6 @@ export const handleParticipantFinished = async (
},
});
//TODO: Send Discord Message
//TODO: Send Email
await prisma.user.update({
where: {
id: user.id,
@@ -22,19 +20,24 @@ export const handleParticipantFinished = async (
badges: {
push: event.finishedBadges,
},
permissions: event.finishedPermissions,
permissions: {
push: event.finishedPermissions,
},
},
});
//TODO: Send Discord Message
await sendCourseCompletedEmail(user.email, user, event);
await prisma.participant.update({
where: {
id: participant.id,
},
data: {
finished: true,
completetionWorkflowFinished: true,
statusLog: {
push: {
event: "Event finished",
event: "Berechtigungen und Badges vergeben",
timestamp: new Date(),
user: "system",
},

View File

@@ -0,0 +1,21 @@
import * as React from "react";
import { Event, User } from "@repo/db";
import { Html, Button, render } from "@react-email/components";
const Template = ({ event, user }: { user: User; event: Event }) => (
<Html lang="en">
<p>You completed the Course {event.name}</p>
<p>Congratulation</p>
</Html>
);
export function renderCourseCompleted({
user,
event,
}: {
user: User;
event: Event;
}) {
return render(<Template event={event} user={user} />);
}

View File

@@ -0,0 +1,59 @@
import { Event, User } from "@repo/db";
import nodemailer from "nodemailer";
import { renderCourseCompleted } from "./mail-templates/CourseCompleted";
let transporter: nodemailer.Transporter | null = null;
const initTransporter = () => {
if (!process.env.MAIL_SERVER)
return console.error("MAIL_SERVER is not defined");
if (!process.env.MAIL_PORT) return console.error("MAIL_PORT is not defined");
if (!process.env.MAIL_USER) return console.error("MAIL_USER is not defined");
if (!process.env.MAIL_PASSWORD)
return console.error("MAIL_PASSWORD is not defined");
transporter = nodemailer.createTransport({
host: process.env.MAIL_SERVER,
port: parseInt(process.env.MAIL_PORT),
secure: true, // true for 465, false for other ports
auth: {
user: process.env.MAIL_USER,
pass: process.env.MAIL_PASSWORD,
},
});
transporter.on("error", (err) => {
console.error("Mail occurred:", err);
});
transporter.on("idle", () => {
console.log("Mail Idle");
});
};
initTransporter();
export const sendCourseCompletedEmail = async (
to: string,
user: User,
event: Event,
) => {
const emailHtml = await renderCourseCompleted({ user, event });
if (!transporter) {
console.error("Transporter is not initialized");
return;
}
transporter.sendMail(
{
from: process.env.MAIL_USER,
to,
subject: `Congratulations ${user.firstname} on completing ${event.name}`,
html: emailHtml,
},
(error, info) => {
if (error) {
console.error("Error sending email:", error);
} else {
}
},
);
};