mirror of
https://codeberg.org/MarkusThielker/next-ory.git
synced 2025-04-10 11:58:41 +00:00
NORY-41: add new pagination
This commit is contained in:
parent
2d2c021446
commit
9defc8a391
4 changed files with 122 additions and 2 deletions
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||||
import { IdentityDataTable } from '@/app/(inside)/user/data-table';
|
import { IdentityDataTable } from '@/app/(inside)/user/data-table';
|
||||||
import { SearchInput } from '@/components/search-input';
|
import { SearchInput } from '@/components/search-input';
|
||||||
import { queryIdentities } from '@/lib/action/identity';
|
import { queryIdentities } from '@/lib/action/identity';
|
||||||
|
import { IdentityPagination } from '@/components/pagination';
|
||||||
|
|
||||||
export default async function UserPage(
|
export default async function UserPage(
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,7 @@ export default async function UserPage(
|
||||||
const query = params.query ? params.query as string : '';
|
const query = params.query ? params.query as string : '';
|
||||||
|
|
||||||
let pageSize = 50;
|
let pageSize = 50;
|
||||||
|
let paginationRange = 11;
|
||||||
|
|
||||||
const { data, pageCount } = await queryIdentities({ page, pageSize, query });
|
const { data, pageCount } = await queryIdentities({ page, pageSize, query });
|
||||||
|
|
||||||
|
@ -31,12 +33,18 @@ export default async function UserPage(
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<SearchInput
|
<SearchInput
|
||||||
value={query}
|
value={query}
|
||||||
|
pageParamKey="page"
|
||||||
queryParamKey="query"
|
queryParamKey="query"
|
||||||
placeholder="Search for identifiers (Email, Username...)"/>
|
placeholder="Search for addresses and traits"/>
|
||||||
<IdentityDataTable
|
<IdentityDataTable
|
||||||
data={data}
|
data={data}
|
||||||
page={page}
|
page={page}
|
||||||
query={query}/>
|
query={query}/>
|
||||||
|
<IdentityPagination
|
||||||
|
page={page}
|
||||||
|
pageCount={pageCount}
|
||||||
|
pageParamKey="page"
|
||||||
|
paginationRange={paginationRange}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
101
dashboard/src/components/pagination.tsx
Normal file
101
dashboard/src/components/pagination.tsx
Normal file
|
@ -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 (
|
||||||
|
<Pagination>
|
||||||
|
<PaginationContent>
|
||||||
|
{
|
||||||
|
page > 1 && (
|
||||||
|
<PaginationItem key={'previous'}>
|
||||||
|
<PaginationPrevious
|
||||||
|
|
||||||
|
href={updatePage(page - 1)}/>
|
||||||
|
</PaginationItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
page - (paginationRange / 2) > 1 &&
|
||||||
|
<PaginationItem key={'ellipsis-previous'}>
|
||||||
|
<PaginationEllipsis/>
|
||||||
|
</PaginationItem>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Array.from({ length: paginationRange }, (_, i) => {
|
||||||
|
|
||||||
|
const difference = (i + 1) - Math.round(paginationRange / 2);
|
||||||
|
const nextPage = page + difference;
|
||||||
|
|
||||||
|
if (nextPage < 1 || nextPage > pageCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PaginationItem key={nextPage}>
|
||||||
|
<PaginationLink
|
||||||
|
href={updatePage(nextPage)}
|
||||||
|
isActive={page === nextPage}
|
||||||
|
>
|
||||||
|
{nextPage}
|
||||||
|
</PaginationLink>
|
||||||
|
</PaginationItem>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
{
|
||||||
|
page + (paginationRange / 2) < pageCount &&
|
||||||
|
<PaginationItem key={'ellipsis-next'}>
|
||||||
|
<PaginationEllipsis/>
|
||||||
|
</PaginationItem>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
page < pageCount && (
|
||||||
|
<PaginationItem key={'next'}>
|
||||||
|
<PaginationNext href={updatePage(page + 1)}/>
|
||||||
|
</PaginationItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</PaginationContent>
|
||||||
|
</Pagination>
|
||||||
|
);
|
||||||
|
}
|
|
@ -7,12 +7,13 @@ import { ChangeEvent, HTMLInputTypeAttribute } from 'react';
|
||||||
interface SearchInputProps {
|
interface SearchInputProps {
|
||||||
value: string;
|
value: string;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
|
pageParamKey: string;
|
||||||
queryParamKey: string;
|
queryParamKey: string;
|
||||||
type?: HTMLInputTypeAttribute;
|
type?: HTMLInputTypeAttribute;
|
||||||
className?: string;
|
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 router = useRouter();
|
||||||
const params = useSearchParams();
|
const params = useSearchParams();
|
||||||
|
@ -28,6 +29,8 @@ export function SearchInput({ value, placeholder, queryParamKey, type, className
|
||||||
newParams.set(queryParamKey, value);
|
newParams.set(queryParamKey, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newParams.delete(pageParamKey);
|
||||||
|
|
||||||
router.replace('?' + newParams.toString());
|
router.replace('?' + newParams.toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,13 @@ interface QueryIdentitiesProps {
|
||||||
|
|
||||||
export async function queryIdentities({ page, pageSize, query }: QueryIdentitiesProps) {
|
export async function queryIdentities({ page, pageSize, query }: QueryIdentitiesProps) {
|
||||||
|
|
||||||
|
if (page < 1 || pageSize < 1) {
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
pageCount: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const db = await getDB();
|
const db = await getDB();
|
||||||
const result = await db.select()
|
const result = await db.select()
|
||||||
.from(identities)
|
.from(identities)
|
||||||
|
@ -31,6 +38,7 @@ export async function queryIdentities({ page, pageSize, query }: QueryIdentities
|
||||||
${`%${query}%`}`,
|
${`%${query}%`}`,
|
||||||
ilike(identityVerifiableAddresses.value, `%${query}%`),
|
ilike(identityVerifiableAddresses.value, `%${query}%`),
|
||||||
))
|
))
|
||||||
|
.orderBy(identities.id)
|
||||||
.limit(pageSize)
|
.limit(pageSize)
|
||||||
.offset((page - 1) * pageSize);
|
.offset((page - 1) * pageSize);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue