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