'use client'; import { useEffect, useState, useRef } from 'react'; import styles from '@/app/home/plugins/plugins.module.css'; import { MCPMarketCardVO } from '@/app/home/plugins/mcp-market/mcp-market-card/MCPMarketCardVO'; import MCPMarketCardComponent from '@/app/home/plugins/mcp-market/mcp-market-card/MCPMarketCardComponent'; import { spaceClient } from '@/app/infra/http/HttpClient'; import { useTranslation } from 'react-i18next'; import { Input } from '@/components/ui/input'; import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from '@/components/ui/pagination'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; export default function MCPMarketComponent({ askInstallServer, }: { askInstallServer: (githubURL: string) => void; }) { const { t } = useTranslation(); const [marketServerList, setMarketServerList] = useState( [], ); const [totalCount, setTotalCount] = useState(0); const [nowPage, setNowPage] = useState(1); const [searchKeyword, setSearchKeyword] = useState(''); const [loading, setLoading] = useState(false); const [sortByValue, setSortByValue] = useState('pushed_at'); const [sortOrderValue, setSortOrderValue] = useState('DESC'); const searchTimeout = useRef(null); const pageSize = 12; useEffect(() => { initData(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); function initData() { getServerList(); } function onInputSearchKeyword(keyword: string) { setSearchKeyword(keyword); // 清除之前的定时器 if (searchTimeout.current) { clearTimeout(searchTimeout.current); } // 设置新的定时器 searchTimeout.current = setTimeout(() => { setNowPage(1); getServerList(1, keyword); }, 500); } function getServerList( page: number = nowPage, keyword: string = searchKeyword, sortBy: string = sortByValue, sortOrder: string = sortOrderValue, ) { setLoading(true); spaceClient .getMCPMarketServers(page, pageSize, keyword, sortBy, sortOrder) .then((res) => { setMarketServerList( res.servers.map((marketServer) => { let repository = marketServer.repository; if (repository.startsWith('https://github.com/')) { repository = repository.replace('https://github.com/', ''); } if (repository.startsWith('github.com/')) { repository = repository.replace('github.com/', ''); } const author = repository.split('/')[0]; const name = repository.split('/')[1]; return new MCPMarketCardVO({ author: author, description: marketServer.description, githubURL: `https://github.com/${repository}`, name: name, serverId: String(marketServer.ID), starCount: marketServer.stars, version: 'version' in marketServer ? String(marketServer.version) : '1.0.0', // 如果没有提供版本,则默认为1.0.0 }); }), ); setTotalCount(res.total); setLoading(false); console.log('market servers:', res); }) .catch((error) => { console.error(t('mcp.getServerListError'), error); setLoading(false); }); } function handlePageChange(page: number) { setNowPage(page); getServerList(page); } function handleSortChange(value: string) { const [newSortBy, newSortOrder] = value.split(',').map((s) => s.trim()); setSortByValue(newSortBy); setSortOrderValue(newSortOrder); setNowPage(1); getServerList(1, searchKeyword, newSortBy, newSortOrder); } return (
onInputSearchKeyword(e.target.value)} />
{totalCount > 0 && ( handlePageChange(nowPage - 1)} className={ nowPage <= 1 ? 'pointer-events-none opacity-50' : '' } /> {/* 如果总页数大于5,则只显示5页,如果总页数小于5,则显示所有页 */} {(() => { const totalPages = Math.ceil(totalCount / pageSize); const maxVisiblePages = 5; let startPage = Math.max( 1, nowPage - Math.floor(maxVisiblePages / 2), ); const endPage = Math.min( totalPages, startPage + maxVisiblePages - 1, ); if (endPage - startPage + 1 < maxVisiblePages) { startPage = Math.max(1, endPage - maxVisiblePages + 1); } return Array.from( { length: endPage - startPage + 1 }, (_, i) => { const pageNum = startPage + i; return ( handlePageChange(pageNum)} > {pageNum} ); }, ); })()} handlePageChange(nowPage + 1)} className={ nowPage >= Math.ceil(totalCount / pageSize) ? 'pointer-events-none opacity-50' : '' } /> )}
{loading ? (
{t('mcp.loading')}
) : marketServerList.length === 0 ? (
{t('mcp.noMatchingServers')}
) : ( marketServerList.map((vo, index) => (
{ askInstallServer(githubURL); }} />
)) )}
); }