diff --git a/frontend/components/AgentListView.tsx b/frontend/components/AgentListView.tsx index fc9cb59..96ff09c 100644 --- a/frontend/components/AgentListView.tsx +++ b/frontend/components/AgentListView.tsx @@ -1,99 +1,113 @@ -'use client' -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' -import { AgentsList, TabType } from './AgentsList' -import { useMemo, useState } from 'react' -import { AgentDetails, useAgents } from '@/hooks/useAgents' -import { ChevronLeft, ChevronRight, Search } from 'lucide-react' -import { DOTS, usePagination } from '@/hooks/usePagination' -import { useAttackers } from '@/hooks/useAttackers' -import { AttackersList } from './AttackersList' - -const PAGE_SIZE = 10 -const SIBLING_COUNT = 1 +'use client'; +import { Suspense } from 'react'; +import { useSearchParams, useRouter } from 'next/navigation'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; +import { AgentsList, TabType } from './AgentsList'; +import { useMemo, useState } from 'react'; +import { AgentDetails, useAgents } from '@/hooks/useAgents'; +import { ChevronLeft, ChevronRight, Search } from 'lucide-react'; +import { usePagination } from '@/hooks/usePagination'; +import { useAttackers } from '@/hooks/useAttackers'; +import { AttackersList } from './AttackersList'; + +const PAGE_SIZE = 10; +const SIBLING_COUNT = 1; type AgentListViewProps = { - heading: string - subheading: string -} + heading: string; + subheading: string; +}; export const AgentListView = ({ heading, subheading }: AgentListViewProps) => { - const [searchQuery, setSearchQuery] = useState('') - const [currentPage, setCurrentPage] = useState(0) - const [selectedTab, setSelectedTab] = useState(TabType.ActiveAgents) - //TODO: show toast for failed to load agents + return ( + Loading...}> + + + ); +}; + +const AgentListViewInner = ({ heading, subheading }: AgentListViewProps) => { + const searchParams = useSearchParams(); + const router = useRouter(); + + // Get tab from URL, default to ActiveAgents + const selectedTab = (searchParams.get('tab') as TabType) || TabType.ActiveAgents; + const [searchQuery, setSearchQuery] = useState(''); + const [currentPage, setCurrentPage] = useState(0); + const { agents: allAgents, loading: isFetchingAllAgents, totalAgents: totalAllAgents, - } = useAgents({ page: currentPage, pageSize: PAGE_SIZE, active: null }) + } = useAgents({ page: currentPage, pageSize: PAGE_SIZE, active: null }); const { agents: activeAgents, loading: isFetchingActiveAgents, totalAgents: totalActiveAgents, - } = useAgents({ page: currentPage, pageSize: PAGE_SIZE, active: true }) + } = useAgents({ page: currentPage, pageSize: PAGE_SIZE, active: true }); const { attackers = [], loading: isFetchingAttackers, totalAttackers, - } = useAttackers({ page: currentPage, pageSize: PAGE_SIZE }) + } = useAttackers({ page: currentPage, pageSize: PAGE_SIZE }); - let totalTabEntries = 0 + let totalTabEntries = 0; if (selectedTab === TabType.TopAttackers) { - totalTabEntries = totalAttackers + totalTabEntries = totalAttackers; } else if (selectedTab === TabType.ActiveAgents) { - totalTabEntries = totalActiveAgents + totalTabEntries = totalActiveAgents; } else { - totalTabEntries = totalAllAgents + totalTabEntries = totalAllAgents; } - const totalPages = Math.ceil(totalTabEntries / PAGE_SIZE) + + const totalPages = Math.ceil(totalTabEntries / PAGE_SIZE); const paginationRange = usePagination({ currentPage, totalCount: totalTabEntries, pageSize: PAGE_SIZE, siblingCount: SIBLING_COUNT, - }) + }); const filterAgents = (agents: AgentDetails[], query: string) => { - if (!query.trim()) return agents - - const lowercaseQuery = query.toLowerCase().trim() + if (!query.trim()) return agents; return agents.filter( (agent) => - agent.name.toLowerCase().includes(lowercaseQuery) || - agent.address.toLowerCase().includes(lowercaseQuery) - ) - } + agent.name.toLowerCase().includes(query.toLowerCase()) || + agent.address.toLowerCase().includes(query.toLowerCase()) + ); + }; + const filteredAgents = useMemo( () => filterAgents(allAgents, searchQuery), [allAgents, searchQuery] - ) + ); const filteredActiveAgents = useMemo( () => filterAgents(activeAgents, searchQuery), [activeAgents, searchQuery] - ) + ); + + const handleTabChange = (tab: string) => { + router.push(`?tab=${tab}`, { scroll: false }); + setCurrentPage(0); + if (tab === TabType.TopAttackers) { + setSearchQuery(''); + } + }; const handlePreviousPage = () => { if (currentPage > 0) { - setCurrentPage(currentPage - 1) + setCurrentPage(currentPage - 1); } - } + }; const handleNextPage = () => { if (currentPage < totalPages - 1) { - setCurrentPage(currentPage + 1) - } - } - - const handleTabChange = (tab: string) => { - setSelectedTab(tab as TabType) - setCurrentPage(0) - if (tab === TabType.TopAttackers) { - setSearchQuery('') + setCurrentPage(currentPage + 1); } - } + }; return (
@@ -101,19 +115,15 @@ export const AgentListView = ({ heading, subheading }: AgentListViewProps) => {

{heading}

-

{subheading}

+
- +
Agents ranking @@ -130,79 +140,39 @@ export const AgentListView = ({ heading, subheading }: AgentListViewProps) => { placeholder="Search by agent" className="placeholder:text-[#6F6F6F] border border-[#6F6F6F] rounded-[28px] bg-transparent px-5 py-1 min-h-[2rem] text-sm outline-none focus:border-white w-full md:w-auto" /> - +
)}
- + - + - + + + {/* Pagination */}
- - {paginationRange.map((pageNumber, index) => { - if (pageNumber === DOTS) { - return ( - - ... - - ) - } - return ( - - ) - })} - + ))} + +
- ) -} + ); +};