g1t/apps/web/app/routes/support.tsx

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