Skip to content
215 linesCodeBlameRaw
1import { ArrowUpRight, BookOpen, CircleAlert, CreditCard, LifeBuoy, Lock, ShieldAlert, Activity, Ticket } from "lucide-react";
2import type { ReactNode } from "react";
3import { Link } from "react-router";
4
5import type { Route } from "./+types/support";
6import { TrustPage } from "../components/trust-page";
7import { StatusDot, useSiteStatus } from "../components/footer";
8import { STATUS_URL, statusTitle } from "../lib/status";
9import { CONTACT } from "../lib/legal";
10import { page } from "../lib/meta";
11import { Card } from "../components/ui/card";
12
13export function meta(args: Route.MetaArgs) {
14 return page(args, {
15 title: "Support · g1t",
16 description: "How to get help with g1t: the documentation, the status page, who to write to, and what to include.",
17 });
18}
19
20const DOCS: [string, string][] = [
21 ["Quickstart", "https://docs.g1t.sh/quickstart/"],
22 ["Working with g1t", "https://docs.g1t.sh/guides/working-with-g1t/"],
23 ["Git", "https://docs.g1t.sh/guides/git/"],
24 ["Accounts and sign-in", "https://docs.g1t.sh/guides/authentication/"],
25 ["Usage and billing", "https://docs.g1t.sh/guides/usage-and-billing/"],
26 ["Guardrails", "https://docs.g1t.sh/guides/guardrails/"],
27 ["API reference", "https://docs.g1t.sh/reference/api/"],
28 ["MCP tools", "https://docs.g1t.sh/reference/mcp/"],
29];
30
31const MAILBOXES: { icon: ReactNode; title: string; address: string; about: string }[] = [
32 {
33 icon: <LifeBuoy size={16} />,
34 title: "Help with g1t",
35 address: CONTACT.support,
36 about: "Accounts, workspaces, git, agents, deployments, something that doesn't work, or closing an account.",
37 },
38 {
39 icon: <Ticket size={16} />,
40 title: "Invites",
41 address: CONTACT.support,
42 about: "More invites for you or your workspace. Say who you would like to bring.",
43 },
44 {
45 icon: <CreditCard size={16} />,
46 title: "Billing",
47 address: CONTACT.billing,
48 about: "Charges, invoices, refunds, custom terms and enterprise billing.",
49 },
50 {
51 icon: <ShieldAlert size={16} />,
52 title: "Security",
53 address: CONTACT.security,
54 about: "A vulnerability in g1t. See responsible disclosure on the security page.",
55 },
56 {
57 icon: <Lock size={16} />,
58 title: "Privacy",
59 address: CONTACT.privacy,
60 about: "A copy of your information, deleting it, or a question about how it's used.",
61 },
62 {
63 icon: <CircleAlert size={16} />,
64 title: "Report abuse",
65 address: CONTACT.abuse,
66 about: "Something on g1t that breaks the Acceptable Use Policy: malware, phishing, spam, infringement.",
67 },
68];
69
70function Section({ title, children }: { title: string; children: ReactNode }) {
71 return (
72 <section className="mt-14 first:mt-0">
73 <h2 className="text-xl font-semibold tracking-tight">{title}</h2>
74 <div className="mt-4">{children}</div>
75 </section>
76 );
77}
78
79export default function Support() {
80 const status = useSiteStatus();
81 return (
82 <TrustPage
83 eyebrow="Support"
84 title="Get help with g1t"
85 lede={<p>Most answers are in the documentation. When they aren't, a person at g1t reads every message.</p>}
86 >
87 <div className="max-w-3xl">
88 <div className="grid gap-3 sm:grid-cols-2">
89 <a
90 href="https://docs.g1t.sh/"
91 className="group flex gap-3 rounded-xl border border-line bg-surface p-5 transition-colors hover:border-line-strong hover:bg-raised"
92 >
93 <BookOpen size={18} className="mt-0.5 shrink-0 text-accent" />
94 <span>
95 <span className="flex items-center gap-1 font-medium">
96 Read the documentation <ArrowUpRight size={14} className="text-faint group-hover:text-fg" />
97 </span>
98 <span className="mt-1 block text-sm text-muted">Guides for every part of g1t, and the API and MCP reference.</span>
99 </span>
100 </a>
101 <a
102 href={STATUS_URL}
103 className="group flex gap-3 rounded-xl border border-line bg-surface p-5 transition-colors hover:border-line-strong hover:bg-raised"
104 >
105 <Activity size={18} className="mt-0.5 shrink-0 text-accent" />
106 <span>
107 <span className="flex items-center gap-2 font-medium">
108 Check the status <StatusDot state={status?.overall.state ?? null} />
109 <ArrowUpRight size={14} className="text-faint group-hover:text-fg" />
110 </span>
111 <span className="mt-1 block text-sm text-muted">
112 {status ? `${statusTitle(status)}. ` : ""}Whether each part of g1t is working, at status.g1t.sh.
113 </span>
114 </span>
115 </a>
116 </div>
117
118 <ul className="mt-6 flex flex-wrap gap-x-5 gap-y-2 text-sm text-muted">
119 {DOCS.map(([label, href]) => (
120 <li key={href}>
121 <a href={href} className="hover:text-fg">
122 {label}
123 </a>
124 </li>
125 ))}
126 </ul>
127
128 <Section title="Write to us">
129 {/* One mailbox for now; each topic says what to put in the subject so
130 mail can be sorted. Separate addresses can come back in CONTACT. */}
131 {new Set(MAILBOXES.map((box) => box.address)).size === 1 && (
132 <p className="mb-3 text-sm text-muted">
133 Write to{" "}
134 <a href={`mailto:${MAILBOXES[0].address}`} className="font-mono text-accent hover:underline">
135 {MAILBOXES[0].address}
136 </a>{" "}
137 and start the subject with the topic below.
138 </p>
139 )}
140 <Card asChild tone="plain" divided>
141 <ul>
142 {MAILBOXES.map((box) => (
143 <li key={box.title} className="flex flex-col gap-1 px-4 py-4 sm:flex-row sm:items-start sm:gap-4">
144 <span className="flex shrink-0 items-center gap-2 font-medium sm:w-40">
145 <span className="text-muted">{box.icon}</span>
146 {box.title}
147 </span>
148 <span className="min-w-0">
149 <a
150 href={`mailto:${box.address}?subject=${encodeURIComponent(`[g1t ${box.title}] `)}`}
151 className="font-mono text-sm text-accent hover:underline"
152 >
153 {new Set(MAILBOXES.map((other) => other.address)).size === 1 ? `Subject: [g1t ${box.title}]` : box.address}
154 </a>
155 <span className="mt-0.5 block text-sm text-muted">{box.about}</span>
156 </span>
157 </li>
158 ))}
159 </ul>
160 </Card>
161 <p className="mt-4 text-sm text-muted">
162 Write from the email address on your g1t account, so we know it's you. Found a bug in g1t itself? You can
163 also open an issue on <Link to="/flagon-io/g1t/issues" className="text-accent hover:underline">flagon-io/g1t</Link>.
164 </p>
165 </Section>
166
167 <Section title="What to include">
168 <ul className="list-disc space-y-1.5 pl-5 text-[0.9375rem] text-fg/90">
169 <li>Your username, and the workspace and project, such as <code className="rounded bg-raised px-1.5 py-0.5 font-mono text-[0.85em]">g1t.sh/acme/web</code>.</li>
170 <li>A link to where it happened: the page, issue, pull request, agent run or workflow run.</li>
171 <li>What you did, what you expected, and what happened instead, with any error message as text.</li>
172 <li>When it happened, with your time zone.</li>
173 </ul>
174 <p className="mt-4 rounded-xl border border-warn/30 bg-warn/5 px-4 py-3 text-sm">
175 <span className="font-medium">Never send a password, an access token, a secret or a card number.</span>{" "}
176 <span className="text-muted">
177 g1t staff will never ask for them, by email or any other way. If you've sent one, revoke or change it.
178 </span>
179 </p>
180 </Section>
181
182 <Section title="From your workspace">
183 <p className="text-[0.9375rem] text-fg/90">
184 Owners can ask for two things straight from <span className="font-medium">Settings → Billing and plans</span>, and
185 the answer comes back to the same page and by email:
186 </p>
187 <ul className="mt-3 list-disc space-y-1.5 pl-5 text-[0.9375rem] text-fg/90">
188 <li>
189 <span className="font-medium">Raise my limit</span>, when the workspace needs more than its spend limit allows.
190 A person answers within one business day.
191 </li>
192 <li>
193 <span className="font-medium">Spent more than you meant to? Tell us.</span>, when a month ran over by
194 accident. See <Link to="/policies/refunds" className="text-accent hover:underline">refunds</Link> for the
195 goodwill credit.
196 </li>
197 </ul>
198 </Section>
199
200 <Section title="When you'll hear back">
201 <ul className="list-disc space-y-1.5 pl-5 text-[0.9375rem] text-fg/90">
202 <li>Help and billing: within one business day.</li>
203 <li>Security reports: acknowledged within two business days.</li>
204 <li>Privacy requests: within 30 days, usually much sooner.</li>
205 </ul>
206 <p className="mt-3 text-sm text-muted">
207 Business days are Monday to Friday, US time, apart from public holidays. If something seems down, the{" "}
208 <a href={STATUS_URL} className="text-accent hover:underline">status page</a> checks every part of g1t each
209 minute.
210 </p>
211 </Section>
212 </div>
213 </TrustPage>
214 );
215}