feat: show family assignment counts in notdienst planning dropdown and support editing unassigned days in published plans

This commit is contained in:
t.indorf
2026-05-21 14:29:13 +02:00
parent f6acb3d271
commit e9595fab21
9 changed files with 455 additions and 31 deletions
+189
View File
@@ -0,0 +1,189 @@
import {
Body,
Button,
Container,
Head,
Heading,
Html,
Preview,
Section,
Text,
} from "@react-email/components";
import { baseBodyStyle, colors, fontStack } from "./_styles";
type NotdienstAssignmentEmailProps = {
parentName: string;
kitaName: string;
dateLabel: string;
link: string;
};
export function NotdienstAssignmentEmail({
parentName,
kitaName,
dateLabel,
link,
}: NotdienstAssignmentEmailProps) {
return (
<Html lang="de">
<Head />
<Preview>Aktualisierung Notdienst-Plan: Zuteilung für {dateLabel}</Preview>
<Body style={styles.body}>
<Container style={styles.container}>
<Section style={styles.card}>
<Section style={styles.brandBar}>
<Text style={styles.brand}>Kita-Planer</Text>
</Section>
<Text style={styles.kicker}>Notdienst-Einteilung</Text>
<Heading style={styles.heading}>Neuer Notdienst-Termin zugewiesen</Heading>
<Text style={styles.lead}>
Hallo {parentName},
</Text>
<Text style={styles.text}>
in der Kita <strong>{kitaName}</strong> gab es eine Änderung an der Notdienst-Planung.
Du wurdest für folgenden Tag für den Notdienst eingeteilt:
</Text>
<Section style={styles.dateBadge}>
<Text style={styles.dateText}>{dateLabel}</Text>
</Section>
<Text style={styles.text}>
Bitte merke dir diesen Termin vor. Du kannst den vollständigen Plan auch jederzeit online im Kita-Planer einsehen.
</Text>
<Button href={link} style={styles.button}>
Zum Kita-Planer
</Button>
<Text style={styles.fallbackText}>
Falls der Button nicht funktioniert, kopiere diesen Link in deinen Browser:
</Text>
<Text style={styles.linkText}>{link}</Text>
</Section>
<Text style={styles.footer}>
Diese Nachricht wurde automatisch vom Kita-Planer deiner Kita versendet.
</Text>
</Container>
</Body>
</Html>
);
}
const styles = {
body: baseBodyStyle,
container: {
width: "100%",
maxWidth: "600px",
margin: "0 auto",
padding: "32px 20px",
fontFamily: fontStack,
},
card: {
padding: "0 28px 28px",
backgroundColor: colors.cardBg,
borderRadius: "10px",
border: `1px solid ${colors.border}`,
boxShadow: "0 10px 26px rgba(31, 59, 45, 0.08)",
overflow: "hidden",
fontFamily: fontStack,
},
brandBar: {
margin: "0 -28px 28px",
padding: "14px 28px",
backgroundColor: colors.brandGreen,
fontFamily: fontStack,
},
brand: {
margin: 0,
color: colors.eyebrow,
fontSize: "12px",
fontWeight: 800,
letterSpacing: "0.08em",
textTransform: "uppercase" as const,
fontFamily: fontStack,
},
kicker: {
margin: "0 0 10px",
color: colors.brandGreenAccent,
fontSize: "12px",
fontWeight: 800,
letterSpacing: "0.06em",
textTransform: "uppercase" as const,
fontFamily: fontStack,
},
heading: {
margin: "0 0 14px",
color: colors.textPrimary,
fontSize: "28px",
lineHeight: "34px",
fontWeight: 800,
fontFamily: fontStack,
},
lead: {
margin: "0 0 22px",
color: colors.textBody,
fontSize: "16px",
lineHeight: "24px",
fontFamily: fontStack,
},
text: {
margin: "0 0 24px",
color: colors.textBody,
fontSize: "15px",
lineHeight: "24px",
fontFamily: fontStack,
},
dateBadge: {
padding: "16px",
backgroundColor: "#f7f5ef",
borderLeft: `4px solid ${colors.brandGreen}`,
borderRadius: "4px",
margin: "0 0 24px",
fontFamily: fontStack,
},
dateText: {
margin: 0,
fontSize: "18px",
fontWeight: 700,
color: colors.textPrimary,
fontFamily: fontStack,
},
button: {
display: "inline-block",
padding: "14px 20px",
backgroundColor: colors.brandGreen,
color: "#ffffff",
borderRadius: "6px",
fontSize: "15px",
fontWeight: 700,
textDecoration: "none",
fontFamily: fontStack,
},
fallbackText: {
margin: "28px 0 8px",
color: colors.textMuted,
fontSize: "13px",
lineHeight: "20px",
fontFamily: fontStack,
},
linkText: {
margin: 0,
color: colors.link,
fontSize: "13px",
lineHeight: "20px",
wordBreak: "break-all" as const,
fontFamily: fontStack,
},
footer: {
margin: "20px 0 0",
color: colors.textFaint,
fontSize: "12px",
lineHeight: "18px",
textAlign: "center" as const,
fontFamily: fontStack,
},
};