CustomPagination.tsx raw
1 import { useMemo } from "react";
2 import {
3 Pagination,
4 PaginationContent,
5 PaginationEllipsis,
6 PaginationItem,
7 PaginationLink,
8 PaginationNext,
9 PaginationPrevious,
10 } from "src/components/ui/pagination";
11 import { cn, generatePageNumbers } from "src/lib/utils";
12
13 type CustomPaginationProps = {
14 page: number;
15 limit: number;
16 totalCount: number;
17 handlePageChange(page: number): void;
18 };
19
20 export function CustomPagination({
21 page,
22 totalCount,
23 limit,
24 handlePageChange,
25 }: CustomPaginationProps) {
26 const totalPages = Math.ceil(totalCount / limit);
27
28 const pageNumbers = useMemo(() => {
29 return generatePageNumbers(page, totalPages);
30 }, [page, totalPages]);
31
32 if (totalPages <= 1) {
33 return null;
34 }
35 return (
36 <div className="mt-4 self-center">
37 <Pagination>
38 <PaginationContent>
39 <PaginationItem
40 className={cn(
41 page === 1 && "pointer-events-none opacity-30 dark:opacity-20"
42 )}
43 >
44 <PaginationPrevious
45 href="#"
46 onClick={(e) => {
47 e.preventDefault();
48 handlePageChange(page - 1);
49 }}
50 />
51 </PaginationItem>
52
53 {pageNumbers.map((p, index) =>
54 p === "ellipsis" ? (
55 <PaginationItem key={index}>
56 <PaginationEllipsis className="flex items-center" />
57 </PaginationItem>
58 ) : (
59 <PaginationItem key={index}>
60 <PaginationLink
61 href="#"
62 isActive={p === page}
63 onClick={(e) => {
64 e.preventDefault();
65 handlePageChange(p);
66 }}
67 >
68 {p}
69 </PaginationLink>
70 </PaginationItem>
71 )
72 )}
73
74 <PaginationItem
75 className={cn(
76 page === totalPages &&
77 "pointer-events-none opacity-30 dark:opacity-20"
78 )}
79 >
80 <PaginationNext
81 href="#"
82 onClick={(e) => {
83 e.preventDefault();
84 handlePageChange(page + 1);
85 }}
86 />
87 </PaginationItem>
88 </PaginationContent>
89 </Pagination>
90 </div>
91 );
92 }
93