import { useState, useEffect, useCallback } from 'react' import { useTranslation } from 'react-i18next' import Button from './Button' import Input from './Input' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './Select' import { cn } from '@/lib/utils' import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-react' export type PaginationControlsProps = { currentPage: number totalPages: number pageSize: number totalCount: number onPageChange: (page: number) => void onPageSizeChange: (pageSize: number) => void isLoading?: boolean compact?: boolean className?: string } const PAGE_SIZE_OPTIONS = [ { value: 10, label: '10' }, { value: 20, label: '20' }, { value: 50, label: '50' }, { value: 100, label: '100' }, { value: 200, label: '200' } ] export default function PaginationControls({ currentPage, totalPages, pageSize, totalCount, onPageChange, onPageSizeChange, isLoading = false, compact = false, className }: PaginationControlsProps) { const { t } = useTranslation() const [inputPage, setInputPage] = useState(currentPage.toString()) // Update input when currentPage changes useEffect(() => { setInputPage(currentPage.toString()) }, [currentPage]) // Handle page input change with debouncing const handlePageInputChange = useCallback((value: string) => { setInputPage(value) }, []) // Handle page input submit const handlePageInputSubmit = useCallback(() => { const pageNum = parseInt(inputPage, 10) if (!isNaN(pageNum) && pageNum >= 1 && pageNum <= totalPages) { onPageChange(pageNum) } else { // Reset to current page if invalid setInputPage(currentPage.toString()) } }, [inputPage, totalPages, onPageChange, currentPage]) // Handle page input key press const handlePageInputKeyPress = useCallback((e: React.KeyboardEvent) => { if (e.key === 'Enter') { handlePageInputSubmit() } }, [handlePageInputSubmit]) // Handle page size change const handlePageSizeChange = useCallback((value: string) => { const newPageSize = parseInt(value, 10) if (!isNaN(newPageSize)) { onPageSizeChange(newPageSize) } }, [onPageSizeChange]) // Navigation handlers const goToFirstPage = useCallback(() => { if (currentPage > 1 && !isLoading) { onPageChange(1) } }, [currentPage, onPageChange, isLoading]) const goToPrevPage = useCallback(() => { if (currentPage > 1 && !isLoading) { onPageChange(currentPage - 1) } }, [currentPage, onPageChange, isLoading]) const goToNextPage = useCallback(() => { if (currentPage < totalPages && !isLoading) { onPageChange(currentPage + 1) } }, [currentPage, totalPages, onPageChange, isLoading]) const goToLastPage = useCallback(() => { if (currentPage < totalPages && !isLoading) { onPageChange(totalPages) } }, [currentPage, totalPages, onPageChange, isLoading]) if (totalPages <= 1) { return null } if (compact) { return (
handlePageInputChange(e.target.value)} onBlur={handlePageInputSubmit} onKeyPress={handlePageInputKeyPress} disabled={isLoading} className="h-8 w-12 text-center text-sm" /> / {totalPages}
) } return (
{t('pagination.showing', { start: Math.min((currentPage - 1) * pageSize + 1, totalCount), end: Math.min(currentPage * pageSize, totalCount), total: totalCount })}
{t('pagination.page')} handlePageInputChange(e.target.value)} onBlur={handlePageInputSubmit} onKeyPress={handlePageInputKeyPress} disabled={isLoading} className="h-8 w-16 text-center text-sm" /> / {totalPages}
{t('pagination.pageSize')}
) }