From 5a9ca2bbf94e5deab689e75c50a78d60d50ebcff Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 7 Nov 2025 19:52:34 +0000 Subject: [PATCH] Add pagination to agents screen Implement pagination controls on the agents screen to manage a large number of agents. This includes state management for current page and items per page, logic to slice and display agents, and UI elements for navigation (previous, next, page numbers, ellipsis). The search functionality now resets to the first page. --- src/pages/Agents.tsx | 104 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 8 deletions(-) diff --git a/src/pages/Agents.tsx b/src/pages/Agents.tsx index c5c3095..65797eb 100644 --- a/src/pages/Agents.tsx +++ b/src/pages/Agents.tsx @@ -5,12 +5,23 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Pagination, + PaginationContent, + PaginationEllipsis, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, +} from "@/components/ui/pagination"; import { Plus, Search, Bot, ChevronRight } from "lucide-react"; export default function Agents() { const navigate = useNavigate(); const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(""); + const [currentPage, setCurrentPage] = useState(1); + const itemsPerPage = 9; const [agents] = useState([ { @@ -43,6 +54,18 @@ export default function Agents() { agent.name.toLowerCase().includes(searchQuery.toLowerCase()) ); + // Paginação + const totalPages = Math.ceil(filteredAgents.length / itemsPerPage); + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + const paginatedAgents = filteredAgents.slice(startIndex, endIndex); + + // Reset para primeira página quando buscar + const handleSearch = (query: string) => { + setSearchQuery(query); + setCurrentPage(1); + }; + return (
@@ -64,13 +87,20 @@ export default function Agents() { setSearchQuery(e.target.value)} + onChange={(e) => handleSearch(e.target.value)} className="pl-10" />
-

- {filteredAgents.length} {filteredAgents.length === 1 ? 'agente encontrado' : 'agentes encontrados'} -

+
+

+ {filteredAgents.length} {filteredAgents.length === 1 ? 'agente encontrado' : 'agentes encontrados'} +

+ {totalPages > 1 && ( +

+ Página {currentPage} de {totalPages} +

+ )} +
{filteredAgents.length === 0 ? ( @@ -78,8 +108,9 @@ export default function Agents() {

Nenhum agente encontrado.

) : ( -
- {filteredAgents.map((agent) => ( + <> +
+ {paginatedAgents.map((agent) => ( - ))} -
+ ))} +
+ + {totalPages > 1 && ( +
+ + + + setCurrentPage(prev => Math.max(1, prev - 1))} + className={currentPage === 1 ? "pointer-events-none opacity-50" : "cursor-pointer"} + /> + + + {[...Array(totalPages)].map((_, index) => { + const pageNumber = index + 1; + + // Mostrar primeira página, última página e páginas próximas à atual + if ( + pageNumber === 1 || + pageNumber === totalPages || + (pageNumber >= currentPage - 1 && pageNumber <= currentPage + 1) + ) { + return ( + + setCurrentPage(pageNumber)} + isActive={currentPage === pageNumber} + className="cursor-pointer" + > + {pageNumber} + + + ); + } + + // Mostrar ellipsis + if (pageNumber === currentPage - 2 || pageNumber === currentPage + 2) { + return ( + + + + ); + } + + return null; + })} + + + setCurrentPage(prev => Math.min(totalPages, prev + 1))} + className={currentPage === totalPages ? "pointer-events-none opacity-50" : "cursor-pointer"} + /> + + + +
+ )} + )}