continued the kita-planer

This commit is contained in:
t.indorf
2026-05-08 14:32:14 +02:00
parent b686e714ff
commit 7aff691803
85 changed files with 9434 additions and 588 deletions
+52 -54
View File
@@ -15,10 +15,7 @@ import { prisma } from "@/lib/prisma";
const BASE_URL =
process.env.NEXTAUTH_URL ?? process.env.AUTH_URL ?? "http://localhost:3000";
export async function triggerAlertAction(
assignmentId: string,
parentUserId: string,
) {
export async function triggerAlertAction(assignmentId: string) {
const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
const kitaId = session.user.kitaId!;
@@ -36,6 +33,19 @@ export async function triggerAlertAction(
id: true,
firstName: true,
lastName: true,
family: {
select: {
users: {
where: { role: UserRole.ELTERN },
select: {
id: true,
email: true,
firstName: true,
lastName: true,
},
},
},
},
},
},
},
@@ -50,7 +60,9 @@ export async function triggerAlertAction(
return { error: "Notdienst-Einteilung wurde nicht gefunden." };
}
if (!parentUserId) {
const parents = assignment.child.family.users;
if (parents.length === 0) {
return { error: "Kein Elternteil für diesen Notdienst hinterlegt." };
}
@@ -59,64 +71,50 @@ export async function triggerAlertAction(
return { error: mailConfigError };
}
const parentLink = await prisma.childParent.findFirst({
where: {
kitaId,
childId: assignment.child.id,
userId: parentUserId,
},
include: {
user: {
select: {
email: true,
firstName: true,
lastName: true,
},
},
},
});
if (!parentLink) {
return { error: "Das Elternteil passt nicht zu dieser Einteilung." };
}
const token = crypto.randomUUID();
await prisma.notdienstAlert.create({
data: {
kitaId,
assignmentId,
parentUserId,
triggeredById: session.user.id,
status: NotdienstAlertStatus.PENDING,
confirmationToken: token,
},
});
const alertUrl = `${BASE_URL}/alert/${token}`;
const dateLabel = format(assignment.date, "EEEE, dd. MMMM yyyy", {
locale: de,
});
const childName = `${assignment.child.firstName} ${assignment.child.lastName}`;
const alertJobs: { email: string; token: string }[] = [];
const emailResult = await sendAppEmail({
to: parentLink.user.email,
subject: `Dringender Notdienst-Alarm für ${dateLabel}`,
react: createElement(AlertEmail, {
date: dateLabel,
childName,
confirmLink: alertUrl,
await prisma.$transaction(
parents.map((parent) => {
const token = crypto.randomUUID();
alertJobs.push({ email: parent.email, token });
return prisma.notdienstAlert.create({
data: {
kitaId,
assignmentId,
parentUserId: parent.id,
triggeredById: session.user.id,
status: NotdienstAlertStatus.PENDING,
confirmationToken: token,
},
});
}),
});
);
for (const job of alertJobs) {
const emailResult = await sendAppEmail({
to: job.email,
subject: `Dringender Notdienst-Alarm für ${dateLabel}`,
react: createElement(AlertEmail, {
date: dateLabel,
childName,
confirmLink: `${BASE_URL}/alert/${job.token}`,
}),
});
if (!emailResult.success) {
revalidatePath("/dashboard");
return {
error: `Alarm wurde angelegt, aber mindestens eine E-Mail konnte nicht versendet werden: ${emailResult.error}`,
};
}
}
revalidatePath("/dashboard");
if (!emailResult.success) {
return {
error: `Alarm wurde angelegt, aber die E-Mail konnte nicht versendet werden: ${emailResult.error}`,
};
}
return { success: true };
} catch (error) {
console.error(error);