feat(blog): optional quote label + swappable related-product card per post

Both were fully hardcoded before: every blockquote showed a static
"Merke dir:" label, and every post's "Passend dazu" card always linked
the same flagship product. Now driven by two new Posts fields —
quoteLabel (empty hides the label/icon/underline, blockquote still
renders) and relatedProduct (empty hides the card entirely) — mirroring
Products.spotlight but per-post instead of a single site-wide flag.

README's collection table updated to match today's Payload changes
(shipping-settings, the new Posts fields, trust-badges' placeholder
tokens, admin sidebar grouping) — also fixed a stale claim that `media`
isn't tenant-scoped; it already was.
This commit is contained in:
Marco
2026-07-21 13:10:06 +00:00
parent 225a8567a9
commit 2d6cff9f40
4 changed files with 140 additions and 90 deletions
+48 -44
View File
@@ -94,52 +94,56 @@ export default async function BlogDetailPage({
)}
<Reveal delay={0.15} className="flex flex-col gap-6 w-full max-w-[48rem] mx-auto px-[var(--layout-padding-x)] pb-10">
<RichText content={post.content} />
<RichText content={post.content} quoteLabel={post.quoteLabel} />
{/* "Passend dazu" — static cross-promo, not CMS content (same
reasoning as the legal pages' brand callouts): every post
currently points at the same flagship product rather than
needing a per-post "related product" field that nothing else
uses yet. Matches the actual built Figma frame exactly (node
4674:349, fetched via get_design_context) — 1px border-border,
rounded-md, px-9/py-7 padding; an earlier version guessed a
plain borderless row instead, which get_metadata's structural
dump didn't reveal (frame-level stroke/padding/radius aren't
visible there, only get_design_context shows those). */}
<Link
href="/todo-cards"
className="group flex items-center gap-6 border border-border rounded-md px-9 py-7 hover:border-brand transition-colors"
>
<Image alt="" src="/icon-todo-passend-dazu.png" width={64} height={75} className="w-16 h-[4.6875rem] shrink-0 object-contain" />
<div className="flex-1 min-w-0 flex flex-col gap-2.5">
<p className="font-bold text-[0.8125rem] text-brand">Passend dazu:</p>
<div className="flex items-end justify-between gap-4 w-full">
{/* w-[19rem] (305px) — matches Figma's title-col exactly,
so the description wraps at the same point instead of
stretching out to fill the space before "Entdecken". */}
<div className="flex flex-col gap-2 items-start w-[19rem] shrink-0">
<p
className="font-semibold text-[1.375rem] text-text-primary whitespace-nowrap"
style={{ fontFamily: "var(--font-lora)" }}
>
ToDo-Karten
</p>
<p className="text-[0.9375rem] text-text-muted leading-[1.45]">Bringe Struktur in deine Aufgaben und gewinne Zeit zurück.</p>
</div>
<span className="flex items-center gap-1.5 font-bold text-[0.875rem] text-text-primary whitespace-nowrap">
Entdecken
<svg
viewBox="0 0 20 20"
className="size-3.5 transition-transform duration-200 group-hover:translate-x-1"
fill="none"
aria-hidden="true"
>
<path d="M4 10h12m0 0-5-5m5 5-5 5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</span>
{/* "Passend dazu" — per-post CMS content now (Posts.relatedProduct),
not a hardcoded flagship-product link. Hidden entirely if the
post has no related product, or that product has no detail
page to send "Entdecken" to. Matches the actual built Figma
frame exactly (node 4674:349, fetched via get_design_context) —
1px border-border, rounded-md, px-9/py-7 padding; an earlier
version guessed a plain borderless row instead, which
get_metadata's structural dump didn't reveal (frame-level
stroke/padding/radius aren't visible there, only
get_design_context shows those). */}
{post.relatedProduct?.href && (
<Link
href={post.relatedProduct.href}
className="group flex items-center gap-6 border border-border rounded-md px-9 py-7 hover:border-brand transition-colors"
>
<div className="relative w-16 h-[4.6875rem] shrink-0 rounded-sm overflow-hidden">
<Image alt="" src={post.relatedProduct.image} fill sizes="64px" className="object-cover" />
</div>
</div>
</Link>
<div className="flex-1 min-w-0 flex flex-col gap-2.5">
<p className="font-bold text-[0.8125rem] text-brand">Passend dazu:</p>
<div className="flex items-end justify-between gap-4 w-full">
{/* w-[19rem] (305px) — matches Figma's title-col exactly,
so the description wraps at the same point instead of
stretching out to fill the space before "Entdecken". */}
<div className="flex flex-col gap-2 items-start w-[19rem] shrink-0">
<p
className="font-semibold text-[1.375rem] text-text-primary whitespace-nowrap"
style={{ fontFamily: "var(--font-lora)" }}
>
{post.relatedProduct.name}
</p>
<p className="text-[0.9375rem] text-text-muted leading-[1.45]">{post.relatedProduct.description}</p>
</div>
<span className="flex items-center gap-1.5 font-bold text-[0.875rem] text-text-primary whitespace-nowrap">
Entdecken
<svg
viewBox="0 0 20 20"
className="size-3.5 transition-transform duration-200 group-hover:translate-x-1"
fill="none"
aria-hidden="true"
>
<path d="M4 10h12m0 0-5-5m5 5-5 5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</span>
</div>
</div>
</Link>
)}
</Reveal>
{/* Author bio — same hardcoded-brand-chrome reasoning as above;