import { useQuery } from "@tanstack/react-query"; import { Database, Plus, RotateCcw } from "lucide-react"; import { useState } from "react"; import { useNavigate } from "react-router"; import { listRepositories } from "~/client/api-client/sdk.gen"; import { listRepositoriesOptions } from "~/client/api-client/@tanstack/react-query.gen"; import { RepositoryIcon } from "~/client/components/repository-icon"; import { Button } from "~/client/components/ui/button"; import { Card } from "~/client/components/ui/card"; import { Input } from "~/client/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/client/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~/client/components/ui/table"; import type { Route } from "./+types/repositories"; import { cn } from "~/client/lib/utils"; import { EmptyState } from "~/client/components/empty-state"; export const handle = { breadcrumb: () => [{ label: "Repositories" }], }; export function meta(_: Route.MetaArgs) { return [ { title: "Zerobyte - Repositories" }, { name: "description", content: "Manage your backup repositories with encryption and compression.", }, ]; } export const clientLoader = async () => { const repositories = await listRepositories(); if (repositories.data) return repositories.data; return []; }; export default function Repositories({ loaderData }: Route.ComponentProps) { const [searchQuery, setSearchQuery] = useState(""); const [statusFilter, setStatusFilter] = useState(""); const [backendFilter, setBackendFilter] = useState(""); const clearFilters = () => { setSearchQuery(""); setStatusFilter(""); setBackendFilter(""); }; const navigate = useNavigate(); const { data } = useQuery({ ...listRepositoriesOptions(), initialData: loaderData, refetchInterval: 10000, refetchOnWindowFocus: true, }); const filteredRepositories = data?.filter((repository) => { const matchesSearch = repository.name.toLowerCase().includes(searchQuery.toLowerCase()); const matchesStatus = !statusFilter || repository.status === statusFilter; const matchesBackend = !backendFilter || repository.type === backendFilter; return matchesSearch && matchesStatus && matchesBackend; }) || []; const hasNoRepositories = data?.length === 0; const hasNoFilteredRepositories = filteredRepositories.length === 0 && !hasNoRepositories; if (hasNoRepositories) { return ( navigate("/repositories/create")}> Create Repository } /> ); } return (
setSearchQuery(e.target.value)} /> {(searchQuery || statusFilter || backendFilter) && ( )}
Name Backend Compression Status {hasNoFilteredRepositories ? (

No repositories match your filters.

) : ( filteredRepositories.map((repository) => ( navigate(`/repositories/${repository.name}`)} > {repository.name} {repository.type} {repository.compressionMode || "off"} {repository.status || "unknown"} )) )}
{hasNoFilteredRepositories ? ( "No repositories match filters." ) : ( {filteredRepositories.length} repositor {filteredRepositories.length === 1 ? "y" : "ies"} )}
); }