{/* Pagination controls */}
{!loading && !error && totalPages > 1 && locations.length > 0 && (
<div className="flex justify-center items-center mt-6">
<nav className="flex items-center gap-1" aria-label="Pagination">
{/* First page button */}
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-md"
onClick={() => handlePageChange(1)}
disabled={currentPage === 1}
aria-label="First page"
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<polyline points="11 17 6 12 11 7"></polyline>
<polyline points="18 17 13 12 18 7"></polyline>
</svg>
</Button>
{/* Previous page button */}
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-md"
onClick={() => handlePageChange(currentPage - 1)}
disabled={currentPage === 1}
aria-label="Previous page"
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<polyline points="15 18 9 12 15 6"></polyline>
</svg>
</Button>
{/* Page number buttons */}
{(() => {
const totalPagesCount = totalPages;
const current = currentPage;
const pages = [];
// Always show first page
if (current > 3) {
pages.push(
<Button
key="page-1"
variant={current === 1 ? "default" : "outline"}
size="icon"
className="h-8 w-8 rounded-md"
onClick={() => handlePageChange(1)}
>
1
</Button>
);
// Add ellipsis if not showing page 2
if (current > 4) {
pages.push(
<span key="ellipsis1" className="px-1">…</span>
);
}
}
// Show current page and surrounding pages
const startPage = Math.max(1, current - 1);
const endPage = Math.min(totalPagesCount, current + 1);
for (let i = startPage; i <= endPage; i++) {
if (i === 1 || i === totalPagesCount) continue; // Skip first and last pages as they're handled separately
pages.push(
<Button
key={`page-${i}`}
variant={current === i ? "default" : "outline"}
size="icon"
className="h-8 w-8 rounded-md"
onClick={() => handlePageChange(i)}
>
{i}
</Button>
);
}
// Add ellipsis if needed
if (current < totalPagesCount - 3) {
pages.push(
<span key="ellipsis2" className="px-1">…</span>
);
}
// Always show last page
if (totalPagesCount > 1) {
pages.push(
<Button
key={`page-${totalPagesCount}`}
variant={current === totalPagesCount ? "default" : "outline"}
size="icon"
className="h-8 w-8 rounded-md"
onClick={() => handlePageChange(totalPagesCount)}
>
{totalPagesCount}
</Button>
);
}
return pages;
})()}
{/* Next page button */}
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-md"
onClick={() => handlePageChange(currentPage + 1)}
disabled={currentPage === totalPages}
aria-label="Next page"
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</Button>
{/* Last page button */}
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-md"
onClick={() => handlePageChange(totalPages)}
disabled={currentPage === totalPages}
aria-label="Last page"
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<polyline points="13 17 18 12 13 7"></polyline>
<polyline points="6 17 11 12 6 7"></polyline>
</svg>
</Button>
</nav>
</div>
)}