feat: implement emergency duty (Notdienst) swapping for parents
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
DutyAssignmentStatus,
|
||||
EventParticipationStatus,
|
||||
NotdienstSwapStatus,
|
||||
TerminStatus,
|
||||
TerminType,
|
||||
UserRole,
|
||||
} from "@prisma/client";
|
||||
import { HelpCircle } from "lucide-react";
|
||||
@@ -11,9 +11,12 @@ import { requireKitaSession } from "@/lib/auth-utils";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { AdminTerminModal } from "./_components/admin-termin-modal";
|
||||
import { PendingAnfragen, type PendingTerminDto } from "./_components/pending-anfragen";
|
||||
import { type CalendarListItemDto } from "./_components/termin-list";
|
||||
import { type CalendarListItemDto, type NotdienstSwapOptionDto } from "./_components/termin-list";
|
||||
import { TerminRequestModal } from "./_components/termin-request-modal";
|
||||
import { CalendarOverviewClient } from "./_components/calendar-overview-client";
|
||||
import {
|
||||
CalendarOverviewClient,
|
||||
type NotdienstSwapRequestDto,
|
||||
} from "./_components/calendar-overview-client";
|
||||
|
||||
export const metadata = { title: "Terminkalender · Kita-Planer" };
|
||||
|
||||
@@ -31,6 +34,7 @@ export default async function KalenderPage({
|
||||
const resolvedSearchParams = await searchParams;
|
||||
const currentTab = resolvedSearchParams.tab || "übersicht";
|
||||
const now = new Date();
|
||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
|
||||
const confirmedTermineRows = await prisma.termin.findMany({
|
||||
where: {
|
||||
@@ -159,6 +163,13 @@ export default async function KalenderPage({
|
||||
select: {
|
||||
id: true,
|
||||
date: true,
|
||||
planId: true,
|
||||
plan: {
|
||||
select: {
|
||||
year: true,
|
||||
month: true,
|
||||
},
|
||||
},
|
||||
child: {
|
||||
select: {
|
||||
firstName: true,
|
||||
@@ -175,6 +186,56 @@ export default async function KalenderPage({
|
||||
orderBy: { date: "asc" },
|
||||
});
|
||||
|
||||
const pendingSwapRows =
|
||||
!isAdmin && session.user.familyId
|
||||
? await prisma.notdienstSwapRequest.findMany({
|
||||
where: {
|
||||
kitaId: session.user.kitaId,
|
||||
status: NotdienstSwapStatus.PENDING,
|
||||
OR: [
|
||||
{ requesterFamilyId: session.user.familyId },
|
||||
{
|
||||
targetAssignment: {
|
||||
child: {
|
||||
familyId: session.user.familyId,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
requesterFamilyId: true,
|
||||
message: true,
|
||||
targetAssignment: {
|
||||
select: {
|
||||
date: true,
|
||||
child: {
|
||||
select: {
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
family: { select: { name: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
offeredAssignment: {
|
||||
select: {
|
||||
date: true,
|
||||
child: {
|
||||
select: {
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
family: { select: { name: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: "desc" },
|
||||
})
|
||||
: [];
|
||||
|
||||
const allUserTermine: CalendarListItemDto[] = [
|
||||
...confirmedTermineRows.map((termin) => ({
|
||||
...termin,
|
||||
@@ -213,21 +274,59 @@ export default async function KalenderPage({
|
||||
}),
|
||||
...notdienstAssignmentRows.map((assignment) => {
|
||||
const isOwn = assignment.child.familyId === familyIdForParticipation;
|
||||
const canRequestSwap =
|
||||
!isAdmin &&
|
||||
!isOwn &&
|
||||
!!session.user.familyId &&
|
||||
assignment.date >= today;
|
||||
return {
|
||||
kind: "notdienst" as const,
|
||||
id: assignment.id,
|
||||
planId: assignment.planId,
|
||||
planYear: assignment.plan.year,
|
||||
planMonth: assignment.plan.month,
|
||||
title: isOwn
|
||||
? `Mein Notdienst (${assignment.child.firstName})`
|
||||
: `Notdienst (${assignment.child.family.name})`,
|
||||
familyId: assignment.child.familyId,
|
||||
familyName: assignment.child.family.name,
|
||||
childName: `${assignment.child.firstName} ${assignment.child.lastName}`,
|
||||
isOwn,
|
||||
canRequestSwap,
|
||||
startDate: assignment.date,
|
||||
endDate: assignment.date,
|
||||
};
|
||||
}),
|
||||
].sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
|
||||
|
||||
const notdienstSwapOptions: NotdienstSwapOptionDto[] = notdienstAssignmentRows
|
||||
.filter(
|
||||
(assignment) =>
|
||||
assignment.child.familyId === familyIdForParticipation &&
|
||||
assignment.date >= today,
|
||||
)
|
||||
.map((assignment) => ({
|
||||
id: assignment.id,
|
||||
date: assignment.date,
|
||||
childName: `${assignment.child.firstName} ${assignment.child.lastName}`,
|
||||
familyName: assignment.child.family.name,
|
||||
}));
|
||||
|
||||
const pendingSwapRequests: NotdienstSwapRequestDto[] = pendingSwapRows.map(
|
||||
(request) => ({
|
||||
id: request.id,
|
||||
direction:
|
||||
request.requesterFamilyId === session.user.familyId ? "outgoing" : "incoming",
|
||||
targetDate: request.targetAssignment.date,
|
||||
targetFamilyName: request.targetAssignment.child.family.name,
|
||||
targetChildName: `${request.targetAssignment.child.firstName} ${request.targetAssignment.child.lastName}`,
|
||||
offeredDate: request.offeredAssignment.date,
|
||||
offeredFamilyName: request.offeredAssignment.child.family.name,
|
||||
offeredChildName: `${request.offeredAssignment.child.firstName} ${request.offeredAssignment.child.lastName}`,
|
||||
message: request.message,
|
||||
}),
|
||||
);
|
||||
|
||||
let allPendingTermine: PendingTerminDto[] = [];
|
||||
if (isAdmin) {
|
||||
const pendingRows = await prisma.termin.findMany({
|
||||
@@ -305,6 +404,8 @@ export default async function KalenderPage({
|
||||
termine={allUserTermine}
|
||||
userId={session.user.id}
|
||||
isAdmin={isAdmin}
|
||||
notdienstSwapOptions={notdienstSwapOptions}
|
||||
pendingSwapRequests={pendingSwapRequests}
|
||||
/>
|
||||
) : currentTab === "anfragen" ? (
|
||||
<PendingAnfragen termine={allPendingTermine} />
|
||||
@@ -313,6 +414,8 @@ export default async function KalenderPage({
|
||||
termine={[]}
|
||||
userId={session.user.id}
|
||||
isAdmin={isAdmin}
|
||||
notdienstSwapOptions={notdienstSwapOptions}
|
||||
pendingSwapRequests={pendingSwapRequests}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -322,6 +425,8 @@ export default async function KalenderPage({
|
||||
termine={allUserTermine}
|
||||
userId={session.user.id}
|
||||
isAdmin={isAdmin}
|
||||
notdienstSwapOptions={notdienstSwapOptions}
|
||||
pendingSwapRequests={pendingSwapRequests}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -405,5 +510,3 @@ function TabLink({
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user