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);