Skip to content

g1t/apps/web/app/components/start-plan.tsx

47 lines1,795 bytesCodeBlame
1/**
2 * What a free workspace may not do, and the way forward: a free workspace
3 * adds no one (members, invites, outside collaborators) until it starts the
4 * plan, and a person owns at most one free workspace. Identity refuses both
5 * either way; these say so before anyone tries.
6 */
7import { Sparkles } from "lucide-react";
8
9import { ButtonLink } from "./ui";
10
11/** Where a workspace's plan is started. */
12export function planHref(workspace: string): string {
13 return `/${workspace}/-/billing#plan`;
14}
15
16/** "Start the plan to invite people", with the button, for a free workspace's owners. */
17export function StartPlanToInvite({
18 workspace,
19 owner,
20 outside = false,
21}: {
22 workspace: string;
23 owner: boolean;
24 /** On a repository's Access page: members can still be given roles. */
25 outside?: boolean;
26}) {
27 return (
28 <div role="note" className="rounded-xl border border-accent/30 bg-accent/5 p-4">
29 <div className="flex flex-col gap-3 sm:flex-row sm:items-center">
30 <Sparkles size={16} className="hidden shrink-0 text-accent sm:block" aria-hidden />
31 <div className="min-w-0 grow">
32 <p className="text-sm font-medium">Start the plan to invite people</p>
33 <p className="mt-1 text-sm text-muted">
34 {workspace} is a free workspace, so it cannot add people
35 {outside ? " from outside it. Its members can still be given a role here." : ". Its members stay as they are."}{" "}
36 {owner ? "The plan is for everyone in the workspace at one price, never per person." : "An owner can start it."}
37 </p>
38 </div>
39 {owner && (
40 <span className="shrink-0">
41 <ButtonLink to={planHref(workspace)}>Start the plan</ButtonLink>
42 </span>
43 )}
44 </div>
45 </div>
46 );
47}