RepoSettings.tsx
Raw
1import type { LabelRow, RepositoryRow } from "../../db/index.ts";
2import type { SessionUser } from "../../middleware/session.ts";
3import { Layout } from "../layout.tsx";
4import { RepoHeader } from "./RepoHeader.tsx";
5import { RepoNav } from "./RepoNav.tsx";
6
7interface RepoSettingsProps {
8 user: SessionUser;
9 repo: RepositoryRow;
10 branches: string[];
11 labels: LabelRow[];
12 success?: string;
13 error?: string;
14}
15
16export function RepoSettings({
17 user,
18 repo,
19 branches,
20 labels,
21 success,
22 error,
23}: RepoSettingsProps) {
24 return (
25 <Layout user={user} title={`Settings — ${repo.name}`}>
26 <div class="container">
27 <RepoHeader repo={repo} />
28 <RepoNav repo={repo} active="settings" user={user} />
29 {success && <p class="form-success">{success}</p>}
30 {error && <p class="form-error">{error}</p>}
31 <form
32 method="POST"
33 action={`/${repo.name}/settings`}
34 class="form-card"
35 >
36 <div class="form-group">
37 <label for="description">Description</label>
38 <input
39 id="description"
40 name="description"
41 type="text"
42 value={repo.description ?? ""}
43 placeholder="A short description"
44 />
45 </div>
46 <div class="form-group">
47 <label for="default_branch">Default branch</label>
48 {branches.length > 0 ? (
49 <select
50 id="default_branch"
51 name="default_branch"
52 class="branch-select"
53 >
54 {branches.map((b) => (
55 <option
56 value={b}
57 selected={
58 b === repo.default_branch
59 ? true
60 : undefined
61 }
62 >
63 {b}
64 </option>
65 ))}
66 </select>
67 ) : (
68 <p class="form-hint">
69 No branches yet — push your first commit to set
70 the default branch.
71 </p>
72 )}
73 </div>
74 <div class="form-group">
75 <label class="checkbox-label">
76 <input
77 type="checkbox"
78 name="is_private"
79 value="1"
80 checked={repo.is_private === 1}
81 />
82 Private repository (only visible to you)
83 </label>
84 </div>
85 <div class="form-group">
86 <label class="checkbox-label">
87 <input
88 type="checkbox"
89 name="is_pinned"
90 value="1"
91 checked={repo.is_pinned === 1}
92 />
93 Pin this repository (always shown at the top of the
94 list)
95 </label>
96 </div>
97 <div class="form-group">
98 <label for="issue_template">
99 Issue template{" "}
100 <span class="text-muted">
101 (Markdown, prefilled when opening a new issue)
102 </span>
103 </label>
104 <textarea
105 id="issue_template"
106 name="issue_template"
107 rows="8"
108 placeholder="## Description&#10;&#10;## Steps to reproduce&#10;&#10;## Expected behavior"
109 >
110 {repo.issue_template ?? ""}
111 </textarea>
112 </div>
113 <div class="form-group">
114 <label for="patch_template">
115 Patch template{" "}
116 <span class="text-muted">
117 (Markdown, prefilled when submitting a new
118 patch)
119 </span>
120 </label>
121 <textarea
122 id="patch_template"
123 name="patch_template"
124 rows="8"
125 placeholder="## Summary&#10;&#10;## Testing"
126 >
127 {repo.patch_template ?? ""}
128 </textarea>
129 </div>
130 <button type="submit" class="btn btn-primary">
131 Save settings
132 </button>
133 </form>
134 <div class="form-card">
135 <h2 class="section-title">Labels</h2>
136 {labels.length > 0 && (
137 <div class="label-settings-list">
138 {labels.map((label) => (
139 <div class="label-settings-item">
140 <span
141 class="label-settings-swatch"
142 style={`background:${label.color}`}
143 />
144 <span class="label-settings-name">
145 {label.name}
146 </span>
147 <form
148 method="POST"
149 action={`/${repo.name}/settings/labels/delete`}
150 >
151 <input
152 type="hidden"
153 name="id"
154 value={String(label.id)}
155 />
156 <button
157 class="btn btn-danger btn-sm"
158 type="submit"
159 >
160 Delete
161 </button>
162 </form>
163 </div>
164 ))}
165 </div>
166 )}
167 <form
168 method="POST"
169 action={`/${repo.name}/settings/labels`}
170 class="label-add-form"
171 >
172 <input
173 class="form-input label-name-input"
174 type="text"
175 name="name"
176 placeholder="Label name"
177 maxlength="50"
178 required
179 />
180 <label class="label-color-swatch-label" title="Pick a color">
181 <input
182 type="color"
183 name="color"
184 value="#808080"
185 class="label-color-input"
186 />
187 </label>
188 <button type="submit" class="btn btn-secondary btn-sm">
189 Add label
190 </button>
191 </form>
192 </div>
193 <div class="danger-zone">
194 <h2 class="section-title danger-title">Danger zone</h2>
195 <div class="form-card danger-card">
196 <div class="danger-item">
197 <div>
198 <strong>Delete this repository</strong>
199 <p class="text-muted">
200 Once deleted, there is no going back.
201 </p>
202 </div>
203 <details class="confirm-details">
204 <summary class="btn btn-danger">
205 Delete repository
206 </summary>
207 <div class="confirm-popup">
208 Delete {repo.name}? This cannot be undone.
209 <form
210 method="POST"
211 action={`/${repo.name}/settings/delete`}
212 class="inline-form"
213 >
214 <button
215 type="submit"
216 class="btn btn-danger"
217 >
218 Yes, delete
219 </button>
220 </form>
221 </div>
222 </details>
223 </div>
224 </div>
225 </div>
226 </div>
227 </Layout>
228 );
229}
230