From 35670126cae62da3310fe8da1f12d106ba90dee2 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 2 Jul 2026 13:27:14 +0000 Subject: [PATCH] Wire up the blog section to Payload CMS instead of hardcoded posts Blog.tsx now fetches the einfach-produktiv tenant's posts from the shared Payload instance at build/render time (ISR, 60s revalidate), via a small typed fetch helper in app/lib/payload.ts. Co-Authored-By: Claude Sonnet 5 --- app/components/Blog.tsx | 48 ++++++++++------------------------ app/lib/payload.ts | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 35 deletions(-) create mode 100644 app/lib/payload.ts diff --git a/app/components/Blog.tsx b/app/components/Blog.tsx index cd1f9e3..9a5a623 100644 --- a/app/components/Blog.tsx +++ b/app/components/Blog.tsx @@ -1,37 +1,15 @@ import Link from "next/link"; +import { getBlogPosts } from "../lib/payload"; -const featured = { - thumbnail: "/blog-featured.jpg", - category: "Fokus", - readTime: "5 Min", - title: "Der Feierabend-Knopf", - excerpt: - "So schaffst du deinen Tag wirklich im Feierabend und nicht, wenn der Laptop zu ist. Feierabend, wenn du ihn lebst", - href: "/blog/feierabend-knopf", -}; +export async function Blog() { + const posts = await getBlogPosts(3); + if (posts.length === 0) return null; -const secondary = [ - { - thumbnail: "/blog-post-1.jpg", - category: "Methoden", - readTime: "6 Min", - title: "Die 2-Minuten-Regel richtig anwenden", - excerpt: - "Warum sie wirklich funktioniert – und wie du sie in deinem Alltag clever nutzt.", - href: "/blog/2-minuten-regel", - }, - { - thumbnail: "/blog-post-2.jpg", - category: "Tools", - readTime: "4 Min", - title: "Die Promodoro-Technik für deinen Alltag", - excerpt: - "Effektives Zeitmanagement in vier kleinen Schritten, die dir helfen, fokussiert und mit mehr Energie zu arbeiten.", - href: "/blog/promodoro-technik", - }, -]; + const featured = { ...posts[0], href: `/blog/${posts[0].slug}` }; + const secondary = posts + .slice(1, 3) + .map((post) => ({ ...post, href: `/blog/${post.slug}` })); -export function Blog() { return (
@@ -56,7 +34,7 @@ export function Blog() {
@@ -65,7 +43,7 @@ export function Blog() {
{featured.category} - {featured.readTime} + {featured.readTime} Min

{secondary.map((post) => (

{/* Thumbnail: own border-radius so it sits neatly inside the padded card */}
@@ -108,7 +86,7 @@ export function Blog() {
{post.category} - {post.readTime} + {post.readTime} Min

{ + const params = new URLSearchParams({ + "where[tenant.slug][equals]": TENANT_SLUG, + sort: "-publishedAt", + depth: "2", + limit: String(limit), + }); + + const res = await fetch(`${PAYLOAD_URL}/api/posts?${params}`, { + next: { revalidate: 60 }, + }); + if (!res.ok) { + console.error(`getBlogPosts: Payload returned ${res.status} ${res.statusText}`); + return []; + } + + const data: { docs?: PayloadPost[] } = await res.json(); + const docs = Array.isArray(data.docs) ? data.docs : []; + return docs.map((post) => ({ + id: post.id, + title: post.title, + slug: post.slug, + category: + typeof post.category === "object" && post.category + ? post.category.name + : "", + readTime: post.readTime, + excerpt: post.excerpt, + thumbnail: + typeof post.thumbnail === "object" && post.thumbnail + ? post.thumbnail.url + : null, + })); +}