170 lines
5.9 KiB
TypeScript
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>
|
|
);
|
|
} |