Move trust badges, shipping/payment methods, Werkzeuge cards, product spotlight into CMS

New Payload collections, all editable without a code deploy:
- TrustBadges: the horizontal Schneller-Versand/Versandkostenfrei/Mit-
  Liebe-verpackt row (TrustRow.tsx, now an async server component).
- CartTrustBadges: the Sichere-Zahlung/14-Tage-Rückgaberecht/Nachhaltig-
  verpackt sidebar bullets — shared by /cart (title only) and /checkout
  (title + description), which previously had two different hardcoded
  bullet lists for what's conceptually the same content.
- ShippingMethods: /checkout's Versandart radios. Each method has its own
  optional freeShippingThreshold — omitted means "never free" (Express),
  not "always free". /cart's FreeShippingBanner now targets the lowest
  threshold among active methods instead of a single global constant, and
  hides entirely if no active method has one.
- PaymentMethods: /checkout's Zahlungsart radios, icons as an array
  (Kreditkarte shows 3 logos, PayPal/Überweisung show 1).
- Products: new spotlight/spotlightHeadline/spotlightText/spotlightImage/
  compareAtPrice fields. ProductSpotlight.tsx (homepage) now shows
  whichever product has `spotlight` checked instead of being hardcoded to
  ToDo-Karten, with its own marketing copy separate from the plain
  catalog name/description. AddToCartButton takes an explicit productId
  prop now instead of a hardcoded "todo-karten" constant.
- WerkzeugeCards: the homepage's "Meine Werkzeuge" 3-card grid (Tools.tsx,
  now async). Icons use a uniform box instead of the previous per-card
  hand-tuned width/height/rotation, which only worked for 3 known,
  upside-down-authored SVGs — those were re-exported as pre-flipped PNGs.

lib/payload.ts gained getTrustBadges/getCartTrustBadges/getShippingMethods/
getPaymentMethods/getWerkzeugeCards/getSpotlightProduct, all with the same
graceful-empty-array-on-fetch-failure pattern as the existing functions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-07-19 23:15:46 +00:00
parent 754966c8ba
commit d472eb546f
10 changed files with 419 additions and 186 deletions
+6 -2
View File
@@ -5,7 +5,6 @@ import { addToCart } from "../lib/cart";
import { useCartFly } from "./CartFly";
const FEEDBACK_MS = 2000;
const PRODUCT_ID = "todo-karten";
/**
* Shared by /todo-cards's Hero + pricing panel and Home's product
@@ -17,9 +16,14 @@ const PRODUCT_ID = "todo-karten";
export function AddToCartButton({
label,
className,
productId = "todo-karten",
}: {
label: string;
className?: string;
/** Defaults to "todo-karten" for /todo-cards' own hardcoded usage — Home's
* ProductSpotlight passes the actual CMS-selected spotlight product's id
* explicitly, since that can now be a different product. */
productId?: string;
}) {
const [added, setAdded] = useState(false);
const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
@@ -29,7 +33,7 @@ export function AddToCartButton({
useEffect(() => () => clearTimeout(timeoutRef.current), []);
function handleClick() {
addToCart(PRODUCT_ID);
addToCart(productId);
if (buttonRef.current) fly(buttonRef.current);
setAdded(true);
clearTimeout(timeoutRef.current);