PatchList.tsx
⎇
Raw
1import type { PatchRow, RepositoryRow } from "../../db/index.ts";
2import { displayName } from "../../lib/users.ts";
3import type { SessionUser } from "../../middleware/session.ts";
4import { Avatar } from "../Avatar.tsx";
5import { Layout } from "../layout.tsx";
6import { Pagination, type PaginationInfo } from "../Pagination.tsx";
7import { RepoHeader } from "../repos/RepoHeader.tsx";
8import { RepoNav } from "../repos/RepoNav.tsx";
9
10interface PatchListProps {
11 user: SessionUser | null;
12 repo: RepositoryRow;
13 patches: (PatchRow & { author_username: string; author_avatar_version: number | null })[];
14 status: string;
15 counts: Record<string, number>;
16 pagination: PaginationInfo;
17}
18
19export function PatchList({
20 user,
21 repo,
22 patches,
23 status,
24 counts,
25 pagination,
26}: PatchListProps) {
27 return (
28 <Layout user={user} title={`Patches — ${repo.name}`}>
29 <div class="container">
30 <RepoHeader repo={repo} />
31 <RepoNav repo={repo} active="patches" user={user} />
32 <div class="list-header">
33 <div class="list-header-tabs">
34 <a
35 href={`/${repo.name}/patches?status=open`}
36 class={`list-tab${status === "open" ? " active" : ""}`}
37 >
38 Open{" "}
39 {(counts.open ?? 0) > 0 && (
40 <span class="tab-count">{counts.open}</span>
41 )}
42 </a>
43 <a
44 href={`/${repo.name}/patches?status=merged`}
45 class={`list-tab${status === "merged" ? " active" : ""}`}
46 >
47 Merged{" "}
48 {(counts.merged ?? 0) > 0 && (
49 <span class="tab-count">{counts.merged}</span>
50 )}
51 </a>
52 <a
53 href={`/${repo.name}/patches?status=closed`}
54 class={`list-tab${status === "closed" ? " active" : ""}`}
55 >
56 Closed{" "}
57 {(counts.closed ?? 0) > 0 && (
58 <span class="tab-count">{counts.closed}</span>
59 )}
60 </a>
61 </div>
62 {user && (
63 <a
64 href={`/${repo.name}/patches/new`}
65 class="btn btn-primary btn-sm"
66 >
67 Upload patch
68 </a>
69 )}
70 </div>
71 {patches.length === 0 ? (
72 <div class="empty-state">
73 <p>No {status} patches.</p>
74 </div>
75 ) : (
76 <ul class="issue-list">
77 {patches.map((patch) => (
78 <li class="issue-item">
79 <div class="issue-main">
80 <span
81 class={`patch-status-dot ${patch.status}`}
82 />
83 <a
84 href={`/${repo.name}/patches/${patch.number}`}
85 class="issue-title"
86 >
87 {patch.title}
88 </a>
89 <span class="issue-number">
90 #{patch.number}
91 </span>
92 </div>
93 <div class="issue-meta">
94 <Avatar
95 userId={patch.author_id}
96 version={patch.author_avatar_version}
97 size={20}
98 />
99 <span>
100 by {displayName(patch.author_username)}
101 </span>
102 <time datetime={patch.created_at}>
103 {new Date(
104 patch.created_at,
105 ).toLocaleDateString()}
106 </time>
107 </div>
108 </li>
109 ))}
110 </ul>
111 )}
112 <Pagination {...pagination} />
113 </div>
114 </Layout>
115 );
116}
117