website refactor

This commit is contained in:
2026-01-18 21:31:08 +01:00
parent 502d4aa092
commit b43a23a48c
96 changed files with 3461 additions and 4067 deletions

View File

@@ -1,88 +1,77 @@
import { ChevronLeft, ChevronRight } from 'lucide-react';
import React from 'react';
import { Box } from './primitives/Box';
import { Button } from './Button';
import { Icon } from './Icon';
import { Stack } from './primitives/Stack';
import { Text } from './Text';
import { ChevronLeft, ChevronRight } from 'lucide-react';
interface PaginationProps {
export 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];
};
export const Pagination = ({
currentPage,
totalPages,
onPageChange
}: PaginationProps) => {
const pages = Array.from({ length: totalPages }, (_, i) => i + 1);
const visiblePages = pages.filter(page => {
if (totalPages <= 7) return true;
if (page === 1 || page === totalPages) return true;
if (page >= currentPage - 1 && page <= currentPage + 1) return true;
return false;
});
return (
<Box display="flex" alignItems="center" justifyContent="between" pt={4}>
<Text size="sm" color="text-gray-500">
Showing {startItem}{endItem} of {totalItems}
<Box display="flex" alignItems="center" justifyContent="between" paddingTop={4}>
<Text size="sm" variant="low">
Page {currentPage} of {totalPages}
</Text>
<Stack direction="row" align="center" gap={2}>
<Box display="flex" alignItems="center" gap={2}>
<Button
variant="secondary"
onClick={() => onPageChange(Math.max(1, currentPage - 1))}
disabled={currentPage === 1}
variant="ghost"
size="sm"
icon={<Icon icon={ChevronLeft} size={5} />}
disabled={currentPage === 1}
onClick={() => onPageChange(currentPage - 1)}
icon={<ChevronLeft size={16} />}
>
<Box as="span" className="sr-only">Previous</Box>
Previous
</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>
<Box display="flex" alignItems="center" gap={1}>
{visiblePages.map((page, index) => {
const prevPage = visiblePages[index - 1];
const showEllipsis = prevPage && page - prevPage > 1;
return (
<React.Fragment key={page}>
{showEllipsis && <Text variant="low">...</Text>}
<Button
variant={page === currentPage ? 'primary' : 'ghost'}
size="sm"
onClick={() => onPageChange(page)}
style={{ minWidth: '2.5rem', padding: 0 }}
>
{page}
</Button>
</React.Fragment>
);
})}
</Box>
<Button
variant="secondary"
onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
disabled={currentPage === totalPages}
variant="ghost"
size="sm"
icon={<Icon icon={ChevronRight} size={5} />}
disabled={currentPage === totalPages}
onClick={() => onPageChange(currentPage + 1)}
icon={<ChevronRight size={16} />}
>
<Box as="span" className="sr-only">Next</Box>
Next
</Button>
</Stack>
</Box>
</Box>
);
}
};