feat: Telefonnummer im Kontaktformular ist Pflicht
Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 2m50s

Gleiche Prüfung wie bei der Buchung: mindestens 6 Zeichen, nur Ziffern, Leerzeichen und + ( ) / -.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-07 00:56:30 +02:00
1 parent 20adfaa97e
commit a47e91e9d5
3 files changed
+15 -5

No files matched your search

+2 -2
View File
@@ -101,8 +101,8 @@ export function ContactSection() {
{error("email")} {error("email")}
</div> </div>
<div> <div>
<label className="field-label" htmlFor="ct-phone">Telefon (optional)</label> <label className="field-label" htmlFor="ct-phone">Telefon</label>
<input {...fieldProps("phone")} className="field" type="tel" autoComplete="tel" maxLength={60} /> <input {...fieldProps("phone")} className="field" type="tel" autoComplete="tel" required maxLength={40} />
{error("phone")} {error("phone")}
</div> </div>
<div> <div>
+7 -1
View File
@@ -28,7 +28,13 @@ const optionalText = (max: number) =>
export const contactRequestSchema = z.object({ export const contactRequestSchema = z.object({
name: z.string().trim().min(2, "Bitte gib deinen Namen an.").max(120), name: z.string().trim().min(2, "Bitte gib deinen Namen an.").max(120),
email: z.string().trim().max(200).pipe(z.email("Bitte gib eine gültige E-Mail-Adresse an.")), email: z.string().trim().max(200).pipe(z.email("Bitte gib eine gültige E-Mail-Adresse an.")),
phone: optionalText(60), // Gleiche Regel wie bei der Buchung.
phone: z
.string("Bitte gib eine Telefonnummer an.")
.trim()
.min(6, "Bitte gib eine Telefonnummer an.")
.max(40)
.regex(/^[+0-9 ()/-]+$/, "Die Telefonnummer darf nur Ziffern, Leerzeichen und + ( ) / - enthalten."),
availability: optionalText(200), availability: optionalText(200),
message: optionalText(2000), message: optionalText(2000),
privacy: z.literal(true, { error: "Bitte bestätige die Datenschutzhinweise." }), privacy: z.literal(true, { error: "Bitte bestätige die Datenschutzhinweise." }),
+6 -2
View File
@@ -10,7 +10,7 @@ function request(overrides: Record<string, unknown> = {}) {
return contactRequestSchema.parse({ return contactRequestSchema.parse({
name: "Lena Beispiel", name: "Lena Beispiel",
email: "[email protected]", email: "[email protected]",
phone: "", phone: "+49 170 1234567",
availability: "abends", availability: "abends",
message: "Passt das Camp für Einsteigerinnen?", message: "Passt das Camp für Einsteigerinnen?",
privacy: true, privacy: true,
@@ -61,6 +61,10 @@ describe("Erstgespräch", () => {
test("Pflichtangaben und Einwilligung werden serverseitig geprüft", () => { test("Pflichtangaben und Einwilligung werden serverseitig geprüft", () => {
expect(contactRequestSchema.safeParse({ name: "L", email: "kein-mail", privacy: false }).success).toBe(false); expect(contactRequestSchema.safeParse({ name: "L", email: "kein-mail", privacy: false }).success).toBe(false);
expect(contactRequestSchema.safeParse({ name: "Lena", email: "[email protected]", privacy: false }).success).toBe(false); expect(contactRequestSchema.safeParse({ name: "Lena", email: "[email protected]", privacy: false }).success).toBe(false);
expect(request({ phone: " " }).phone).toBeNull(); const base = { name: "Lena", email: "[email protected]", privacy: true };
expect(contactRequestSchema.safeParse(base).success).toBe(false);
expect(contactRequestSchema.safeParse({ ...base, phone: " " }).success).toBe(false);
expect(contactRequestSchema.safeParse({ ...base, phone: "abc123456" }).success).toBe(false);
expect(request({ phone: " +49 170 1234567 " }).phone).toBe("+49 170 1234567");
}); });
}); });