Files
Refinity/src/components/ui/functionalpagination.tsx
2025-08-05 20:38:18 -05:00

170 lines
5.9 KiB
TypeScript

"use client";
import { useSearchParams, useRouter } from "next/navigation";
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
interface FunctionalPaginationProps {
hasNextPage?: boolean; // Whether there are more results
showPageNumbers?: number; // How many page numbers to show around current (default: 2)
}
export default function FunctionalPagination({
hasNextPage = true, // Assume there's a next page unless told otherwise
showPageNumbers = 2
}: FunctionalPaginationProps) {
const searchParams = useSearchParams();
const router = useRouter();
const currentPage = parseInt(searchParams.get("p") || "1");
const searchQuery = searchParams.get("q") || "";
const pageSize = searchParams.get("pageSize") || "10";
// Generate URL for a specific page
const generatePageUrl = (page: number) => {
const params = new URLSearchParams();
if (searchQuery) params.set("q", searchQuery);
params.set("p", page.toString());
params.set("pageSize", pageSize);
return `/search?${params.toString()}`;
};
// Handle page navigation
const navigateToPage = (page: number) => {
if (page < 1) return;
router.push(generatePageUrl(page));
};
// Calculate which page numbers to show (pages around current page)
const getPageNumbers = () => {
const pages: number[] = [];
// Show pages around current page
const start = Math.max(1, currentPage - showPageNumbers);
const end = currentPage + showPageNumbers;
for (let i = start; i <= end; i++) {
pages.push(i);
}
return pages;
};
const pageNumbers = getPageNumbers();
return (
<Pagination>
<PaginationContent>
{/* Previous Button */}
<PaginationItem>
<PaginationPrevious
href={currentPage > 1 ? generatePageUrl(currentPage - 1) : "#"}
onClick={(e) => {
if (currentPage <= 1) {
e.preventDefault();
return;
}
e.preventDefault();
navigateToPage(currentPage - 1);
}}
className={currentPage <= 1 ? "pointer-events-none opacity-50" : ""}
/>
</PaginationItem>
{/* Page Numbers */}
{pageNumbers.map((page) => (
<PaginationItem key={page}>
<PaginationLink
href={generatePageUrl(page)}
onClick={(e) => {
e.preventDefault();
navigateToPage(page);
}}
isActive={page === currentPage}
>
{page}
</PaginationLink>
</PaginationItem>
))}
{/* Next Button */}
<PaginationItem>
<PaginationNext
href={hasNextPage ? generatePageUrl(currentPage + 1) : "#"}
onClick={(e) => {
if (!hasNextPage) {
e.preventDefault();
return;
}
e.preventDefault();
navigateToPage(currentPage + 1);
}}
className={!hasNextPage ? "pointer-events-none opacity-50" : ""}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
);
}
// Alternative simpler version if you just want basic prev/next
export function SimplePagination() {
const searchParams = useSearchParams();
const router = useRouter();
const currentPage = parseInt(searchParams.get("p") || "1");
const searchQuery = searchParams.get("q") || "";
const pageSize = searchParams.get("pageSize") || "10";
const generatePageUrl = (page: number) => {
const params = new URLSearchParams();
if (searchQuery) params.set("q", searchQuery);
params.set("p", page.toString());
params.set("pageSize", pageSize);
return `/search?${params.toString()}`;
};
const navigateToPage = (page: number) => {
if (page < 1) return;
router.push(generatePageUrl(page));
};
return (
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious
href={currentPage > 1 ? generatePageUrl(currentPage - 1) : "#"}
onClick={(e) => {
e.preventDefault();
if (currentPage > 1) navigateToPage(currentPage - 1);
}}
className={currentPage <= 1 ? "pointer-events-none opacity-50" : ""}
/>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
{currentPage}
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext
href={generatePageUrl(currentPage + 1)}
onClick={(e) => {
e.preventDefault();
navigateToPage(currentPage + 1);
}}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
);
}