continued the kita-planer
This commit is contained in:
@@ -1,24 +1,264 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { z } from "zod";
|
||||
|
||||
import { requireKitaSession } from "@/lib/auth-utils";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { signOut } from "@/auth"; // Note: this is NextAuth v5 server side signOut if needed, but we do client side
|
||||
|
||||
const childSchema = z.object({
|
||||
firstName: z.string().min(1, "Vorname ist erforderlich.").max(100).trim(),
|
||||
lastName: z.string().min(1, "Nachname ist erforderlich.").max(100).trim(),
|
||||
dateOfBirth: z.string().optional(),
|
||||
});
|
||||
|
||||
const familySchema = z.object({
|
||||
familyName: z.string().min(1, "Familienname ist erforderlich.").max(120).trim(),
|
||||
});
|
||||
|
||||
const contactSchema = z.object({
|
||||
phone: z.string().trim().max(50).optional(),
|
||||
street: z.string().trim().max(120).optional(),
|
||||
postalCode: z.string().trim().max(20).optional(),
|
||||
city: z.string().trim().max(100).optional(),
|
||||
});
|
||||
|
||||
function parseDateInput(value?: string) {
|
||||
if (!value) return null;
|
||||
|
||||
const date = new Date(`${value}T00:00:00`);
|
||||
return Number.isNaN(date.getTime()) ? null : date;
|
||||
}
|
||||
|
||||
async function requireOwnFamilyChild(
|
||||
childId: string,
|
||||
familyId: string | null,
|
||||
kitaId: string,
|
||||
) {
|
||||
if (!familyId) return null;
|
||||
|
||||
return prisma.child.findFirst({
|
||||
where: { id: childId, familyId, kitaId },
|
||||
});
|
||||
}
|
||||
|
||||
export async function createMyChild(rawPayload: unknown) {
|
||||
const session = await requireKitaSession();
|
||||
const parsed = childSchema.safeParse(rawPayload);
|
||||
|
||||
if (!session.user.familyId) {
|
||||
return { error: "Dein Account ist noch keinem Haushalt zugeordnet." };
|
||||
}
|
||||
|
||||
if (!parsed.success) {
|
||||
return { error: "Ungültige Eingabedaten." };
|
||||
}
|
||||
|
||||
try {
|
||||
await prisma.child.create({
|
||||
data: {
|
||||
kitaId: session.user.kitaId,
|
||||
familyId: session.user.familyId,
|
||||
firstName: parsed.data.firstName,
|
||||
lastName: parsed.data.lastName,
|
||||
dateOfBirth: parseDateInput(parsed.data.dateOfBirth),
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath("/dashboard/profil");
|
||||
revalidatePath("/dashboard/families");
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Anlegen des Kindes:", error);
|
||||
return { error: "Das Kind konnte nicht angelegt werden." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function createMyFamily(rawPayload: unknown) {
|
||||
const session = await requireKitaSession();
|
||||
const parsed = familySchema.safeParse(rawPayload);
|
||||
|
||||
if (!parsed.success) {
|
||||
return { error: "Bitte gib einen gültigen Familiennamen ein." };
|
||||
}
|
||||
|
||||
if (session.user.familyId) {
|
||||
return { error: "Dein Account ist bereits einem Haushalt zugeordnet." };
|
||||
}
|
||||
|
||||
try {
|
||||
await prisma.$transaction(async (tx) => {
|
||||
const family = await tx.family.create({
|
||||
data: {
|
||||
kitaId: session.user.kitaId,
|
||||
name: parsed.data.familyName,
|
||||
},
|
||||
});
|
||||
|
||||
await tx.user.update({
|
||||
where: { id: session.user.id },
|
||||
data: { familyId: family.id },
|
||||
});
|
||||
});
|
||||
|
||||
revalidatePath("/dashboard/profil");
|
||||
revalidatePath("/dashboard/families");
|
||||
revalidatePath("/dashboard/adressbuch");
|
||||
revalidatePath("/dashboard");
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Anlegen des eigenen Haushalts:", error);
|
||||
return { error: "Der Haushalt konnte nicht angelegt werden." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateMyContact(rawPayload: unknown) {
|
||||
const session = await requireKitaSession();
|
||||
const parsed = contactSchema.safeParse(rawPayload);
|
||||
|
||||
if (!parsed.success) {
|
||||
return { error: "Ungültige Kontaktdaten." };
|
||||
}
|
||||
|
||||
try {
|
||||
await prisma.user.update({
|
||||
where: { id: session.user.id },
|
||||
data: {
|
||||
phone: parsed.data.phone || null,
|
||||
street: parsed.data.street || null,
|
||||
postalCode: parsed.data.postalCode || null,
|
||||
city: parsed.data.city || null,
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath("/dashboard/profil");
|
||||
revalidatePath("/dashboard");
|
||||
revalidatePath("/dashboard/adressbuch");
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Aktualisieren der Kontaktdaten:", error);
|
||||
return { error: "Kontaktdaten konnten nicht gespeichert werden." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateMyChild(childId: string, rawPayload: unknown) {
|
||||
const session = await requireKitaSession();
|
||||
const parsed = childSchema.safeParse(rawPayload);
|
||||
|
||||
if (!parsed.success) {
|
||||
return { error: "Ungültige Eingabedaten." };
|
||||
}
|
||||
|
||||
try {
|
||||
const child = await requireOwnFamilyChild(
|
||||
childId,
|
||||
session.user.familyId,
|
||||
session.user.kitaId,
|
||||
);
|
||||
|
||||
if (!child) {
|
||||
return { error: "Dieses Kind gehört nicht zu deinem Haushalt." };
|
||||
}
|
||||
|
||||
await prisma.child.update({
|
||||
where: { id: childId },
|
||||
data: {
|
||||
firstName: parsed.data.firstName,
|
||||
lastName: parsed.data.lastName,
|
||||
dateOfBirth: parseDateInput(parsed.data.dateOfBirth),
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath("/dashboard/profil");
|
||||
revalidatePath("/dashboard/families");
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Aktualisieren des Kindes:", error);
|
||||
return { error: "Das Kind konnte nicht aktualisiert werden." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteMyChild(childId: string) {
|
||||
const session = await requireKitaSession();
|
||||
|
||||
try {
|
||||
const child = await requireOwnFamilyChild(
|
||||
childId,
|
||||
session.user.familyId,
|
||||
session.user.kitaId,
|
||||
);
|
||||
|
||||
if (!child) {
|
||||
return { error: "Dieses Kind gehört nicht zu deinem Haushalt." };
|
||||
}
|
||||
|
||||
await prisma.child.delete({
|
||||
where: { id: childId },
|
||||
});
|
||||
|
||||
revalidatePath("/dashboard/profil");
|
||||
revalidatePath("/dashboard/families");
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Entfernen des Kindes:", error);
|
||||
return { error: "Das Kind konnte nicht entfernt werden." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteMyAccount() {
|
||||
const session = await requireKitaSession();
|
||||
|
||||
try {
|
||||
// Da wir onDelete: Cascade überall konfiguriert haben,
|
||||
// löscht dieser eine Befehl den User, seine ChildParent-Links,
|
||||
// seine MitbringselItems, seine NotdienstAvailabilities etc.
|
||||
await prisma.user.delete({
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: session.user.id,
|
||||
kitaId: session.user.kitaId,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
familyId: true,
|
||||
},
|
||||
});
|
||||
|
||||
// The client component will trigger the actual NextAuth client signOut,
|
||||
// but returning success indicates the DB deletion was successful.
|
||||
if (!user) {
|
||||
return { error: "Account wurde nicht gefunden." };
|
||||
}
|
||||
|
||||
if (!user.familyId) {
|
||||
await prisma.user.delete({
|
||||
where: { id: user.id },
|
||||
});
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
const family = await prisma.family.findFirst({
|
||||
where: {
|
||||
id: user.familyId,
|
||||
kitaId: session.user.kitaId,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
users: {
|
||||
select: { id: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!family) {
|
||||
return { error: "Haushalt wurde nicht gefunden." };
|
||||
}
|
||||
|
||||
if (family.users.length <= 1) {
|
||||
await prisma.family.delete({
|
||||
where: { id: family.id },
|
||||
});
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
await prisma.user.delete({
|
||||
where: { id: user.id },
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Löschen des Accounts:", error);
|
||||
|
||||
Reference in New Issue
Block a user