Skip to content

Commit 1b1edd1

Browse files
committed
fix: Home.jsx zeigt jetzt reine Blog-Liste statt Landing Page Hero
1 parent 4fe2fa4 commit 1b1edd1

File tree

1 file changed

+101
-25
lines changed

1 file changed

+101
-25
lines changed

src/pages/Home.jsx

Lines changed: 101 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,112 @@
1-
import { useEffect } from 'react'
2-
import { useLocation, useNavigate } from 'react-router-dom'
3-
import Hero from '../components/Hero'
4-
import TutorialSection from '../components/TutorialSection'
5-
import { scrollToSection } from '../utils/scrollToSection'
1+
import { useState, useEffect } from 'react'
2+
import { Loader2 } from 'lucide-react'
3+
import PostCard from '../components/dynamic-page/PostCard'
4+
import { api } from '../api/client'
65

76
/**
8-
* The application's homepage component.
7+
* Blog Home Page - Shows all published posts from all pages.
98
*
10-
* Acts as the primary landing point for authenticated or returning users.
11-
*
12-
* Features:
13-
* - Smart Scroll Restoration: Handles `location.state.scrollTo` to jump to specific sections upon navigation.
14-
* - Composition: Combines the `Hero` (standard) and `TutorialSection` components.
9+
* This replaces the previous landing-style Hero component with a clean
10+
* blog listing view. Posts are fetched from all CMS pages and displayed
11+
* in a unified list.
1512
*/
1613
const Home = () => {
17-
const location = useLocation()
18-
const navigate = useNavigate()
14+
const [posts, setPosts] = useState([])
15+
const [loading, setLoading] = useState(true)
16+
const [error, setError] = useState(null)
17+
1918
useEffect(() => {
20-
const targetSection = location.state?.scrollTo
21-
if (!targetSection) {
22-
return
19+
const fetchAllPosts = async () => {
20+
try {
21+
setLoading(true)
22+
// Fetch all pages
23+
const pagesData = await api.listPages()
24+
if (!pagesData?.items) {
25+
setPosts([])
26+
return
27+
}
28+
29+
// Fetch posts from each page
30+
const allPosts = []
31+
for (const page of pagesData.items) {
32+
try {
33+
const postsData = await api.listPublishedPosts(page.slug)
34+
if (postsData?.items) {
35+
postsData.items.forEach(post => {
36+
allPosts.push({
37+
...post,
38+
pageSlug: page.slug,
39+
pageTitle: page.title
40+
})
41+
})
42+
}
43+
} catch (e) {
44+
// Page might have no posts, that's ok
45+
}
46+
}
47+
48+
// Sort by creation date, newest first
49+
allPosts.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
50+
setPosts(allPosts)
51+
} catch (err) {
52+
console.error('Error fetching posts:', err)
53+
setError(err)
54+
} finally {
55+
setLoading(false)
56+
}
2357
}
24-
requestAnimationFrame(() => {
25-
scrollToSection(targetSection)
26-
})
27-
navigate(location.pathname, { replace: true, state: {} })
28-
}, [location, navigate])
58+
59+
fetchAllPosts()
60+
}, [])
61+
2962
return (
30-
<>
31-
<Hero />
32-
<TutorialSection />
33-
</>
63+
<main className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-slate-100 dark:from-slate-950 dark:via-slate-900 dark:to-slate-950">
64+
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 pt-28 pb-16">
65+
{/* Page Header */}
66+
<div className="mb-12 text-center">
67+
<h1 className="text-4xl font-bold text-gray-900 dark:text-white mb-4">
68+
Blog
69+
</h1>
70+
<p className="text-lg text-gray-600 dark:text-slate-300">
71+
Alle veröffentlichten Artikel
72+
</p>
73+
</div>
74+
75+
{/* Content */}
76+
{loading ? (
77+
<div className="flex flex-col items-center justify-center py-20 text-gray-500 dark:text-slate-400">
78+
<Loader2 className="w-10 h-10 animate-spin mb-4" />
79+
<p>Lade Artikel…</p>
80+
</div>
81+
) : error ? (
82+
<div className="rounded-2xl border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-900/20 p-6 text-red-700 dark:text-red-300">
83+
<h2 className="font-semibold mb-1">Fehler beim Laden</h2>
84+
<p className="text-sm">{error.message || 'Unbekannter Fehler'}</p>
85+
</div>
86+
) : posts.length === 0 ? (
87+
<div className="rounded-2xl border border-gray-200 dark:border-slate-800 bg-white dark:bg-slate-900/80 p-10 text-center">
88+
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">
89+
Noch keine Artikel
90+
</h2>
91+
<p className="text-gray-500 dark:text-slate-400">
92+
Sobald Artikel veröffentlicht werden, erscheinen sie hier.
93+
</p>
94+
</div>
95+
) : (
96+
<div className="space-y-8">
97+
<p className="text-sm text-gray-500 dark:text-slate-400">
98+
{posts.length} {posts.length === 1 ? 'Artikel' : 'Artikel'}
99+
</p>
100+
<div className="space-y-10">
101+
{posts.map((post) => (
102+
<PostCard key={`${post.pageSlug}-${post.id}`} post={post} pageSlug={post.pageSlug} />
103+
))}
104+
</div>
105+
</div>
106+
)}
107+
</div>
108+
</main>
34109
)
35110
}
111+
36112
export default Home

0 commit comments

Comments
 (0)