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
+108 -21
View File
@@ -2,11 +2,22 @@ import { requireKitaSession } from "@/lib/auth-utils";
import { prisma } from "@/lib/prisma";
import { format } from "date-fns";
import { de } from "date-fns/locale";
import { UserCircle, Mail, Baby, Shield, CalendarHeart } from "lucide-react";
import {
Baby,
CalendarHeart,
Home,
Mail,
Phone,
Shield,
UserCircle,
} from "lucide-react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { DeleteAccountDialog } from "./_components/delete-account-dialog";
import { MyChildrenManager } from "./_components/my-children-manager";
import { CreateFamilyDialog } from "./_components/create-family-dialog";
import { ContactForm } from "./_components/contact-form";
export const metadata = { title: "Mein Profil · Kita-Planer" };
@@ -15,12 +26,41 @@ export default async function ProfilPage() {
const user = await prisma.user.findUniqueOrThrow({
where: { id: session.user.id },
include: {
childLinks: {
include: { child: true },
select: {
id: true,
email: true,
firstName: true,
lastName: true,
role: true,
familyId: true,
phone: true,
street: true,
postalCode: true,
city: true,
createdAt: true,
family: {
select: {
name: true,
children: {
select: {
id: true,
firstName: true,
lastName: true,
dateOfBirth: true,
},
orderBy: [{ lastName: "asc" }, { firstName: "asc" }],
},
},
},
dutyAssignments: {
include: { duty: true },
select: {
id: true,
duty: {
select: {
name: true,
},
},
},
},
},
});
@@ -56,12 +96,39 @@ export default async function ProfilPage() {
</div>
<div className="font-medium">{user.email}</div>
</div>
<div>
<div className="text-sm text-muted-foreground flex items-center gap-1">
<Phone className="h-3.5 w-3.5" /> Telefon
</div>
<div className="font-medium">
{user.phone ?? "Noch nicht hinterlegt"}
</div>
</div>
<div>
<div className="text-sm text-muted-foreground">Rolle im Verein</div>
<Badge variant={user.role === "ELTERN" ? "secondary" : "default"} className="mt-1">
{user.role}
</Badge>
</div>
<div>
<div className="text-sm text-muted-foreground flex items-center gap-1">
<Home className="h-3.5 w-3.5" /> Haushalt
</div>
{user.family ? (
<div className="font-medium">{user.family.name}</div>
) : (
<div className="mt-2 space-y-3 rounded-md border border-dashed p-3">
<p className="text-sm text-muted-foreground">
Dein Account ist noch keinem Haushalt zugeordnet. Lege hier
deinen eigenen Haushalt an, wenn du selbst Elternteil in der
Kita bist.
</p>
<CreateFamilyDialog
defaultFamilyName={`Familie ${user.lastName}`}
/>
</div>
)}
</div>
<div className="pt-2 border-t mt-2">
<div className="text-sm text-muted-foreground flex items-center gap-1">
<CalendarHeart className="h-3.5 w-3.5" /> Mitglied seit
@@ -74,6 +141,29 @@ export default async function ProfilPage() {
</Card>
<div className="flex flex-col gap-6">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Phone className="h-5 w-5" />
Kontaktdaten
</CardTitle>
<CardDescription>
Diese Angaben helfen bei Notdienst, Adressbuch und Abstimmung in
der Kita.
</CardDescription>
</CardHeader>
<CardContent>
<ContactForm
contact={{
phone: user.phone,
street: user.street,
postalCode: user.postalCode,
city: user.city,
}}
/>
</CardContent>
</Card>
{/* Kinder */}
<Card>
<CardHeader>
@@ -83,19 +173,17 @@ export default async function ProfilPage() {
</CardTitle>
</CardHeader>
<CardContent>
{user.childLinks.length === 0 ? (
<p className="text-sm text-muted-foreground">Keine Kinder verknüpft.</p>
) : (
<div className="flex flex-col gap-2">
{user.childLinks.map((link) => (
<div key={link.child.id} className="flex items-center justify-between p-2 rounded-md bg-muted/50">
<span className="font-medium">
{link.child.firstName} {link.child.lastName}
</span>
</div>
))}
</div>
)}
<MyChildrenManager
items={(user.family?.children ?? []).map((child) => ({
id: child.id,
firstName: child.firstName,
lastName: child.lastName,
dateOfBirth: child.dateOfBirth
? child.dateOfBirth.toISOString().slice(0, 10)
: null,
}))}
canManage={!!user.familyId}
/>
</CardContent>
</Card>
@@ -124,12 +212,11 @@ export default async function ProfilPage() {
</div>
</div>
{/* Danger Zone */}
<Card className="border-destructive/20 mt-8">
<CardHeader>
<CardTitle className="text-destructive">Danger Zone</CardTitle>
<CardDescription>
Hier kannst du dein Profil und alle zugehörigen Daten DSGVO-konform löschen.
Hier kannst du dein Profil und je nach Haushaltssituation auch die
zugehörigen Familiendaten DSGVO-konform löschen.
</CardDescription>
</CardHeader>
<CardContent>