"use client"; import { useState, type FormEvent, type HTMLAttributes } from "react"; import { useRouter } from "next/navigation"; import { Container, SectionHeading, Button } from "@/components/ui"; import { TrustBadges } from "@/components/trust-badges"; import { useCartStore, cartTotalCents, cartItemCount } from "@/store/cart-store"; import { formatPrice } from "@/lib/format"; import { resolveShippingCostCents, type ShippingTierLike } from "@/lib/shipping-calc"; import { resolveBulkDiscount, type BulkDiscountTierLike } from "@/lib/bulk-discount-calc"; import { useI18n } from "@/i18n/i18n-provider"; type Fulfillment = "VERSAND" | "ABHOLUNG"; export interface CheckoutInitialValues { firstName: string; lastName: string; email: string; phone: string; street: string; zip: string; city: string; } export function CheckoutForm({ initialValues, tiers, bulkDiscountTiers, }: { initialValues?: CheckoutInitialValues; tiers: ShippingTierLike[]; bulkDiscountTiers: BulkDiscountTierLike[]; }) { const { t } = useI18n(); const items = useCartStore((s) => s.items); const subtotal = cartTotalCents(items); const totalQuantity = cartItemCount(items); const router = useRouter(); const [fulfillment, setFulfillment] = useState("VERSAND"); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); const [isGift, setIsGift] = useState(false); // Live sichtbar statt erst nach der Weiterleitung zu Stripe — reagiert auf // die Versand/Abholung-Auswahl, damit die Gesamtsumme immer stimmt. const shipping = fulfillment === "ABHOLUNG" ? 0 : resolveShippingCostCents(tiers, totalQuantity); const activeBulkDiscount = resolveBulkDiscount(bulkDiscountTiers, totalQuantity); const bulkDiscountCents = activeBulkDiscount ? Math.round((subtotal * activeBulkDiscount.percent) / 100) : 0; const total = subtotal - bulkDiscountCents + shipping; async function handleSubmit(event: FormEvent) { event.preventDefault(); setSubmitting(true); setError(null); const formData = new FormData(event.currentTarget); const payload = { email: String(formData.get("email") ?? ""), firstName: String(formData.get("firstName") ?? ""), lastName: String(formData.get("lastName") ?? ""), phone: String(formData.get("phone") ?? "") || undefined, fulfillmentMethod: fulfillment, street: String(formData.get("street") ?? "") || undefined, zip: String(formData.get("zip") ?? "") || undefined, city: String(formData.get("city") ?? "") || undefined, country: "DE", items: items.map((item) => ({ productId: item.productId, quantity: item.quantity })), discountCode: String(formData.get("discountCode") ?? "").trim() || undefined, giftMessage: isGift ? String(formData.get("giftMessage") ?? "").trim() || undefined : undefined, }; try { const response = await fetch("/api/checkout", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); const data = await response.json(); if (!response.ok) { if (data.orderNumber) { router.push(`/checkout/success?order=${data.orderNumber}&pending=1`); return; } setError(data.error ?? t.checkoutPage.genericError); setSubmitting(false); return; } window.location.href = data.url; } catch { setError(t.checkoutPage.genericError); setSubmitting(false); } } if (items.length === 0) { return (
); } return (

{t.checkoutPage.fulfillmentLabel}

{(["VERSAND", "ABHOLUNG"] as const).map((option) => ( ))}
{fulfillment === "VERSAND" ? (

{t.checkoutPage.deliveryTimeNote}

) : null}
{fulfillment === "VERSAND" ? (
) : null}
{isGift ? (