RepoHome.tsx
Raw
1import config from "../../config.ts";
2import type { RepositoryRow } from "../../db/index.ts";
3import type { SessionUser } from "../../middleware/session.ts";
4import type { TreeEntry } from "../../services/git.ts";
5import { Layout } from "../layout.tsx";
6import { BranchSelector } from "./BranchSelector.tsx";
7import { FileTreeTable } from "./FileTreeTable.tsx";
8import { RepoHeader } from "./RepoHeader.tsx";
9import { RepoNav } from "./RepoNav.tsx";
10
11interface RepoHomeProps {
12 user: SessionUser | null;
13 repo: RepositoryRow;
14 entries: TreeEntry[];
15 readmeHtml: string | null;
16 readmePath?: string;
17 hasContent: boolean;
18 branches: string[];
19 tags?: string[];
20}
21
22export function RepoHome({
23 user,
24 repo,
25 entries,
26 readmeHtml,
27 readmePath,
28 hasContent,
29 branches,
30 tags,
31}: RepoHomeProps) {
32 return (
33 <Layout user={user} title={repo.name}>
34 <div class="container">
35 <RepoHeader repo={repo} />
36 {repo.description && (
37 <p class="repo-description">{repo.description}</p>
38 )}
39 <RepoNav repo={repo} active="code" user={user} />
40 {!hasContent ? (
41 <div class="empty-state">
42 <h2>This repository is empty.</h2>
43 <p>Push your first commit to get started:</p>
44 <pre class="code-setup">
45 <code>{`git clone ${sshUrl(repo.name)}
46cd ${repo.name}
47echo "# ${repo.name}" > README.md
48git add .
49git commit -m "Initial commit"
50git push origin main`}</code>
51 </pre>
52 </div>
53 ) : (
54 <>
55 <div class="tree-toolbar">
56 <BranchSelector
57 repoName={repo.name}
58 branches={branches}
59 tags={tags}
60 currentRef={repo.default_branch}
61 view="tree"
62 />
63 <div class="tree-toolbar-actions">
64 {branches.includes(repo.default_branch) &&
65 user?.isAdmin && (
66 <a
67 href={`/${repo.name}/new-file/${repo.default_branch}`}
68 class="btn btn-sm btn-primary"
69 >
70 New file
71 </a>
72 )}
73 <details class="clone-popup-details">
74 <summary class="btn btn-sm btn-primary">
75 Clone
76 </summary>
77 <div class="clone-popup">
78 <div class="clone-url-row">
79 <span class="clone-url-label">
80 HTTP
81 </span>
82 <input
83 type="text"
84 readonly
85 value={httpUrl(repo.name)}
86 class="clone-url-input"
87 />
88 </div>
89 {!config.SSH_DISABLED && (
90 <div class="clone-url-row">
91 <span class="clone-url-label">
92 SSH
93 </span>
94 <input
95 type="text"
96 readonly
97 value={sshUrl(repo.name)}
98 class="clone-url-input"
99 />
100 </div>
101 )}
102 </div>
103 </details>
104 </div>
105 </div>
106 <FileTreeTable
107 repoName={repo.name}
108 treeRef={repo.default_branch}
109 subpath=""
110 entries={entries}
111 />
112 {readmeHtml && (
113 <div class="readme-section">
114 <div class="readme-header">
115 <span>README</span>
116 {readmePath && (
117 <a
118 href={`/${repo.name}/raw/${repo.default_branch}/${readmePath}`}
119 class="btn btn-sm"
120 >
121 Raw
122 </a>
123 )}
124 </div>
125 <div class="markdown-body">{readmeHtml}</div>
126 </div>
127 )}
128 </>
129 )}
130 </div>
131 </Layout>
132 );
133}
134
135function httpUrl(name: string) {
136 return `${config.BASE_URL}/${name}.git`;
137}
138
139function sshUrl(name: string) {
140 const host = new URL(config.BASE_URL).hostname;
141 return `ssh://git@${host}:${config.SSH_PORT}/${name}.git`;
142}
143