FileEdit.tsx
Raw
1import type { RepositoryRow } from "../../db/index.ts";
2import type { SessionUser } from "../../middleware/session.ts";
3import { Layout } from "../layout.tsx";
4import { RepoHeader } from "../repos/RepoHeader.tsx";
5import { RepoNav } from "./RepoNav.tsx";
6
7interface FileEditProps {
8 user: SessionUser;
9 repo: RepositoryRow;
10 ref: string;
11 filePath: string;
12 content: string;
13 error?: string;
14}
15
16export function FileEdit({
17 user,
18 repo,
19 ref: editRef,
20 filePath,
21 content,
22 error,
23}: FileEditProps) {
24 const parts = filePath.split("/");
25 const filename = parts[parts.length - 1] ?? filePath;
26 return (
27 <Layout user={user} title={`Edit ${repo.name}/${filePath}`}>
28 <div class="container">
29 <RepoHeader repo={repo} />
30 <RepoNav repo={repo} active="code" user={user} />
31 <div class="breadcrumb">
32 <a href={`/${repo.name}/tree/${editRef}`}>{repo.name}</a>
33 {parts.map((part, i) => {
34 const partPath = parts.slice(0, i + 1).join("/");
35 const isLast = i === parts.length - 1;
36 return (
37 <>
38 <span class="breadcrumb-sep">/</span>
39 {isLast ? (
40 <span class="breadcrumb-current">
41 {part}
42 </span>
43 ) : (
44 <a
45 href={`/${repo.name}/tree/${editRef}/${partPath}`}
46 >
47 {part}
48 </a>
49 )}
50 </>
51 );
52 })}
53 </div>
54 <p class="form-hint">WARNING: Line endings are normalized to LF (\n) on save.</p>
55 {error && <p class="form-error">{error}</p>}
56 <form
57 method="POST"
58 action={`/${repo.name}/edit/${editRef}/${filePath}`}
59 >
60 <div class="file-blob-header">
61 <span class="file-blob-name">{filename}</span>
62 <div class="file-blob-actions">
63 <a
64 href={`/${repo.name}/blob/${editRef}/${filePath}`}
65 class="btn btn-sm btn-ghost"
66 >
67 Cancel
68 </a>
69 </div>
70 </div>
71 <div class="file-blob-body">
72 <textarea
73 name="content"
74 class="file-edit-textarea"
75 rows="30"
76 spellcheck="false"
77 autocomplete="off"
78 autocorrect="off"
79 autocapitalize="off"
80 >
81 {content}
82 </textarea>
83 </div>
84 <div class="form-card">
85 <p class="form-hint" style="margin-bottom: var(--space-4);">
86 Committing directly to{" "}
87 <strong>{editRef}</strong>
88 </p>
89 <div class="form-group">
90 <label for="message">Commit message</label>
91 <textarea
92 id="message"
93 name="message"
94 rows="3"
95 required
96 >
97 {`Edited ${filename}`}
98 </textarea>
99 </div>
100 <div class="form-actions">
101 <button type="submit" class="btn btn-primary">
102 Commit changes
103 </button>
104 <a
105 href={`/${repo.name}/blob/${editRef}/${filePath}`}
106 class="btn btn-ghost"
107 >
108 Cancel
109 </a>
110 </div>
111 </div>
112 </form>
113 </div>
114 </Layout>
115 );
116}
117