Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
72 linesCodeBlameRaw
1import { data, Link } from "react-router";
2
3import type { Route } from "./+types/policy";
4import { PoliciesDraft } from "../components/policies-draft";
5import { Contents, PolicyText, TrustPage, outline } from "../components/legal-doc";
6import { POLICIES, POLICIES_UPDATED, longDate } from "../lib/legal";
7import { page } from "../lib/meta";
8import acceptableUse from "../content/policies/acceptable-use.md?raw";
9import privacy from "../content/policies/privacy.md?raw";
10import refunds from "../content/policies/refunds.md?raw";
11import subprocessors from "../content/policies/subprocessors.md?raw";
12import terms from "../content/policies/terms.md?raw";
13
14/** Each policy's text, written in Markdown in app/content/policies. */
15const TEXT: Record<string, string> = {
16 terms,
17 privacy,
18 "acceptable-use": acceptableUse,
19 refunds,
20 subprocessors,
21};
22
23export function loader({ params }: Route.LoaderArgs) {
24 const policy = POLICIES.find((p) => p.slug === params.policy);
25 if (!policy || !TEXT[policy.slug]) throw data(null, { status: 404 });
26 return { policy };
27}
28
29export function meta({ loaderData, ...args }: Route.MetaArgs) {
30 const policy = loaderData?.policy;
31 return page(args, {
32 title: policy ? `${policy.title} · g1t` : "Policies · g1t",
33 description: policy?.summary,
34 });
35}
36
37export default function Policy({ loaderData }: Route.ComponentProps) {
38 const { policy } = loaderData;
39 const source = TEXT[policy.slug];
40 return (
41 <TrustPage
42 eyebrow={
43 <Link to="/policies" className="hover:underline hover:underline-offset-4">
44 Policies
45 </Link>
46 }
47 title={policy.title}
48 lede={<p className="text-sm">Last updated {longDate(POLICIES_UPDATED)}.</p>}
49 aside={<Contents items={outline(source)} />}
50 >
51 <PoliciesDraft />
52 <PolicyText source={source} />
53 <nav aria-label="Other policies" className="mt-14 max-w-3xl border-t border-line pt-6">
54 <p className="text-sm font-medium">Other policies</p>
55 <ul className="mt-3 flex flex-wrap gap-x-5 gap-y-2 text-sm text-muted">
56 {POLICIES.filter((p) => p.slug !== policy.slug).map((p) => (
57 <li key={p.slug}>
58 <Link to={`/policies/${p.slug}`} className="hover:text-fg">
59 {p.title}
60 </Link>
61 </li>
62 ))}
63 <li>
64 <Link to="/security" className="hover:text-fg">
65 Security
66 </Link>
67 </li>
68 </ul>
69 </nav>
70 </TrustPage>
71 );
72}