Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 1 | import { Form } from "react-router"; |
| 2 | ||
| 3 | import type { Route } from "./+types/github"; | |
| 4 | import { page } from "../../lib/meta"; | |
| Merge branch 'worktree-agent-a985c01f43538af01' | 5 | import { ErrorText, SubmitButton, TimeAgo } from "../../components/ui"; |
| Merge branch 'worktree-agent-ae1299e92e4462012' | 6 | import { Hint } from "../../components/ui/hint"; |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 7 | import { assertSameOrigin, requireUser } from "../../lib/session.server"; |
| 8 | import { GithubMark } from "../../components/github"; | |
| 9 | import { githubSignIn } from "../../lib/github.server"; | |
| 10 | ||
| 11 | export function meta(args: Route.MetaArgs) { | |
| 12 | return page(args, { title: "GitHub · Settings · g1t" }); | |
| 13 | } | |
| 14 | ||
| 15 | export async function loader({ request, context }: Route.LoaderArgs) { | |
| 16 | const user = requireUser(context, request); | |
| 17 | return { github: await githubSignIn.account(user).catch(() => null) }; | |
| 18 | } | |
| 19 | ||
| 20 | export async function action({ request, context }: Route.ActionArgs) { | |
| 21 | assertSameOrigin(request); | |
| 22 | const user = requireUser(context, request); | |
| 23 | const form = await request.formData(); | |
| 24 | if (form.get("intent") === "unlink-github") { | |
| 25 | const result = await githubSignIn.unlink(user); | |
| 26 | return result.ok ? null : { githubError: result.error.message }; | |
| 27 | } | |
| 28 | return null; | |
| 29 | } | |
| 30 | ||
| 31 | export default function GithubSettings({ loaderData, actionData }: Route.ComponentProps) { | |
| 32 | const { github } = loaderData; | |
| 33 | if (!github?.enabled) { | |
| 34 | return <p className="text-sm text-muted">Signing in with GitHub is not set up here.</p>; | |
| 35 | } | |
| 36 | return ( | |
| 37 | <section id="github" className="scroll-mt-20"> | |
| 38 | {github.account ? ( | |
| 39 | <div className="flex flex-wrap items-center gap-x-4 gap-y-2 rounded-md border border-line px-4 py-3"> | |
| 40 | <GithubMark className="size-5 shrink-0" /> | |
| 41 | <div className="min-w-0"> | |
| 42 | <p className="text-sm"> | |
| 43 | Linked to <span className="font-mono">@{github.account.login}</span> | |
| 44 | </p> | |
| 45 | <p className="text-xs text-faint"> | |
| 46 | Since <TimeAgo at={github.account.linkedAt} /> | |
| 47 | {!github.account.authorized && " · access ended: link it again to import repositories"} | |
| 48 | </p> | |
| 49 | </div> | |
| 50 | <div className="ml-auto flex items-center gap-2"> | |
| 51 | {!github.account.authorized && ( | |
| 52 | <a href="/auth/github?link=1" className="text-sm text-muted hover:text-fg"> | |
| 53 | Link again | |
| 54 | </a> | |
| 55 | )} | |
| 56 | <Form method="post"> | |
| 57 | <input type="hidden" name="intent" value="unlink-github" /> | |
| Merge branch 'worktree-agent-ae1299e92e4462012' | 58 | <Hint label={github.hasPassword ? undefined : "GitHub is how you sign in. Set a password first."} disabled={!github.hasPassword}> |
| The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after. | 59 | <SubmitButton variant="outline" pending="Unlinking…" match={{ intent: "unlink-github" }} disabled={!github.hasPassword}> |
| Merge branch 'worktree-agent-ae1299e92e4462012' | 60 | Unlink |
| 61 | </SubmitButton> | |
| 62 | </Hint> | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 63 | </Form> |
| 64 | </div> | |
| 65 | </div> | |
| 66 | ) : ( | |
| 67 | <a | |
| 68 | href="/auth/github?link=1" | |
| 69 | className="inline-flex items-center gap-2 rounded-md border border-line px-3.5 py-2 text-sm font-medium text-fg/90 hover:border-line-strong hover:bg-surface hover:text-fg" | |
| 70 | > | |
| 71 | <GithubMark /> Link GitHub | |
| 72 | </a> | |
| 73 | )} | |
| 74 | {github.account && !github.hasPassword && ( | |
| 75 | <p className="mt-2 text-xs text-faint"> | |
| 76 | GitHub is the only way you sign in, so it cannot be unlinked yet. Sign out and use Forgot your password to set one. | |
| 77 | </p> | |
| 78 | )} | |
| 79 | <ErrorText>{actionData?.githubError}</ErrorText> | |
| 80 | </section> | |
| 81 | ); | |
| 82 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.