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.

21 linesCodeBlameRaw
1/**
2 * Workspace invitations, as the person invited sees them on /invitations
3 * and on the page for someone without a workspace. No Workers or React
4 * imports, so it can be tested under Node.
5 */
6
7type Shown = { role: "owner" | "member"; expiresAt: string };
8
9/** What follows the inviter's name: the role it joins with, and until when it works. */
10export function invitationLine(invitation: Shown, now = Date.now()): string {
11 const role = invitation.role === "owner" ? "an owner" : "a member";
12 const days = Math.ceil((new Date(invitation.expiresAt).getTime() - now) / (24 * 60 * 60 * 1000));
13 const until = days <= 1 ? "It expires within a day." : `It works for ${days} more days.`;
14 return `invited you to join as ${role}. ${until}`;
15}
16
17/** What the page says once an invitation was declined. */
18export function declinedLine(workspace: string | null | undefined): string {
19 const name = workspace?.trim();
20 return name ? `You declined the invitation to ${name}. Whoever sent it has been told.` : "You declined the invitation. Whoever sent it has been told.";
21}