-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathpage.tsx
More file actions
141 lines (125 loc) · 4.39 KB
/
page.tsx
File metadata and controls
141 lines (125 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"use client"
import { useEffect, useState, useCallback } from "react"
import { useRouter, useSearchParams } from "next/navigation"
import { getPaginatedPosts } from "@/lib/blog"
import BlogCard from "@/components/blog-card"
import Pagination from "@/components/pagination"
import Link from "next/link"
import Footer from "@/components/footer"
interface BlogPost {
slug: string
title: string
author: string
date: string
image: string
excerpt: string
featured: boolean
}
interface PaginatedData {
posts: BlogPost[]
totalPages: number
hasNextPage: boolean
hasPrevPage: boolean
}
export default function HomePage() {
const router = useRouter()
const searchParams = useSearchParams()
const [paginatedData, setPaginatedData] = useState<PaginatedData | null>(null)
const [loading, setLoading] = useState(true)
const [currentPage, setCurrentPage] = useState(1)
// Get current page from URL
const getPageFromUrl = useCallback(() => {
const pageParam = searchParams.get("page")
if (!pageParam) return 1
const page = Number.parseInt(pageParam, 10)
return isNaN(page) || page < 1 ? 1 : page
}, [searchParams])
// Update current page when URL changes
useEffect(() => {
const urlPage = getPageFromUrl()
if (urlPage !== currentPage) {
setCurrentPage(urlPage)
}
}, [searchParams, getPageFromUrl, currentPage])
// Load posts when current page changes
useEffect(() => {
function loadPosts() {
setLoading(true)
try {
const data = getPaginatedPosts(currentPage, 12)
setPaginatedData(data)
} catch (error) {
console.error("Error loading posts:", error)
} finally {
setLoading(false)
}
}
loadPosts()
}, [currentPage])
const handlePageChange = useCallback(
(page: number) => {
if (page < 1) page = 1
setCurrentPage(page)
router.push(`/?page=${page}`, { scroll: false })
},
[router],
)
if (loading) {
return (
<div className="min-h-screen bg-gradient-to-br from-green-50 via-yellow-50 to-[#FFC517]/10 flex items-center justify-center">
<div className="text-center">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[#228B22] mx-auto mb-4"></div>
<p className="text-gray-600">Loading articles...</p>
</div>
</div>
)
}
if (!paginatedData) {
return (
<div className="min-h-screen bg-gradient-to-br from-green-50 via-yellow-50 to-[#FFC517]/10 flex items-center justify-center">
<div className="text-center">
<p className="text-gray-600">Failed to load articles.</p>
</div>
</div>
)
}
const { posts, totalPages, hasNextPage, hasPrevPage } = paginatedData
return (
<div className="min-h-screen bg-gradient-to-br from-green-50 via-yellow-50 to-[#FFC517]/10">
{/* Header */}
<header className="border-b border-gradient-to-r from-[#228B22]/20 to-[#FFBF00]/20 bg-white/90 backdrop-blur-sm sticky top-0 z-50 shadow-sm">
<div className="max-w-6xl mx-auto px-4 py-3 flex justify-between items-center">
<div>
<h1 className="text-3xl font-bold font-playfair bg-gradient-to-r from-[#228B22] via-[#5A981A] via-[#91A511] via-[#ADAC0D] via-[#E4B905] to-[#FFBF00] bg-clip-text text-transparent drop-shadow-sm leading-tight pb-2">
Stable Viewpoints
</h1>
<p className="text-gray-600 mt-2 text-base">Independent Articles about Stability</p>
</div>
<Link
href="/submit"
className="inline-flex items-center gap-2 bg-gradient-to-r from-[#228B22] to-[#91A511] hover:from-[#3E921E] hover:to-[#ADAC0D] text-white px-6 py-2 font-semibold transition-all duration-300 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5"
>
Submit an Article
</Link>
</div>
</header>
{/* Main Content */}
<main className="max-w-6xl mx-auto px-4 py-12">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{posts.map((post) => (
<BlogCard key={post.slug} post={post} />
))}
</div>
{/* Pagination */}
<Pagination
currentPage={currentPage}
totalPages={totalPages}
hasNextPage={hasNextPage}
hasPrevPage={hasPrevPage}
onPageChange={handlePageChange}
/>
</main>
<Footer />
</div>
)
}