Workflow/frontend/src/components/Pagination.tsx
root d58d53fa3b feat: initial workflow portal - multi-tenant architecture
- Backend: Node.js + Express + TypeScript + Prisma + PostgreSQL
- Frontend: React + TypeScript + Tailwind CSS + Vite
- Multi-tenant with role-based access (SystemAdmin, Technician, Customer)
- Workflow editor with drag-and-drop steps
- JWT authentication with refresh tokens
- German UI throughout
2026-03-20 22:48:04 +00:00

63 lines
1.7 KiB
TypeScript

import { ChevronLeft, ChevronRight } from 'lucide-react';
interface PaginationProps {
page: number;
totalPages: number;
onPageChange: (page: number) => void;
}
export default function Pagination({
page,
totalPages,
onPageChange,
}: PaginationProps) {
if (totalPages <= 1) return null;
const pages: (number | '...')[] = [];
for (let i = 1; i <= totalPages; i++) {
if (i === 1 || i === totalPages || (i >= page - 1 && i <= page + 1)) {
pages.push(i);
} else if (pages[pages.length - 1] !== '...') {
pages.push('...');
}
}
return (
<nav className="flex items-center justify-center gap-1">
<button
onClick={() => onPageChange(page - 1)}
disabled={page <= 1}
className="rounded-lg p-2 text-gray-500 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-40"
>
<ChevronLeft size={18} />
</button>
{pages.map((p, idx) =>
p === '...' ? (
<span key={`dots-${idx}`} className="px-2 text-gray-400">
...
</span>
) : (
<button
key={p}
onClick={() => onPageChange(p)}
className={`min-w-[36px] rounded-lg px-3 py-1.5 text-sm font-medium ${
p === page
? 'bg-primary-600 text-white'
: 'text-gray-600 hover:bg-gray-100'
}`}
>
{p}
</button>
)
)}
<button
onClick={() => onPageChange(page + 1)}
disabled={page >= totalPages}
className="rounded-lg p-2 text-gray-500 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-40"
>
<ChevronRight size={18} />
</button>
</nav>
);
}