Apply linen design system across app
This commit is contained in:
@@ -2,8 +2,14 @@
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { z } from "zod";
|
||||
import { NotdienstPlanStatus } from "@prisma/client";
|
||||
|
||||
import { requireKitaSession } from "@/lib/auth-utils";
|
||||
import {
|
||||
CHILD_MAX_AGE_YEARS,
|
||||
getChildBirthdateRange,
|
||||
parseDateInput,
|
||||
} from "@/lib/child-birthdate";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
// Telefonnummern: führendes "+" optional, dann Ziffern, Leerzeichen, Bindestriche,
|
||||
@@ -23,8 +29,8 @@ const childSchema = z
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
if (!data.dateOfBirth) return;
|
||||
const parsed = new Date(`${data.dateOfBirth}T00:00:00`);
|
||||
if (Number.isNaN(parsed.getTime())) {
|
||||
const parsed = parseDateInput(data.dateOfBirth);
|
||||
if (!parsed) {
|
||||
ctx.addIssue({
|
||||
path: ["dateOfBirth"],
|
||||
code: "custom",
|
||||
@@ -32,22 +38,19 @@ const childSchema = z
|
||||
});
|
||||
return;
|
||||
}
|
||||
// In der Zukunft geborene Kinder existieren nicht.
|
||||
const today = new Date();
|
||||
today.setHours(23, 59, 59, 999);
|
||||
if (parsed > today) {
|
||||
const { min, max } = getChildBirthdateRange();
|
||||
if (data.dateOfBirth > max) {
|
||||
ctx.addIssue({
|
||||
path: ["dateOfBirth"],
|
||||
code: "custom",
|
||||
message: "Geburtsdatum darf nicht in der Zukunft liegen.",
|
||||
});
|
||||
}
|
||||
// Schutz vor offensichtlichen Tippfehlern (1899 statt 1989 o.ä.).
|
||||
if (parsed.getFullYear() < 1900) {
|
||||
if (data.dateOfBirth < min) {
|
||||
ctx.addIssue({
|
||||
path: ["dateOfBirth"],
|
||||
code: "custom",
|
||||
message: "Bitte ein realistisches Geburtsdatum angeben.",
|
||||
message: `Kinder dürfen maximal ${CHILD_MAX_AGE_YEARS} Jahre alt sein.`,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -79,13 +82,6 @@ const contactSchema = z.object({
|
||||
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;
|
||||
}
|
||||
|
||||
// Gibt die erste konkrete Field-Error-Message aus einem Zod-Fehler zurück,
|
||||
// damit der User nicht nur "Ungültige Eingabedaten" sieht.
|
||||
function firstZodMessage(
|
||||
@@ -290,6 +286,27 @@ export async function deleteMyAccount() {
|
||||
return { error: "Account wurde nicht gefunden." };
|
||||
}
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
const activeNotdienstAssignments = user.familyId
|
||||
? await prisma.notdienstAssignment.count({
|
||||
where: {
|
||||
kitaId: session.user.kitaId,
|
||||
date: { gte: today },
|
||||
plan: { status: NotdienstPlanStatus.PUBLISHED },
|
||||
child: { familyId: user.familyId },
|
||||
},
|
||||
})
|
||||
: 0;
|
||||
|
||||
if (activeNotdienstAssignments > 0) {
|
||||
return {
|
||||
error:
|
||||
"Dein Account kann nicht gelöscht werden, solange aktive Notdienst-Verpflichtungen bestehen.",
|
||||
};
|
||||
}
|
||||
|
||||
if (!user.familyId) {
|
||||
await prisma.user.delete({
|
||||
where: { id: user.id },
|
||||
|
||||
Reference in New Issue
Block a user