From daf5011ef22a59c2f591319fa1cf5ed651c253a1 Mon Sep 17 00:00:00 2001 From: Sean Rose Date: Tue, 10 Mar 2026 22:42:30 +0800 Subject: [PATCH] upgraded pagination with jump to page, page counter, first, prev, next and last page buttons --- app/bookmarks/page.tsx | 92 +++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/app/bookmarks/page.tsx b/app/bookmarks/page.tsx index 260fa5e..48e732f 100644 --- a/app/bookmarks/page.tsx +++ b/app/bookmarks/page.tsx @@ -7,6 +7,8 @@ import { BookmarkX, ChevronLeft, ChevronRight, + ChevronsLeft, + ChevronsRight, LayoutGrid, List, X, @@ -139,59 +141,59 @@ function Pagination({ onChange: (p: number) => void }) { const totalPages = Math.ceil(total / limit) + const [jumpValue, setJumpValue] = useState('') + if (totalPages <= 1) return null - const getPageNumbers = (): (number | 'ellipsis')[] => { - if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i + 1) - const pages: (number | 'ellipsis')[] = [1] - if (page > 3) pages.push('ellipsis') - const start = Math.max(2, page - 1) - const end = Math.min(totalPages - 1, page + 1) - for (let i = start; i <= end; i++) pages.push(i) - if (page < totalPages - 2) pages.push('ellipsis') - pages.push(totalPages) - return pages + function handleJumpKeyDown(e: React.KeyboardEvent) { + if (e.key !== 'Enter') return + const num = parseInt(jumpValue, 10) + if (!isNaN(num) && num >= 1 && num <= totalPages) { + onChange(num) + } + setJumpValue('') } + const navBtnClass = + 'flex items-center justify-center w-9 h-9 rounded-xl text-sm bg-zinc-900 border border-zinc-800 text-zinc-400 hover:text-zinc-100 hover:border-zinc-700 hover:bg-zinc-800 disabled:opacity-25 disabled:cursor-not-allowed transition-all' + return ( -
- +
+ {/* Jump to page */} +
+ Jump to page + setJumpValue(e.target.value)} + onKeyDown={handleJumpKeyDown} + placeholder="—" + className="w-14 px-2 py-1.5 rounded-xl bg-zinc-900 border border-zinc-800 text-zinc-100 placeholder:text-zinc-700 text-sm text-center focus:outline-none focus:border-indigo-500/60 focus:ring-1 focus:ring-indigo-500/20 transition-all [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + /> +
+ + {/* Page indicator */} + + Page {page} of {totalPages} + + {/* Navigation arrows */}
- {getPageNumbers().map((p, i) => - p === 'ellipsis' ? ( - - ) : ( - - ) - )} + + + +
- -
) }