Skip to content
File

Blob: src/client/pages/OwnerPage.tsx

typescript79 lines
1import { Folder, Lock } from "lucide-react";
2 
3import { EmptyState } from "@/client/components/EmptyState";
4import { PageHeader } from "@/client/components/ui/page-header";
5 
6export type OwnerPageRepo = {
7 slug: string;
8 visibility: "public" | "private";
9};
10 
11export type OwnerPageProps = {
12 owner: string;
13 repos: OwnerPageRepo[];
14};
15 
16export function OwnerPage({ owner, repos }: OwnerPageProps) {
17 return (
18 <div>
19 <PageHeader>
20 <div>
21 <span className="mb-1 inline-block text-xs font-semibold uppercase tracking-wider text-accent-500 dark:text-accent-400">
22 Owner
23 </span>
24 <div className="font-display text-2xl font-bold tracking-tight">{owner}</div>
25 </div>
26 <div></div>
27 </PageHeader>
28 <h2>Repositories</h2>
29 <div className="mt-6 grid gap-6 md:grid-cols-2">
30 {repos.length ? (
31 repos.map((repo, i) => {
32 const isPrivate = repo.visibility === "private";
33 const Icon = isPrivate ? Lock : Folder;
34 return (
35 <a
36 key={repo.slug}
37 href={`/${owner}/${repo.slug}`}
38 className="group block animate-slide-up opacity-0 rounded-2xl border border-zinc-300 dark:border-zinc-800/60 bg-white shadow-sm dark:bg-zinc-900/50 dark:shadow-none p-5 hover:-translate-y-0.5 transition-transform cursor-pointer hover:border-zinc-400 dark:hover:border-zinc-700/60 hover:shadow-md"
39 style={{ animationDelay: `${Math.min(i, 7) * 60}ms` }}
40 >
41 <div className="flex items-center gap-3">
42 <span
43 className={`inline-grid h-9 w-9 shrink-0 place-items-center rounded-xl bg-zinc-100 transition-colors group-hover:bg-accent-50 dark:bg-zinc-800 dark:group-hover:bg-accent-900/20 ${
44 isPrivate
45 ? "text-amber-700 group-hover:text-amber-700 dark:text-amber-400 dark:group-hover:text-amber-400"
46 : "text-zinc-500 group-hover:text-accent-500 dark:text-zinc-400 dark:group-hover:text-accent-400"
47 }`}
48 aria-label={isPrivate ? "Private repository" : undefined}
49 >
50 <Icon className="h-[1.1rem] w-[1.1rem]" aria-hidden="true" />
51 </span>
52 <div className="text-lg font-medium">
53 <span className="text-zinc-500 dark:text-zinc-400">{owner}</span>
54 <span className="mx-1 text-zinc-300 dark:text-zinc-600">/</span>
55 <span className="transition-colors group-hover:text-accent-500 dark:group-hover:text-accent-400">
56 {repo.slug}
57 </span>
58 </div>
59 </div>
60 </a>
61 );
62 })
63 ) : (
64 <div className="col-span-full">
65 <EmptyState
66 icon={
67 <Folder className="h-7 w-7 text-zinc-500 dark:text-zinc-400" aria-hidden="true" />
68 }
69 title="No repositories yet"
70 detail="Push a repository to get started."
71 large
72 />
73 </div>
74 )}
75 </div>
76 </div>
77 );
78}