feat: add Pagination - WIP

This commit is contained in:
Pablo Lara
2024-08-08 20:08:11 +02:00
parent ca3d076607
commit bed2b1e7f7
7 changed files with 161 additions and 16 deletions
+23 -6
View File
@@ -4,19 +4,36 @@ import { revalidatePath } from "next/cache";
import { parseStringify } from "@/lib";
export const getProvider = async () => {
interface PaginationOptions {
page?: number;
}
export const getProvider = async ({ page = 1 }: PaginationOptions) => {
if (isNaN(Number(page))) page = 1;
if (page < 1) page = 1;
const keyServer = process.env.LOCAL_SERVER_URL;
try {
const providers = await fetch(`${keyServer}/providers`, {
headers: {
"X-Tenant-ID": `${process.env.HEADER_TENANT_ID}`,
const providers = await fetch(
`${keyServer}/providers?page%5Bnumber%5D=${page}`,
{
headers: {
"X-Tenant-ID": `${process.env.HEADER_TENANT_ID}`,
},
},
});
);
const data = await providers.json();
const parsedData = parseStringify(data);
revalidatePath("/providers");
return parseStringify(data);
return {
providerDetails: parsedData?.data,
currentPage: parsedData?.meta?.pagination?.page,
totalPages: parsedData?.meta?.pagination?.pages,
totalItems: parsedData?.meta?.pagination?.count,
};
} catch (error) {
console.error("Error fetching providers:", error);
return undefined;
}
};
+38 -8
View File
@@ -1,4 +1,5 @@
import { Spacer } from "@nextui-org/react";
import { redirect } from "next/navigation";
import { Suspense } from "react";
import { getProvider } from "@/actions";
@@ -8,9 +9,16 @@ import {
DataTableProvider,
SkeletonTableProvider,
} from "@/components/providers";
import { Header } from "@/components/ui";
import { Header, Pagination } from "@/components/ui";
export default async function Providers() {
export default async function Providers({
searchParams,
}: {
searchParams: {
page: number;
};
}) {
console.log({ searchParams }, "los searchParamsss!");
return (
<>
<Header title="Providers" icon="fluent:cloud-sync-24-regular" />
@@ -20,18 +28,40 @@ export default async function Providers() {
<AddProviderModal />
</div>
<Spacer y={6} />
<Suspense fallback={<SkeletonTableProvider />}>
<SSRDataTable />
<Suspense key={searchParams.page} fallback={<SkeletonTableProvider />}>
<SSRDataTable searchParams={searchParams} />
</Suspense>
</div>
</>
);
}
const SSRDataTable = async () => {
const providersData = await getProvider();
const [providers] = await Promise.all([providersData]);
const SSRDataTable = async ({
searchParams,
}: {
searchParams: {
page: number;
};
}) => {
// const perPage = searchParams['per_page'] ?? '5'
// const page = searchParams.page ? parseInt(searchParams.page) : 1;
const providersData = await getProvider({});
// const [providers] = await Promise.all([providersData]);
// const { providerDetails, currentPage, totalPages, totalItems } = providersData;
// console.log(currentPage, totalPages, 'hehe')
// if (providers.meta.pagination.count === 0) {
// redirect('/');
// }
// console.log(providers);
// const currentPage = providers.meta.pagination.page;
// const pages = providers.meta.pagination.pages;
// const count = providers.meta.pagination.count;
// console.log(`Pages: ${pages}, Count: ${count}`);
return (
<DataTableProvider columns={ColumnsProvider} data={providers?.data ?? []} />
<>
{/* <DataTableProvider columns={ColumnsProvider} data={providerDetails ?? []} /> */}
{/* <Pagination totalPages={totalPages} currentPage={currentPage} /> */}
</>
);
};
+3 -1
View File
@@ -48,7 +48,9 @@ export const AddProviderModal = () => {
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="ghost">Add Cloud Account</Button>
<Button aria-label="Add Cloud Account" variant="ghost">
Add Cloud Account
</Button>
</DialogTrigger>
<DialogContent className="flex flex-col sm:max-w-md md:max-w-4xl">
<DialogHeader className="mb-6 space-y-3">
@@ -15,6 +15,7 @@ interface DataTablePaginationProps<TData> {
export function DataTablePagination<TData>({
table,
}: DataTablePaginationProps<TData>) {
// console.log(table);
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="flex flex-col-reverse items-center gap-4 sm:flex-row sm:gap-6 lg:gap-8">
@@ -45,7 +45,6 @@ export function DataTableProvider<TData, TValue>({
sorting,
},
});
return (
<>
<div className="rounded-md border w-full">
+1
View File
@@ -1,6 +1,7 @@
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
@@ -0,0 +1,95 @@
"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>
);
};