RepoPickerPage.tsx

 1// Repository picker page (/). Shows all registered repos and lets the user
 2// navigate into one. When there is only one repo, the list still renders
 3// (no auto-redirect) so the user always knows which repo they're entering.
 4
 5import { Link } from 'react-router-dom'
 6import { GitFork, FolderOpen, AlertCircle } from 'lucide-react'
 7import { Skeleton } from '@/components/ui/skeleton'
 8import { useRepositoriesQuery } from '@/__generated__/graphql'
 9
10export function RepoPickerPage() {
11  const { data, loading, error } = useRepositoriesQuery()
12
13  return (
14    <div className="mx-auto max-w-lg py-12">
15      <div className="mb-8 flex items-center gap-3">
16        <GitFork className="size-6 text-muted-foreground" />
17        <h1 className="text-xl font-semibold">Repositories</h1>
18      </div>
19
20      {error && (
21        <div className="flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive">
22          <AlertCircle className="size-4 shrink-0" />
23          Failed to load repositories: {error.message}
24        </div>
25      )}
26
27      {loading && !data && (
28        <div className="space-y-2">
29          {Array.from({ length: 3 }).map((_, i) => (
30            <Skeleton key={i} className="h-16 w-full rounded-md" />
31          ))}
32        </div>
33      )}
34
35      <div className="divide-y divide-border rounded-md border border-border">
36        {data?.repositories.nodes.map((repo) => (
37          <Link
38            key={repo.slug}
39            to={`/${repo.slug}`}
40            className="flex items-center gap-3 px-4 py-4 hover:bg-muted/50 transition-colors"
41          >
42            <FolderOpen className="size-5 shrink-0 text-muted-foreground" />
43            <p className="font-medium text-foreground">{repo.slug}</p>
44          </Link>
45        ))}
46
47        {data?.repositories.totalCount === 0 && (
48          <p className="px-4 py-8 text-center text-sm text-muted-foreground">
49            No repositories found.
50          </p>
51        )}
52      </div>
53    </div>
54  )
55}