mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
feat: add Pagination - WIP
This commit is contained in:
+23
-6
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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} /> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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,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";
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user