website refactor
This commit is contained in:
88
apps/website/ui/Pagination.tsx
Normal file
88
apps/website/ui/Pagination.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
|
||||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||||
import { Box } from './Box';
|
||||
import { Button } from './Button';
|
||||
import { Icon } from './Icon';
|
||||
import { Stack } from './Stack';
|
||||
import { Text } from './Text';
|
||||
|
||||
interface PaginationProps {
|
||||
currentPage: number;
|
||||
totalPages: number;
|
||||
totalItems: number;
|
||||
itemsPerPage: number;
|
||||
onPageChange: (page: number) => void;
|
||||
}
|
||||
|
||||
export function Pagination({
|
||||
currentPage,
|
||||
totalPages,
|
||||
totalItems,
|
||||
itemsPerPage,
|
||||
onPageChange,
|
||||
}: PaginationProps) {
|
||||
if (totalPages <= 1) return null;
|
||||
|
||||
const startItem = ((currentPage - 1) * itemsPerPage) + 1;
|
||||
const endItem = Math.min(currentPage * itemsPerPage, totalItems);
|
||||
|
||||
const getPageNumbers = () => {
|
||||
if (totalPages <= 5) {
|
||||
return Array.from({ length: totalPages }, (_, i) => i + 1);
|
||||
}
|
||||
|
||||
if (currentPage <= 3) {
|
||||
return [1, 2, 3, 4, 5];
|
||||
}
|
||||
|
||||
if (currentPage >= totalPages - 2) {
|
||||
return [totalPages - 4, totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
|
||||
}
|
||||
|
||||
return [currentPage - 2, currentPage - 1, currentPage, currentPage + 1, currentPage + 2];
|
||||
};
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="center" justifyContent="between" pt={4}>
|
||||
<Text size="sm" color="text-gray-500">
|
||||
Showing {startItem}–{endItem} of {totalItems}
|
||||
</Text>
|
||||
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => onPageChange(Math.max(1, currentPage - 1))}
|
||||
disabled={currentPage === 1}
|
||||
size="sm"
|
||||
icon={<Icon icon={ChevronLeft} size={5} />}
|
||||
>
|
||||
<Box as="span" className="sr-only">Previous</Box>
|
||||
</Button>
|
||||
|
||||
<Stack direction="row" align="center" gap={1}>
|
||||
{getPageNumbers().map(pageNum => (
|
||||
<Button
|
||||
key={pageNum}
|
||||
variant={currentPage === pageNum ? 'primary' : 'ghost'}
|
||||
onClick={() => onPageChange(pageNum)}
|
||||
className="w-10 h-10 p-0"
|
||||
>
|
||||
{pageNum}
|
||||
</Button>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
|
||||
disabled={currentPage === totalPages}
|
||||
size="sm"
|
||||
icon={<Icon icon={ChevronRight} size={5} />}
|
||||
>
|
||||
<Box as="span" className="sr-only">Next</Box>
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user