Extract nav tabs, detail modal, table row, stats grid, search/filter, records table, pagination, and data-loading hook into _components/ and _hooks/. page.tsx reduced from 833 to 114 LOC. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
'use client'
|
||
|
||
import { PAGE_SIZE } from '../_types'
|
||
|
||
interface PaginationProps {
|
||
currentPage: number
|
||
totalRecords: number
|
||
onPageChange: (page: number) => void
|
||
}
|
||
|
||
export function Pagination({ currentPage, totalRecords, onPageChange }: PaginationProps) {
|
||
const totalPages = Math.ceil(totalRecords / PAGE_SIZE)
|
||
|
||
return (
|
||
<div className="flex items-center justify-between">
|
||
<p className="text-sm text-gray-500">
|
||
Zeige {totalRecords === 0 ? 0 : (currentPage - 1) * PAGE_SIZE + 1}–
|
||
{Math.min(currentPage * PAGE_SIZE, totalRecords)} von {totalRecords} Einträgen
|
||
</p>
|
||
<div className="flex items-center gap-2">
|
||
<button
|
||
onClick={() => onPageChange(Math.max(1, currentPage - 1))}
|
||
disabled={currentPage === 1}
|
||
className="px-3 py-1 text-sm text-gray-600 bg-gray-100 rounded-lg hover:bg-gray-200 disabled:opacity-50"
|
||
>
|
||
Zurück
|
||
</button>
|
||
{Array.from({ length: Math.min(totalPages, 5) }, (_, i) => {
|
||
const page = Math.max(1, Math.min(currentPage - 2, totalPages - 4)) + i
|
||
if (page < 1 || page > totalPages) return null
|
||
return (
|
||
<button
|
||
key={page}
|
||
onClick={() => onPageChange(page)}
|
||
className={`px-3 py-1 text-sm rounded-lg ${
|
||
page === currentPage
|
||
? 'text-white bg-purple-600'
|
||
: 'text-gray-600 bg-gray-100 hover:bg-gray-200'
|
||
}`}
|
||
>
|
||
{page}
|
||
</button>
|
||
)
|
||
})}
|
||
<button
|
||
onClick={() => onPageChange(Math.min(totalPages || 1, currentPage + 1))}
|
||
disabled={currentPage >= (totalPages || 1)}
|
||
className="px-3 py-1 text-sm text-gray-600 bg-gray-100 rounded-lg hover:bg-gray-200 disabled:opacity-50"
|
||
>
|
||
Weiter
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|