Danke! Du bist jetzt für den Newsletter angemeldet.
;
+ }
+
+ return (
+
+ );
+}
diff --git a/app/challenge/page.tsx b/app/challenge/page.tsx
index 1b9b5df..f99e6df 100644
--- a/app/challenge/page.tsx
+++ b/app/challenge/page.tsx
@@ -7,6 +7,7 @@ import { Reveal, RevealGroup, RevealItem } from "../components/Reveal";
import { TestimonialsGrid } from "../components/TestimonialsGrid";
import { LiveTestimonialsGrid } from "../components/LiveTestimonialsGrid";
import { getTestimonials } from "../lib/payload";
+import { EmailCapture } from "./components/EmailCapture";
const title = "7-Tage-Challenge – Mehr Klarheit in 7 Tagen";
const description =
@@ -82,15 +83,6 @@ function Check() {
);
}
-function LockIcon() {
- return (
-
- );
-}
-
const steps = [
{
icon: ,
@@ -122,52 +114,6 @@ const benefits = [
{ title: "Gelassener leben", desc: "Weniger Stress, mehr Zeit für die Dinge, die dir wichtig sind." },
];
-function EmailCapture({ buttonLabel = "Challenge starten" }: { buttonLabel?: string }) {
- return (
-
-
-
-
-
- {/* Consent checkbox — this signup's legal basis is consent (email
- marketing), same wording as the other newsletter forms; colors
- match this page's own hardcoded palette instead of the shared
- design tokens, consistent with the rest of the page. */}
-
-
-
- Keine Werbung. Jederzeit abbestellbar.
-
-
- );
-}
-
export default async function ChallengePage() {
const { isEnabled: isPreview } = await draftMode();
const testimonials = await getTestimonials("challenge", { draft: isPreview });
diff --git a/app/checkout/components/CheckoutContent.tsx b/app/checkout/components/CheckoutContent.tsx
index f0e5db9..8baad76 100644
--- a/app/checkout/components/CheckoutContent.tsx
+++ b/app/checkout/components/CheckoutContent.tsx
@@ -19,6 +19,7 @@ import { dispatchAuthChanged } from "../../lib/auth";
import { readCheckoutDraft, writeCheckoutDraft, clearCheckoutDraft } from "../../lib/checkoutDraft";
import { normalizeVatId, isValidVatId } from "../../lib/vatId";
import { computeExemptTotals, destinationCountry, isExemptionEligibleCountry } from "../../lib/vatExemption";
+import { validateEmailFormat } from "../../lib/email";
import type { ShippingMethod, ShippingCountry, PaymentMethod, TrustBadge, ShippingSettings } from "../../lib/payload";
import type { CustomerProfile } from "../../lib/customerAuth";
@@ -44,11 +45,6 @@ function validateRequired(label: string, value: string): string {
return value.trim() ? "" : `${label} ist erforderlich.`;
}
-function validateEmailFormat(value: string): string {
- if (!value.trim()) return "E-Mail-Adresse ist erforderlich.";
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) ? "" : "Bitte eine gültige E-Mail-Adresse angeben.";
-}
-
function validateZip(value: string, country: string, plzDigitsMap: Record): string {
if (!value.trim()) return "PLZ ist erforderlich.";
const digits = plzDigitsMap[country] ?? 4;
diff --git a/app/components/Newsletter.tsx b/app/components/Newsletter.tsx
index 7a22b9a..69810f3 100644
--- a/app/components/Newsletter.tsx
+++ b/app/components/Newsletter.tsx
@@ -1,9 +1,10 @@
"use client";
-import { useState, type FormEvent, type ReactNode } from "react";
+import type { ReactNode } from "react";
import Link from "next/link";
import Image from "next/image";
import { Reveal } from "./Reveal";
+import { useNewsletterSignup } from "../lib/useNewsletterSignup";
// Same lock icon + copy as /challenge's and /newsletter's EmailCapture —
// unified across all newsletter-signup forms instead of each having its
@@ -33,33 +34,8 @@ export function Newsletter({
title = <>Starte mit einer Woche voller Klarheit.>,
description = "Melde dich zum Newsletter an und erhalte die 7-Tage-Challenge, mit der du durch mehr Struktur weniger Stress spürst.",
}: NewsletterProps = {}) {
- const [email, setEmail] = useState("");
- const [consent, setConsent] = useState(false);
- const [status, setStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
- const [error, setError] = useState("");
-
- async function handleSubmit(e: FormEvent) {
- e.preventDefault();
- setStatus("submitting");
- setError("");
- try {
- const res = await fetch("/api/newsletter/subscribe", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ email, consent, source: "newsletter-page" }),
- });
- const data = await res.json();
- if (!data.ok) {
- setError(data.reason || "Anmeldung ist fehlgeschlagen. Bitte versuche es später erneut.");
- setStatus("error");
- return;
- }
- setStatus("success");
- } catch {
- setError("Anmeldung ist fehlgeschlagen. Bitte versuche es später erneut.");
- setStatus("error");
- }
- }
+ const { email, emailError, consent, setConsent, status, error, emailRef, handleEmailChange, handleEmailBlur, handleSubmit } =
+ useNewsletterSignup("newsletter-page");
return (
@@ -112,12 +88,17 @@ export function Newsletter({
{/* Input + submit button — stacked below md, side by side from md+ */}