@@ -3,18 +3,19 @@ import { Link } from 'react-router-dom'
33import usePages from '../store/usePages'
44import useTags from '../store/useTags'
55
6+ const PER_PAGE = 20
7+
68export default function Home ( ) {
79 const { pages, total, loading, fetchPages } = usePages ( )
810 const { allTags, fetchAllTags } = useTags ( )
9- const [ selectedTag , setSelectedTag ] = useState ( '' )
11+ const [ page , setPage ] = useState ( 1 )
1012
1113 useEffect ( ( ) => {
12- fetchPages ( )
14+ fetchPages ( page , PER_PAGE )
1315 fetchAllTags ( )
14- } , [ ] )
16+ } , [ page ] )
1517
16- // Client-side tag filter (since tag filter on list isn't in the backend yet for list endpoint)
17- const filteredPages = pages
18+ const totalPages = Math . ceil ( total / PER_PAGE )
1819
1920 return (
2021 < div className = "max-w-4xl mx-auto" >
@@ -45,7 +46,7 @@ export default function Home() {
4546
4647 { loading ? (
4748 < p className = "text-gray-500" > Loading...</ p >
48- ) : filteredPages . length === 0 ? (
49+ ) : pages . length === 0 ? (
4950 < div className = "text-center py-16" >
5051 < p className = "text-gray-400 text-lg mb-4" > No pages yet</ p >
5152 < Link
@@ -56,22 +57,59 @@ export default function Home() {
5657 </ Link >
5758 </ div >
5859 ) : (
59- < div className = "bg-white rounded-xl shadow-sm border border-gray-200" >
60- { filteredPages . map ( ( page , i ) => (
61- < Link
62- key = { page . id }
63- to = { `/page/${ page . slug } ` }
64- className = { `block px-5 py-4 hover:bg-gray-50 transition-colors ${
65- i > 0 ? 'border-t border-gray-100' : ''
66- } `}
67- >
68- < div className = "font-medium text-gray-800" > { page . title } </ div >
69- < div className = "text-sm text-gray-400 mt-1" >
70- /{ page . slug } · { new Date ( page . updated_at ) . toLocaleDateString ( ) } · { page . view_count } views
60+ < >
61+ < div className = "bg-white rounded-xl shadow-sm border border-gray-200" >
62+ { pages . map ( ( p , i ) => (
63+ < Link
64+ key = { p . id }
65+ to = { `/page/${ p . slug } ` }
66+ className = { `block px-5 py-4 hover:bg-gray-50 transition-colors ${
67+ i > 0 ? 'border-t border-gray-100' : ''
68+ } `}
69+ >
70+ < div className = "font-medium text-gray-800" > { p . title } </ div >
71+ < div className = "text-sm text-gray-400 mt-1" >
72+ /{ p . slug } · { new Date ( p . updated_at ) . toLocaleDateString ( ) } · { p . view_count } views
73+ </ div >
74+ </ Link >
75+ ) ) }
76+ </ div >
77+
78+ { /* Pagination */ }
79+ { totalPages > 1 && (
80+ < div className = "flex items-center justify-center gap-2 mt-6" >
81+ < button
82+ onClick = { ( ) => setPage ( ( p ) => Math . max ( 1 , p - 1 ) ) }
83+ disabled = { page === 1 }
84+ className = "px-3 py-1.5 text-sm rounded-lg border border-gray-200 hover:bg-gray-50 disabled:opacity-40 disabled:cursor-not-allowed"
85+ >
86+ Previous
87+ </ button >
88+ < div className = "flex gap-1" >
89+ { Array . from ( { length : totalPages } , ( _ , i ) => i + 1 ) . map ( ( p ) => (
90+ < button
91+ key = { p }
92+ onClick = { ( ) => setPage ( p ) }
93+ className = { `w-8 h-8 text-sm rounded-lg ${
94+ p === page
95+ ? 'bg-blue-600 text-white'
96+ : 'hover:bg-gray-100 text-gray-600'
97+ } `}
98+ >
99+ { p }
100+ </ button >
101+ ) ) }
71102 </ div >
72- </ Link >
73- ) ) }
74- </ div >
103+ < button
104+ onClick = { ( ) => setPage ( ( p ) => Math . min ( totalPages , p + 1 ) ) }
105+ disabled = { page === totalPages }
106+ className = "px-3 py-1.5 text-sm rounded-lg border border-gray-200 hover:bg-gray-50 disabled:opacity-40 disabled:cursor-not-allowed"
107+ >
108+ Next
109+ </ button >
110+ </ div >
111+ ) }
112+ </ >
75113 ) }
76114 </ div >
77115 )
0 commit comments