feat: add functionality to the Pagination component

This commit is contained in:
Pablo Lara committed 2024-08-09 11:54:58 +02:00
1 parent bed2b1e7f7
commit 5bb3c012c9
8 files changed
+100 -180

No files matched your search

@@ -1,65 +1,83 @@
import { Button } from "@nextui-org/react";
"use client";
import {
ChevronLeftIcon,
ChevronRightIcon,
DoubleArrowLeftIcon,
DoubleArrowRightIcon,
} from "@radix-ui/react-icons";
import { type Table } from "@tanstack/react-table";
import Link from "next/link";
import { redirect, usePathname, useSearchParams } from "next/navigation";
interface DataTablePaginationProps<TData> {
table: Table<TData>;
import { extractPaginationInfo } from "@/lib";
import { MetaDataProps } from "@/types";
interface DataTablePaginationProps {
pageSizeOptions?: number[];
metadata?: MetaDataProps;
}
export function DataTablePagination<TData>({
table,
}: DataTablePaginationProps<TData>) {
// console.log(table);
export function DataTablePagination({ metadata }: DataTablePaginationProps) {
if (!metadata) return null;
const pathname = usePathname();
const searchParams = useSearchParams();
const { currentPage, totalPages, totalEntries } =
extractPaginationInfo(metadata);
const createPageUrl = (pageNumber: number | string) => {
const params = new URLSearchParams(searchParams);
if (pageNumber === "...") return `${pathname}?${params.toString()}`;
if (+pageNumber > totalPages) {
return `${pathname}?${params.toString()}`;
}
params.set("page", pageNumber.toString());
return `${pathname}?${params.toString()}`;
};
return (
<div className="flex w-full flex-col-reverse items-center justify-between gap-4 overflow-auto p-1 sm:flex-row sm:gap-8">
<div className="whitespace-nowrap text-sm font-medium">
{totalEntries} entries in Total.
</div>
<div className="flex flex-col-reverse items-center gap-4 sm:flex-row sm:gap-6 lg:gap-8">
<div className="flex items-center justify-center text-sm font-medium">
Page {table.getState().pagination.pageIndex + 1} of{" "}
{table.getPageCount()}
Page {currentPage} of {totalPages}
</div>
<div className="flex items-center space-x-2">
<Button
<Link
aria-label="Go to first page"
variant="light"
className="hidden size-8 p-0 lg:flex"
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href={createPageUrl(1)}
aria-disabled="true"
>
<DoubleArrowLeftIcon className="size-4" aria-hidden="true" />
</Button>
<Button
</Link>
<Link
aria-label="Go to previous page"
variant="light"
className="size-8"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href={createPageUrl(currentPage - 1)}
aria-disabled="true"
>
<ChevronLeftIcon className="size-4" aria-hidden="true" />
</Button>
<Button
</Link>
<Link
aria-label="Go to next page"
variant="light"
className="size-8"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href={createPageUrl(currentPage + 1)}
>
<ChevronRightIcon className="size-4" aria-hidden="true" />
</Button>
<Button
</Link>
<Link
aria-label="Go to last page"
variant="light"
className="hidden size-8 lg:flex"
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href={createPageUrl(totalPages)}
>
<DoubleArrowRightIcon className="size-4" aria-hidden="true" />
</Button>
</Link>
</div>
</div>
</div>
@@ -19,20 +19,22 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table/Table";
import { MetaDataProps } from "@/types";
import { DataTablePagination } from "./DataTablePagination";
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
data: TData[];
metadata?: MetaDataProps;
}
export function DataTableProvider<TData, TValue>({
columns,
data,
metadata,
}: DataTableProps<TData, TValue>) {
const [sorting, setSorting] = useState<SortingState>([]);
const table = useReactTable({
data,
columns,
@@ -97,8 +99,8 @@ export function DataTableProvider<TData, TValue>({
</TableBody>
</Table>
</div>
<div className="flex items-center justify-end space-x-2 py-4">
<DataTablePagination table={table} />
<div className="flex items-center w-full space-x-2 py-4">
<DataTablePagination metadata={metadata} />
</div>
</>
);
-1
View File
@@ -1,7 +1,6 @@
export * from "./alert/Alert";
export * from "./dialog/Dialog";
export * from "./header/Header";
export * from "./pagination/Pagination";
export * from "./select/Select";
export * from "./sidebar";
export * from "./table/StatusBadge";
-95
View File
@@ -1,95 +0,0 @@
"use client";
import Link from "next/link";
import { usePathname, useSearchParams } from "next/navigation";
import React from "react";
interface Props {
totalPages: number;
currentPage: number;
nextPage?: string;
}
export const Pagination = ({ totalPages, currentPage }: Props) => {
const pathname = usePathname();
const searchParams = useSearchParams();
// const currentPage = searchParams["page"] ?? "1";
const createPageUrl = (pageNumber: number | string) => {
const params = new URLSearchParams(searchParams);
if (pageNumber === "...") return `${pathname}?${params.toString()}`;
if (+pageNumber <= 0) {
return `${pathname}`;
}
if (+pageNumber > totalPages) {
return `${pathname}?${params.toString()}`;
}
params.set("page", pageNumber.toString());
return `${pathname}?${params.toString()}`;
};
console.log(pathname, searchParams, currentPage);
return (
<div className="flex justify-center">
<nav aria-label="Page navigation example">
<ul className="flex list-style-none">
<li className="page-item">
<Link
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href={createPageUrl(currentPage - 1)}
aria-disabled="true"
>
Previous
</Link>
</li>
<li className="page-item">
<a
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href="#"
>
1
</a>
</li>
<li className="page-item active">
<a
className="page-link relative block py-1.5 px-3 border-0 bg-blue-600 outline-none transition-all duration-300 rounded text-white hover:text-white hover:bg-blue-600 shadow-md focus:shadow-md"
href="#"
>
2 <span className="visually-hidden"></span>
</a>
</li>
<li className="page-item">
<a
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href="#"
>
3
</a>
</li>
<li className="page-item">
<a
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href="#"
>
...
</a>
</li>
<li className="page-item">
<Link
className="page-link relative block py-1.5 px-3 border-0 bg-transparent outline-none transition-all duration-300 rounded text-gray-800 hover:text-gray-800 hover:bg-gray-200 focus:shadow-none"
href={"#"}
>
Next
</Link>
</li>
</ul>
</nav>
</div>
);
};