Skip to content
82 linesCodeBlameRaw

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.

Merge workspace invitations: nobody joins a workspace without saying yes, people are found by username, your own invites can bring someone in, and nobody is left without a workspace (identity 0040)1import { Link } from "react-router";
2
3import type { Route } from "./+types/invitations";
4import { InvitationList } from "../components/invitation-list";
5import { answerInvitation, loadInvitations } from "../lib/invitations.server";
6import { declinedLine } from "../lib/invitations";
7import { page } from "../lib/meta";
8import { assertSameOrigin, nextPath, requireUser } from "../lib/session.server";
9
10export function meta(args: Route.MetaArgs) {
11 return page(args, { title: "Invitations · g1t" });
12}
13
14/**
15 * The workspace invitations waiting for the signed-in person's answer.
16 * Nobody joins a workspace without saying yes here (or on the invite's own
17 * page). Linked from the inbox item and the invitation email.
18 */
19export async function loader({ request, context }: Route.LoaderArgs) {
20 const user = requireUser(context, request);
21 const next = nextPath(request);
22 return {
23 invitations: await loadInvitations(user),
24 hasWorkspace: (user.workspaces ?? []).length > 0,
25 next: next === "/" ? null : next,
26 };
27}
28
29export async function action({ request, context }: Route.ActionArgs) {
30 assertSameOrigin(request);
31 const user = requireUser(context, request);
32 return (await answerInvitation(user, await request.formData(), request)) ?? null;
33}
34
35export default function Invitations({ loaderData, actionData }: Route.ComponentProps) {
36 const { invitations, hasWorkspace, next } = loaderData;
37 return (
38 <main className="mx-auto max-w-2xl px-4 py-12">
39 <h1 className="text-xl font-semibold">Invitations</h1>
40 <p className="mt-2 text-sm text-muted">
41 Workspaces you are invited to join. You join one only when you accept; declining tells whoever invited you.
42 </p>
43 {actionData?.declined !== undefined && (
44 <p className="mt-4 text-sm text-muted" role="status">
45 {declinedLine(actionData.declined)}
46 </p>
47 )}
48 <div className="mt-6">
49 {invitations.length > 0 ? (
50 <InvitationList
51 invitations={invitations}
52 error={actionData?.invitationError}
53 errorFor={actionData?.invitationId}
54 next={next}
55 />
56 ) : (
57 <div className="rounded-xl border border-dashed border-line px-6 py-10 text-center">
58 <p className="text-sm font-medium">No invitations waiting</p>
59 <p className="mt-1 text-sm text-muted">
60 {hasWorkspace ? (
61 <>
62 When someone invites you to a workspace, it shows here and in your{" "}
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.63 <Link to="/notifications" className="underline underline-offset-4 hover:text-fg">
64 notifications
Merge workspace invitations: nobody joins a workspace without saying yes, people are found by username, your own invites can bring someone in, and nobody is left without a workspace (identity 0040)65 </Link>
66 .
67 </>
68 ) : (
69 <>
70 <Link to="/workspaces/new" className="underline underline-offset-4 hover:text-fg">
71 Create your workspace
72 </Link>
73 , or ask a workspace's owners to invite you by your username.
74 </>
75 )}
76 </p>
77 </div>
78 )}
79 </div>
80 </main>
81 );
82}

This file's history is long; its oldest lines are credited to the oldest commit read.