Ship tracking-codes Phase 2: cookie consent banner + gated script injection

CookieBanner.tsx (equally-weighted Akzeptieren/Ablehnen, TTDSG) +
useConsent() cookie hook + TrackingScripts.tsx render active
tracking-codes rows only once their consentCategory is actually
accepted ('necessary' always renders). Wired into layout.tsx via the
new getTrackingCodes() fetcher. This is what makes the Phase 1
backend collection (tracking-codes) actually usable end to end.

Also reworks NotifyMeForm back to always-visible input+button (better
UX than a collapse-to-reveal step) — the resulting taller CTA is now
reserved on every card via NotifyMeFormReservedSpace, an invisible
twin rendered behind the real button, so an in-stock card's row
height matches an out-of-stock sibling's without the grid's
row-stretch pushing buttons out of alignment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-08-01 20:03:11 +00:00
parent c6b12e9d60
commit 70ee518e1d
8 changed files with 327 additions and 75 deletions
+22 -16
View File
@@ -3,7 +3,7 @@
import { useEffect, useRef, useState } from "react";
import { addToCart, useCart } from "../lib/cart";
import { useCartFly } from "./CartFly";
import { NotifyMeForm } from "./NotifyMeForm";
import { NotifyMeForm, NotifyMeFormReservedSpace } from "./NotifyMeForm";
const FEEDBACK_MS = 2000;
@@ -119,19 +119,23 @@ export function AddToCartButton({
))}
</select>
)}
{currentlyOutOfStock ? (
// Replaces the button slot entirely rather than stacking below a
// disabled "Ausverkauft" button — same reasoning as
// AddToCartInlineButton's identical swap.
<NotifyMeForm productId={numericId} variantName={variants.length > 0 ? (selectedVariant ?? "") : ""} />
) : (
<button
ref={buttonRef}
type="button"
onClick={handleClick}
disabled={disabled}
className={`${base} ${stateClasses}`}
>
{/* Same reserved-space stack as AddToCartInlineButton.tsx's identical
block — see that file's own comment. */}
<div className="relative grid w-full">
<div className="invisible pointer-events-none [grid-area:1/1]">
<NotifyMeFormReservedSpace />
</div>
<div className="[grid-area:1/1] self-start">
{currentlyOutOfStock ? (
<NotifyMeForm productId={numericId} variantName={variants.length > 0 ? (selectedVariant ?? "") : ""} />
) : (
<button
ref={buttonRef}
type="button"
onClick={handleClick}
disabled={disabled}
className={`${base} ${stateClasses}`}
>
{/* CSS-grid text-stack, not just swapping the button's text node
directly — this button is inline-flex/content-sized (no w-full),
so "Hinzugefügt ✓" being shorter than most labels made the whole
@@ -159,8 +163,10 @@ export function AddToCartButton({
</span>
<span className="[grid-area:1/1]">{added ? "Hinzugefügt ✓" : displayLabel}</span>
</span>
</button>
)}
</button>
)}
</div>
</div>
</div>
);
}