feat(checkout): add Packstation delivery option

Toggle between "Lieferadresse" and "Packstation" in the checkout
address form. Packstation swaps Straße und Hausnummer for
Packstationnummer + Postnummer — there's no house number for a
Packstation, so the field doesn't apply.
This commit is contained in:
Marco
2026-07-19 23:31:13 +00:00
parent 0c72b70de7
commit 2a14e18aa1
+62 -7
View File
@@ -71,6 +71,7 @@ export function CheckoutContent({
const [shippingMethodId, setShippingMethodId] = useState<number | null>(shippingMethods[0]?.id ?? null);
const [paymentMethodId, setPaymentMethodId] = useState<number | null>(paymentMethods[0]?.id ?? null);
const [versandOpen, setVersandOpen] = useState(false);
const [deliveryMethod, setDeliveryMethod] = useState<"address" | "packstation">("address");
const productsLoading = products.length === 0 && cart.length > 0;
const items = cart
@@ -176,13 +177,67 @@ export function CheckoutContent({
autoComplete="email"
wrapperClassName="w-full sm:w-[calc(50%-0.5rem)] sm:flex-none min-w-0"
/>
<FormField
label="Straße und Hausnummer"
type="text"
placeholder="Musterstraße 1"
autoComplete="street-address"
wrapperClassName="w-full sm:w-[calc(50%-0.5rem)] sm:flex-none min-w-0"
/>
{/* Segmented control, same sm:w-[calc(50%-0.5rem)] half-row
width as the field(s) below it — Lieferadresse keeps
Straße und Hausnummer, Packstation swaps it out for
Packstationnummer + Postnummer (DHL's two Packstation
identifiers; there's no house number to give). */}
<div className="w-full sm:w-[calc(50%-0.5rem)] flex flex-col gap-2 items-start">
<span className="text-label text-text-muted">Lieferart</span>
<div className="flex w-full rounded-sm border border-border overflow-hidden">
<button
type="button"
onClick={() => setDeliveryMethod("address")}
aria-pressed={deliveryMethod === "address"}
className={`flex-1 py-3 text-body-sm font-bold transition-colors ${
deliveryMethod === "address"
? "bg-brand text-text-primary"
: "text-text-muted hover:text-text-primary"
}`}
>
Lieferadresse
</button>
<button
type="button"
onClick={() => setDeliveryMethod("packstation")}
aria-pressed={deliveryMethod === "packstation"}
className={`flex-1 py-3 text-body-sm font-bold border-l border-border transition-colors ${
deliveryMethod === "packstation"
? "bg-brand text-text-primary"
: "text-text-muted hover:text-text-primary"
}`}
>
Packstation
</button>
</div>
</div>
{deliveryMethod === "address" ? (
<FormField
label="Straße und Hausnummer"
type="text"
placeholder="Musterstraße 1"
autoComplete="street-address"
wrapperClassName="w-full sm:w-[calc(50%-0.5rem)] sm:flex-none min-w-0"
/>
) : (
<div className="flex flex-col sm:flex-row gap-4 w-full">
<FormField
label="Packstationnummer"
type="text"
inputMode="numeric"
placeholder="123"
autoComplete="off"
/>
<FormField
label="Postnummer"
type="text"
inputMode="numeric"
placeholder="1234567"
autoComplete="off"
/>
</div>
)}
<div className="flex flex-col sm:flex-row gap-4 w-full">
<FormField label="PLZ" type="text" placeholder="10115" autoComplete="postal-code" />
<FormField label="Ort" type="text" placeholder="Berlin" autoComplete="address-level2" />