g1t/apps/web/app/routes/repo/code.tsx
| 1 | import { Search } from "lucide-react"; |
| 2 | import { Form } from "react-router"; |
| 3 | |
| 4 | import type { Route } from "./+types/code"; |
| 5 | import { TreeView } from "../../components/repo-view"; |
| 6 | import { notACredential } from "../../components/ui"; |
| 7 | import { page } from "../../lib/meta"; |
| 8 | import { repos } from "../../lib/services.server"; |
| 9 | import { getViewer, unwrap } from "../../lib/session.server"; |
| 10 | |
| 11 | export function meta({ params, ...args }: Route.MetaArgs) { |
| 12 | return page(args, { title: `Code · ${params.owner}/${params.repo} · g1t` }); |
| 13 | } |
| 14 | |
| 15 | export async function loader({ params, context }: Route.LoaderArgs) { |
| 16 | const path = { namespace: params.owner, name: params.repo }; |
| 17 | return unwrap(await repos.tree(path, getViewer(context), null, "")); |
| 18 | } |
| 19 | |
| 20 | /** |
| 21 | * Searches this repository's code: the search page adds `repo:` for it, so |
| 22 | * the results can be widened to all of g1t from there. |
| 23 | */ |
| 24 | function SearchThisRepository({ repo }: { repo: string }) { |
| 25 | return ( |
| 26 | <Form action="/search" role="search" className="relative mb-4 max-w-md"> |
| 27 | <Search size={14} className="pointer-events-none absolute top-1/2 left-3 -translate-y-1/2 text-faint" /> |
| 28 | <input |
| 29 | name="q" |
| 30 | {...notACredential()} |
| 31 | placeholder="Search this repository's code" |
| 32 | aria-label={`Search ${repo}`} |
| 33 | className="h-9 w-full rounded-md border border-line bg-surface pr-3 pl-8 text-sm outline-none transition-colors placeholder:text-faint hover:border-line-strong focus:border-accent-dim" |
| 34 | /> |
| 35 | <input type="hidden" name="repo" value={repo} /> |
| 36 | <input type="hidden" name="type" value="code" /> |
| 37 | </Form> |
| 38 | ); |
| 39 | } |
| 40 | |
| 41 | export default function Code({ loaderData }: Route.ComponentProps) { |
| 42 | const repo = `${loaderData.repo.namespace}/${loaderData.repo.name}`; |
| 43 | return ( |
| 44 | <> |
| 45 | {loaderData.head && <SearchThisRepository repo={repo} />} |
| 46 | <TreeView tree={loaderData} /> |
| 47 | </> |
| 48 | ); |
| 49 | } |