1// Repository picker page (/). Auto-redirects when there is exactly one repo.
2// Shows a list when multiple repos are registered.
3
4import { GitFork, FolderOpen, AlertCircle } from "lucide-react";
5import { useEffect } from "react";
6import { Link, useNavigate } from "react-router-dom";
7
8import { useRepositoriesQuery } from "@/__generated__/graphql";
9import { Skeleton } from "@/components/ui/skeleton";
10
11function repoSlug(name: string | null | undefined): string {
12 return name ?? "_";
13}
14
15function repoLabel(name: string | null | undefined): string {
16 return name ?? "default";
17}
18
19export function RepoPickerPage() {
20 const { data, loading, error } = useRepositoriesQuery();
21 const navigate = useNavigate();
22
23 // Auto-redirect when there is exactly one repo — no need to pick.
24 useEffect(() => {
25 if (data?.repositories.nodes.length === 1) {
26 navigate("/" + repoSlug(data.repositories.nodes[0].name), { replace: true });
27 }
28 }, [data, navigate]);
29
30 return (
31 <div className="mx-auto max-w-lg py-12">
32 <div className="mb-8 flex items-center gap-3">
33 <GitFork className="size-6 text-muted-foreground" />
34 <h1 className="text-xl font-semibold">Repositories</h1>
35 </div>
36
37 {error && (
38 <div className="flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive">
39 <AlertCircle className="size-4 shrink-0" />
40 Failed to load repositories: {error.message}
41 </div>
42 )}
43
44 {loading && !data && (
45 <div className="space-y-2">
46 {Array.from({ length: 3 }).map((_, i) => (
47 <Skeleton key={i} className="h-16 w-full rounded-md" />
48 ))}
49 </div>
50 )}
51
52 <div className="divide-y divide-border rounded-md border border-border">
53 {data?.repositories.nodes.map((repo) => (
54 <Link
55 key={repoSlug(repo.name)}
56 to={`/${repoSlug(repo.name)}`}
57 className="flex items-center gap-3 px-4 py-4 transition-colors hover:bg-muted/50"
58 >
59 <FolderOpen className="size-5 shrink-0 text-muted-foreground" />
60 <p className="font-medium text-foreground">{repoLabel(repo.name)}</p>
61 </Link>
62 ))}
63
64 {data?.repositories.totalCount === 0 && (
65 <p className="px-4 py-8 text-center text-sm text-muted-foreground">
66 No repositories found.
67 </p>
68 )}
69 </div>
70 </div>
71 );
72}