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
+72 -29
View File
@@ -1,10 +1,12 @@
import Link from "next/link";
import { UserRole } from "@prisma/client";
import { Info, Calendar } from "lucide-react";
import { Info, Calendar, ArrowRight, ShieldAlert } from "lucide-react";
import { requireRole } from "@/lib/auth-utils";
import { prisma } from "@/lib/prisma";
import { getTargetMonthData } from "@/lib/date-utils";
import { NotdienstForm } from "./notdienst-form";
import { Button } from "@/components/ui/button";
import { NotdienstEntry } from "./notdienst-entry";
export const metadata = { title: "Notdienst · Kita-Planer" };
@@ -29,34 +31,51 @@ export default async function NotdienstPage() {
select: { notdienstMinPerChildPerMonth: true },
});
// Nur eigene, aktive Kinder laden
const children = await prisma.child.findMany({
where: {
kitaId,
active: true,
parentLinks: { some: { userId: session.user.id } },
},
select: { id: true, firstName: true },
});
// Nur aktive Kinder des eigenen Haushalts laden.
const children = session.user.familyId
? await prisma.child.findMany({
where: {
kitaId,
familyId: session.user.familyId,
active: true,
},
select: { id: true, firstName: true },
})
: [];
const targetData = getTargetMonthData();
const { targetYear, targetMonth, monthName, isLocked } = targetData;
const requiredDaysTotal = children.length * kita.notdienstMinPerChildPerMonth;
const childIds = children.map((child) => child.id);
// Bisherige Einträge für den Zielmonat laden
// Wir filtern bewusst nach den eigenen Kindern und dem User
const availabilities = await prisma.notdienstAvailability.findMany({
where: {
kitaId,
userId: session.user.id,
date: {
gte: new Date(targetYear, targetMonth - 1, 1),
lt: new Date(targetYear, targetMonth, 1),
},
},
select: { date: true },
});
// Bisherige Einträge für den Zielmonat laden, haushaltsweit über die Kinder.
const [availabilities, availabilityCountForCurrentOrNextMonth] =
children.length > 0
? await Promise.all([
prisma.notdienstAvailability.findMany({
where: {
kitaId,
childId: { in: childIds },
date: {
gte: new Date(targetYear, targetMonth - 1, 1),
lt: new Date(targetYear, targetMonth, 1),
},
},
select: { date: true },
}),
prisma.notdienstAvailability.count({
where: {
kitaId,
childId: { in: childIds },
date: {
gte: new Date(new Date().getFullYear(), new Date().getMonth(), 1),
lt: new Date(new Date().getFullYear(), new Date().getMonth() + 2, 1),
},
},
}),
])
: [[], 0];
const selectedDates = availabilities.map((a) => a.date.toISOString());
@@ -86,19 +105,43 @@ export default async function NotdienstPage() {
</div>
{children.length === 0 ? (
<div className="rounded-lg border border-dashed p-8 text-center text-muted-foreground">
Deinem Account sind noch keine Kinder zugeordnet.
</div>
<NotdienstLockout />
) : (
<NotdienstForm
<NotdienstEntry
hasAnyAvailability={availabilityCountForCurrentOrNextMonth > 0}
targetYear={targetYear}
targetMonth={targetMonth}
isLocked={isLocked}
requiredDaysTotal={requiredDaysTotal}
initialSelectedDates={selectedDates}
childrenIds={children.map((c) => c.id)}
childrenIds={childIds}
/>
)}
</div>
);
}
function NotdienstLockout() {
return (
<div className="flex min-h-[420px] items-center justify-center rounded-lg border border-dashed bg-muted/20 p-8 text-center">
<div className="mx-auto max-w-lg">
<div className="mx-auto flex h-20 w-20 items-center justify-center rounded-full bg-amber-100 text-amber-700 shadow-sm">
<ShieldAlert className="h-10 w-10" />
</div>
<h2 className="mt-6 text-2xl font-semibold tracking-tight">
Erst Kinder hinterlegen
</h2>
<p className="mt-3 text-sm leading-6 text-muted-foreground">
Bitte lege zuerst deine Kinder im Profil an, bevor du Notdienste
übernimmst.
</p>
<Button asChild className="mt-6">
<Link href="/dashboard/profil">
Zum Profil
<ArrowRight className="h-4 w-4" />
</Link>
</Button>
</div>
</div>
);
}