Skip to content

g1t/apps/web/app/routes/settings/applications.tsx

51 lines1,989 bytesCodeBlame

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 quotas1import { identity } from "../../lib/services.server";
2
3import type { Route } from "./+types/applications";
4import { page } from "../../lib/meta";
5import { TimeAgo } from "../../components/ui";
6import { DeleteButton } from "../../components/account-settings";
7import { assertSameOrigin, requireUser } from "../../lib/session.server";
8
9export function meta(args: Route.MetaArgs) {
10 return page(args, { title: "Connected applications · Settings · g1t" });
11}
12
13export async function loader({ request, context }: Route.LoaderArgs) {
14 const user = requireUser(context, request);
15 return { applications: await identity.listOAuthGrants(user) };
16}
17
18export async function action({ request, context }: Route.ActionArgs) {
19 assertSameOrigin(request);
20 const user = requireUser(context, request);
21 const form = await request.formData();
22 if (form.get("intent") === "sign-out-application") {
23 await identity.revokeOAuthGrant(user, String(form.get("id") ?? ""));
24 }
25 return null;
26}
27
28export default function ApplicationSettings({ loaderData }: Route.ComponentProps) {
29 const { applications } = loaderData;
30 return (
31 <section id="applications" className="scroll-mt-20">
32 {applications.length === 0 ? (
33 <p className="text-sm text-faint">None yet.</p>
34 ) : (
35 <ul className="divide-y divide-line rounded-md border border-line">
36 {applications.map((application) => (
37 <li key={application.id} className="flex items-center gap-4 px-4 py-3">
38 <div className="min-w-0">
39 <p className="truncate text-sm">{application.clientName}</p>
40 <p className="text-xs text-faint">
41 Connected <TimeAgo at={application.createdAt} /> · last used <TimeAgo at={application.lastUsedAt} />
42 </p>
43 </div>
44 <DeleteButton intent="sign-out-application" id={application.id} label="Sign out" />
45 </li>
46 ))}
47 </ul>
48 )}
49 </section>
50 );
51}