RepoList.tsx
⎇
Raw
1import type { RepositoryRow } from "../../db/index.ts";
2import type { SessionUser } from "../../middleware/session.ts";
3import { Layout } from "../layout.tsx";
4import { Pagination, type PaginationInfo } from "../Pagination.tsx";
5
6interface RepoListProps {
7 user: SessionUser | null;
8 repos: RepositoryRow[];
9 search?: string;
10 pagination: PaginationInfo;
11}
12
13export function RepoList({ user, repos, search, pagination }: RepoListProps) {
14 return (
15 <Layout user={user} title="Repositories">
16 <div class="container">
17 <div class="page-header">
18 <h1 class="page-title">Repositories</h1>
19 {user?.isAdmin && (
20 <a href="/new" class="btn btn-primary">
21 New repository
22 </a>
23 )}
24 </div>
25 <form method="GET" action="/" class="search-form">
26 <div class="search-input-wrap">
27 <input
28 type="search"
29 name="q"
30 value={search ?? ""}
31 placeholder="Search repositories…"
32 class="search-input"
33 autocomplete="off"
34 />
35 <button type="submit" class="btn btn-ghost btn-sm">
36 Search
37 </button>
38 </div>
39 </form>
40 {repos.length === 0 ? (
41 <div class="empty-state">
42 {search ? (
43 <p>
44 No repositories match <strong>{search}</strong>.
45 </p>
46 ) : (
47 <>
48 <p>No repositories yet.</p>
49 {user?.isAdmin && (
50 <a href="/new" class="btn btn-primary">
51 Create your first repository
52 </a>
53 )}
54 </>
55 )}
56 </div>
57 ) : (
58 <ul class="repo-list">
59 {repos.map((repo) => (
60 <li class="repo-card">
61 <div class="repo-card-main">
62 <div class="repo-card-title">
63 <a
64 href={`/${repo.name}`}
65 class="repo-name"
66 >
67 {repo.name}
68 </a>
69 {repo.is_private ? (
70 <span class="badge badge-private">
71 Private
72 </span>
73 ) : null}
74 </div>
75 {repo.description && (
76 <p class="repo-description">
77 {repo.description}
78 </p>
79 )}
80 </div>
81 <div class="repo-card-meta">
82 <time
83 class="repo-date"
84 datetime={repo.created_at}
85 >
86 {new Date(
87 repo.created_at,
88 ).toLocaleDateString()}
89 </time>
90 </div>
91 </li>
92 ))}
93 </ul>
94 )}
95 <Pagination {...pagination} />
96 </div>
97 </Layout>
98 );
99}
100