Add product image gallery, harden Klaro border reset, remove attribution link
ProductGallery.tsx (main image + thumbnail strip) wired into TodoKartenHero.tsx, only replacing the static hero photo once a product actually has extra gallery photos — no visual change otherwise. Backend field: Products.gallery (see payload repo). Klaro's hard black border was still showing after the previous color-only pass — the targeted border:none rule wasn't enough, so this blanket-resets border/outline on every .klaro descendant and re-adds only the shadow this theme actually wants. Also disables the "Realisiert mit Klaro!" attribution link (BSD-3-Clause has no on-page-attribution requirement, Klaro's own disablePoweredBy flag covers this cleanly). Updates the frontend README with the gallery + Klaro fixes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ const product = (overrides: Partial<Product> = {}): Product => ({
|
||||
price: 12.9,
|
||||
compareAtPrice: null,
|
||||
image: "",
|
||||
gallery: [],
|
||||
href: null,
|
||||
active: true,
|
||||
updatedAt: new Date().toISOString(),
|
||||
|
||||
@@ -15,6 +15,7 @@ export type KlaroConfig = {
|
||||
acceptAll: boolean;
|
||||
hideDeclineAll: boolean;
|
||||
noticeAsModal: boolean;
|
||||
disablePoweredBy: boolean;
|
||||
translations: Record<string, Record<string, unknown>>;
|
||||
services: {
|
||||
name: string;
|
||||
@@ -96,6 +97,11 @@ export function buildKlaroConfig(codes: TrackingCode[], onAccept: (code: Trackin
|
||||
acceptAll: true,
|
||||
hideDeclineAll: false,
|
||||
noticeAsModal: false,
|
||||
// Removes the "Realisiert mit Klaro!" attribution link in the modal —
|
||||
// BSD-3-Clause has no on-page-attribution requirement (only source/
|
||||
// binary copyright-notice retention), this is just the maintainers'
|
||||
// own polite ask via a dedicated config flag, not a license term.
|
||||
disablePoweredBy: true,
|
||||
translations: {
|
||||
de: {
|
||||
consentModal: {
|
||||
|
||||
@@ -185,6 +185,11 @@ export type Product = {
|
||||
price: number;
|
||||
compareAtPrice: number | null;
|
||||
image: string;
|
||||
// Extra photos beyond `image` above, for ProductGallery.tsx's
|
||||
// thumbnail-strip UI — empty for the vast majority of products (opt-in
|
||||
// per product, see Products.ts's own field comment). Never includes
|
||||
// `image` itself; ProductGallery treats `image` as always-slide-zero.
|
||||
gallery: string[];
|
||||
href: string | null;
|
||||
// `active` is opt-in for callers to filter by, not applied inside
|
||||
// getProducts()/getProductBySlug() themselves — cart, checkout, order
|
||||
@@ -250,6 +255,7 @@ type PayloadProduct = {
|
||||
price: number;
|
||||
compareAtPrice: number | null;
|
||||
image: { url: string } | number | null;
|
||||
gallery: ({ url: string } | number)[] | null;
|
||||
detailHref: string | null;
|
||||
active: boolean;
|
||||
updatedAt: string;
|
||||
@@ -314,6 +320,9 @@ export function mapPayloadProduct(product: PayloadProduct): Product {
|
||||
price: product.price,
|
||||
compareAtPrice: product.compareAtPrice ?? null,
|
||||
image: typeof product.image === "object" && product.image ? product.image.url : "",
|
||||
gallery: (product.gallery ?? [])
|
||||
.map((g) => (typeof g === "object" && g ? g.url : null))
|
||||
.filter((url): url is string => Boolean(url)),
|
||||
href: product.detailHref || null,
|
||||
active: product.active,
|
||||
updatedAt: product.updatedAt,
|
||||
|
||||
Reference in New Issue
Block a user