import { useState, useEffect } from 'react';
import { useQuery } from '@tanstack/react-query';
import { fetchRepositories } from '@/services/repositoryService';
import type { PaginatedRepositories } from '@/services/repositoryService';
import { useDebounce } from '@/hooks/useDebounce';
import { Input } from '@/components/ui/input';
import { Search } from 'lucide-react';
import { Skeleton } from "@/components/ui/skeleton";
import { columns } from "./RepositoryTableColumns";
import { DataTable } from "./DataTable";
import { Pagination, PaginationContent, PaginationItem, PaginationPrevious, PaginationNext } from "@/components/ui/pagination";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
function DataTableSkeleton() {
return (
{Array.from({ length: 10 }).map((_, i) => (
))}
);
}
export function RepositoryManager() {
const [searchTerm, setSearchTerm] = useState('');
const [page, setPage] = useState(1);
const debouncedSearchTerm = useDebounce(searchTerm, 500);
const { data, isLoading, isError, error } = useQuery({
queryKey: ['repositories', page, debouncedSearchTerm],
queryFn: () => fetchRepositories(page, debouncedSearchTerm),
});
// 当搜索词变化时,重置到第一页
useEffect(() => {
if (debouncedSearchTerm) {
setPage(1);
}
}, [debouncedSearchTerm]);
const repos = data?.data || [];
const totalCount = data?.totalCount || 0;
const limit = data?.limit || 30;
const totalPages = Math.ceil(totalCount / limit);
return (
{isLoading ? (
) : isError ? (
System Error_
加载仓库列表失败: {error.message}
) : (
<>
{totalPages > 1 && (
第 {page} 页 / 共 {totalPages} 页 | 共 {totalCount} 个仓库
{
e.preventDefault();
setPage(p => Math.max(1, p - 1));
}}
className={`border border-border/50 hover:bg-accent hover:text-foreground hover:border-border/80 font-mono text-xs transition-colors ${page <= 1 ? "pointer-events-none opacity-30 bg-muted/40" : "bg-muted/70 text-muted-foreground"}`}
/>
{
e.preventDefault();
setPage(p => Math.min(totalPages, p + 1));
}}
className={`border border-border/50 hover:bg-accent hover:text-foreground hover:border-border/80 font-mono text-xs transition-colors ${page >= totalPages ? "pointer-events-none opacity-30 bg-muted/40" : "bg-muted/70 text-muted-foreground"}`}
/>
)}
>
)}
);
}