axonhub / frontend /src /components /server-side-pagination.tsx
llzai's picture
Upload 1793 files
9853396 verified
'use client';
import { ChevronLeftIcon, ChevronRightIcon, DoubleArrowLeftIcon } from '@radix-ui/react-icons';
import type { PageInfo } from '@/gql/pagination';
import { useTranslation } from 'react-i18next';
import { usePaginationSearch } from '@/hooks/use-pagination-search';
import { Button } from '@/components/ui/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
interface ServerSidePaginationProps {
pageInfo?: PageInfo;
pageSize: number;
dataLength: number;
totalCount?: number;
selectedRows: number;
onNextPage: () => void;
onPreviousPage: () => void;
onFirstPage?: () => void;
onPageSizeChange: (pageSize: number) => void;
onResetCursor?: () => void;
}
export function ServerSidePagination({
pageInfo,
pageSize,
dataLength,
totalCount,
selectedRows,
onNextPage,
onPreviousPage,
onFirstPage,
onPageSizeChange,
onResetCursor,
}: ServerSidePaginationProps) {
const { t } = useTranslation();
const { resetCursor } = usePaginationSearch({
defaultPageSize: 20,
});
return (
<div className='flex items-center justify-between overflow-clip px-2' style={{ overflowClipMargin: 1 }}>
<div className='text-muted-foreground hidden flex-1 text-sm sm:block'>
{totalCount !== undefined
? t('pagination.selectedInfoWithTotal', { selectedRows, dataLength, totalCount })
: t('pagination.selectedInfo', { selectedRows, dataLength })}
</div>
<div className='flex items-center sm:space-x-6 lg:space-x-8'>
<div className='flex items-center space-x-2'>
<p className='hidden text-sm font-medium sm:block'>{t('pagination.rowsPerPage')}</p>
<Select
value={`${pageSize}`}
onValueChange={(value) => {
onPageSizeChange(Number(value));
}}
>
<SelectTrigger className='h-8 w-[70px]'>
<SelectValue placeholder={pageSize} />
</SelectTrigger>
<SelectContent side='top'>
{[10, 20, 30, 40, 50].map((size) => (
<SelectItem key={size} value={`${size}`}>
{size}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className='flex items-center justify-center text-sm font-medium'>
<div className='flex items-center space-x-1'>
<span className='text-muted-foreground'>
{pageInfo?.hasPreviousPage ? t('pagination.hasPrevious') : t('pagination.firstPage')}
</span>
<span className='text-muted-foreground'>|</span>
<span className='text-muted-foreground'>{pageInfo?.hasNextPage ? t('pagination.hasNext') : t('pagination.lastPage')}</span>
</div>
</div>
<div className='flex items-center space-x-2'>
<Button
variant='outline'
className='hidden h-8 w-8 p-0 lg:flex'
onClick={onFirstPage || onResetCursor || resetCursor}
disabled={!pageInfo?.hasPreviousPage}
>
<span className='sr-only'>{t('pagination.firstPage')}</span>
<DoubleArrowLeftIcon className='h-4 w-4' />
</Button>
<Button variant='outline' className='h-8 w-8 p-0' onClick={onPreviousPage} disabled={!pageInfo?.hasPreviousPage}>
<span className='sr-only'>{t('pagination.previousPage')}</span>
<ChevronLeftIcon className='h-4 w-4' />
</Button>
<Button variant='outline' className='h-8 w-8 p-0' onClick={onNextPage} disabled={!pageInfo?.hasNextPage}>
<span className='sr-only'>{t('pagination.nextPage')}</span>
<ChevronRightIcon className='h-4 w-4' />
</Button>
{/* NOT SUPPORTED */}
{/* <Button
variant='outline'
className='hidden h-8 w-8 p-0 lg:flex'
onClick={onNextPage}
disabled={!pageInfo?.hasNextPage}
>
<span className='sr-only'>{t('pagination.lastPage')}</span>
<DoubleArrowRightIcon className='h-4 w-4' />
</Button> */}
</div>
</div>
</div>
);
}