From 70991a434540d8dc5ffd93ae2cc6b453af3fb6e1 Mon Sep 17 00:00:00 2001 From: Timo Knuth Date: Tue, 30 Sep 2025 23:06:28 +0200 Subject: [PATCH] 1. --- src/app/blog/[slug]/page.tsx | 212 +++++++++++++++++++++++++++++++---- 1 file changed, 190 insertions(+), 22 deletions(-) diff --git a/src/app/blog/[slug]/page.tsx b/src/app/blog/[slug]/page.tsx index 78aa845..d8115ff 100644 --- a/src/app/blog/[slug]/page.tsx +++ b/src/app/blog/[slug]/page.tsx @@ -27,6 +27,27 @@ async function getBlogPost(slug: string): Promise { } } +async function getAllBlogPosts(): Promise { + const baseUrl = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:4005' + + try { + const response = await fetch(`${baseUrl}/posts`, { + cache: 'no-store', + next: { revalidate: 0 } + }) + + if (!response.ok) { + return [] + } + + const payload = await response.json() + return Array.isArray(payload.data) ? payload.data : [] + } catch (error) { + console.error('[frontend] Failed to load posts', error) + return [] + } +} + function formatDate(timestamp: string) { const date = new Date(timestamp) return date.toLocaleDateString('en-US', { @@ -81,6 +102,15 @@ function renderSection(section: BlogPostSection) { ) } +function shuffleArray(array: T[]): T[] { + const shuffled = [...array] + for (let i = shuffled.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]] + } + return shuffled +} + export default async function BlogPostPage({ params }: { params: { slug: string } }) { const post = await getBlogPost(params.slug) @@ -88,6 +118,10 @@ export default async function BlogPostPage({ params }: { params: { slug: string notFound() } + const allPosts = await getAllBlogPosts() + const otherPosts = allPosts.filter(p => p.id !== post.id) + const randomPosts = shuffleArray(otherPosts).slice(0, 3) + const heroImage = resolveMediaUrl(post.previewImage) return ( @@ -98,38 +132,41 @@ export default async function BlogPostPage({ params }: { params: { slug: string width: '100%', margin: '0 auto', padding: '48px 20px', - backgroundColor: '#F7F1E1' + backgroundColor: '#F7F1E1', + position: 'relative' }} > + + ← Back + +
- - ← Back - - {heroImage && (
)}
+ + {randomPosts.length > 0 && ( +
+

+ More Articles +

+
+ {randomPosts.map(article => { + const previewUrl = resolveMediaUrl(article.previewImage) + return ( + + +
+ )}
+ + ) }