From 9defc8a391afc36a927f2728f768faefd83c46e9 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 14:47:27 +0100 Subject: [PATCH] NORY-41: add new pagination --- dashboard/src/app/(inside)/user/page.tsx | 10 ++- dashboard/src/components/pagination.tsx | 101 ++++++++++++++++++++++ dashboard/src/components/search-input.tsx | 5 +- dashboard/src/lib/action/identity.ts | 8 ++ 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 dashboard/src/components/pagination.tsx diff --git a/dashboard/src/app/(inside)/user/page.tsx b/dashboard/src/app/(inside)/user/page.tsx index 92eee5e..2c4b825 100644 --- a/dashboard/src/app/(inside)/user/page.tsx +++ b/dashboard/src/app/(inside)/user/page.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { IdentityDataTable } from '@/app/(inside)/user/data-table'; import { SearchInput } from '@/components/search-input'; import { queryIdentities } from '@/lib/action/identity'; +import { IdentityPagination } from '@/components/pagination'; export default async function UserPage( { @@ -17,6 +18,7 @@ export default async function UserPage( const query = params.query ? params.query as string : ''; let pageSize = 50; + let paginationRange = 11; const { data, pageCount } = await queryIdentities({ page, pageSize, query }); @@ -31,12 +33,18 @@ export default async function UserPage(
+ placeholder="Search for addresses and traits"/> +
); diff --git a/dashboard/src/components/pagination.tsx b/dashboard/src/components/pagination.tsx new file mode 100644 index 0000000..6e16bc2 --- /dev/null +++ b/dashboard/src/components/pagination.tsx @@ -0,0 +1,101 @@ +'use client'; + +import { + Pagination, + PaginationContent, + PaginationEllipsis, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, +} from '@/components/ui/pagination'; +import { usePathname, useSearchParams } from 'next/navigation'; + +interface IdentityPaginationProps { + page: number; + pageCount: number; + pageParamKey: string; + paginationRange: number; +} + +export function IdentityPagination( + { + page, + pageCount, + pageParamKey, + paginationRange, + }: IdentityPaginationProps, +) { + + const pathname = usePathname(); + const searchParams = useSearchParams(); + + function updatePage(page: number): string { + const newParams = new URLSearchParams(searchParams.toString()); + + if (page <= 1) { + newParams.delete(pageParamKey); + } else { + newParams.set(pageParamKey, page.toString()); + } + + return pathname + '?' + newParams.toString(); + } + + return ( + + + { + page > 1 && ( + + + + ) + } + { + page - (paginationRange / 2) > 1 && + + + + } + { + Array.from({ length: paginationRange }, (_, i) => { + + const difference = (i + 1) - Math.round(paginationRange / 2); + const nextPage = page + difference; + + if (nextPage < 1 || nextPage > pageCount) { + return; + } + + return ( + + + {nextPage} + + + ); + }) + } + { + page + (paginationRange / 2) < pageCount && + + + + } + { + page < pageCount && ( + + + + ) + } + + + ); +} \ No newline at end of file diff --git a/dashboard/src/components/search-input.tsx b/dashboard/src/components/search-input.tsx index 600c566..d40dd65 100644 --- a/dashboard/src/components/search-input.tsx +++ b/dashboard/src/components/search-input.tsx @@ -7,12 +7,13 @@ import { ChangeEvent, HTMLInputTypeAttribute } from 'react'; interface SearchInputProps { value: string; placeholder: string; + pageParamKey: string; queryParamKey: string; type?: HTMLInputTypeAttribute; className?: string; } -export function SearchInput({ value, placeholder, queryParamKey, type, className }: SearchInputProps) { +export function SearchInput({ value, placeholder, pageParamKey, queryParamKey, type, className }: SearchInputProps) { const router = useRouter(); const params = useSearchParams(); @@ -28,6 +29,8 @@ export function SearchInput({ value, placeholder, queryParamKey, type, className newParams.set(queryParamKey, value); } + newParams.delete(pageParamKey); + router.replace('?' + newParams.toString()); }; diff --git a/dashboard/src/lib/action/identity.ts b/dashboard/src/lib/action/identity.ts index 4a93084..f8ff2b0 100644 --- a/dashboard/src/lib/action/identity.ts +++ b/dashboard/src/lib/action/identity.ts @@ -21,6 +21,13 @@ interface QueryIdentitiesProps { export async function queryIdentities({ page, pageSize, query }: QueryIdentitiesProps) { + if (page < 1 || pageSize < 1) { + return { + data: [], + pageCount: 0, + }; + } + const db = await getDB(); const result = await db.select() .from(identities) @@ -31,6 +38,7 @@ export async function queryIdentities({ page, pageSize, query }: QueryIdentities ${`%${query}%`}`, ilike(identityVerifiableAddresses.value, `%${query}%`), )) + .orderBy(identities.id) .limit(pageSize) .offset((page - 1) * pageSize);