Skip to content

Commit 97e4e97

Browse files
committed
Adds additional pricing for bolt-ons for the Pro plan
1 parent c5bd14e commit 97e4e97

File tree

1 file changed

+116
-50
lines changed

1 file changed

+116
-50
lines changed

apps/webapp/app/routes/resources.orgs.$organizationSlug.select-plan.tsx

Lines changed: 116 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ const pricingDefinitions = {
171171
title: "Concurrent runs",
172172
content: "The number of runs that can be executed at the same time.",
173173
},
174+
additionalConcurrency: {
175+
title: "Additional concurrency",
176+
content: "Then $50/month per 50",
177+
},
174178
taskRun: {
175179
title: "Task runs",
176180
content: "A single execution of a task.",
@@ -188,6 +192,10 @@ const pricingDefinitions = {
188192
title: "Schedules",
189193
content: "You can attach recurring schedules to tasks using cron syntax.",
190194
},
195+
additionalSchedules: {
196+
title: "Additional schedules",
197+
content: "Then $10/month per 1,000",
198+
},
191199
alerts: {
192200
title: "Alert destination",
193201
content:
@@ -198,9 +206,22 @@ const pricingDefinitions = {
198206
content:
199207
"Realtime allows you to send the live status and data from your runs to your frontend. This is the number of simultaneous Realtime connections that can be made.",
200208
},
209+
additionalRealtimeConnections: {
210+
title: "Additional Realtime connections",
211+
content: "Then $10/month per 100",
212+
},
213+
additionalSeats: {
214+
title: "Additional seats",
215+
content: "Then $20/month per seat",
216+
},
201217
branches: {
202218
title: "Branches",
203-
content: "The number of preview branches that can be active (you can archive old ones).",
219+
content:
220+
"Preview branches allow you to test changes before deploying to production. You can have a limited number active at once (but can archive old ones).",
221+
},
222+
additionalBranches: {
223+
title: "Additional branches",
224+
content: "Then $10/month per branch",
204225
},
205226
};
206227

@@ -507,7 +528,7 @@ export function TierFree({
507528
<LogRetention limits={plan.limits} />
508529
<SupportLevel limits={plan.limits} />
509530
<Alerts limits={plan.limits} />
510-
<RealtimeConnecurrency limits={plan.limits} />
531+
<RealtimeConcurrency limits={plan.limits} />
511532
</ul>
512533
</>
513534
)}
@@ -624,7 +645,7 @@ export function TierHobby({
624645
<LogRetention limits={plan.limits} />
625646
<SupportLevel limits={plan.limits} />
626647
<Alerts limits={plan.limits} />
627-
<RealtimeConnecurrency limits={plan.limits} />
648+
<RealtimeConcurrency limits={plan.limits} />
628649
</ul>
629650
</TierContainer>
630651
);
@@ -724,7 +745,9 @@ export function TierPro({
724745
</div>
725746
</Form>
726747
<ul className="flex flex-col gap-2.5">
727-
<ConcurrentRuns limits={plan.limits} />
748+
<ConcurrentRuns limits={plan.limits}>
749+
{pricingDefinitions.additionalConcurrency.content}
750+
</ConcurrentRuns>
728751
<FeatureItem checked>
729752
Unlimited{" "}
730753
<DefinitionTip
@@ -734,14 +757,16 @@ export function TierPro({
734757
tasks
735758
</DefinitionTip>
736759
</FeatureItem>
737-
<TeamMembers limits={plan.limits} />
760+
<TeamMembers limits={plan.limits}>{pricingDefinitions.additionalSeats.content}</TeamMembers>
738761
<Environments limits={plan.limits} />
739-
<Branches limits={plan.limits} />
740-
<Schedules limits={plan.limits} />
762+
<Branches limits={plan.limits}>{pricingDefinitions.additionalBranches.content}</Branches>
763+
<Schedules limits={plan.limits}>{pricingDefinitions.additionalSchedules.content}</Schedules>
741764
<LogRetention limits={plan.limits} />
742765
<SupportLevel limits={plan.limits} />
743766
<Alerts limits={plan.limits} />
744-
<RealtimeConnecurrency limits={plan.limits} />
767+
<RealtimeConcurrency limits={plan.limits}>
768+
{pricingDefinitions.additionalRealtimeConnections.content}
769+
</RealtimeConcurrency>
745770
</ul>
746771
</TierContainer>
747772
);
@@ -902,16 +927,16 @@ function FeatureItem({
902927
children: React.ReactNode;
903928
}) {
904929
return (
905-
<li className="flex items-center gap-2">
930+
<li className="flex items-start gap-2">
906931
{checked ? (
907932
<CheckIcon
908933
className={cn(
909-
"size-4 min-w-4",
934+
"mt-0.5 size-4 min-w-4",
910935
checkedColor === "primary" ? "text-primary" : "text-text-bright"
911936
)}
912937
/>
913938
) : (
914-
<XMarkIcon className="size-4 min-w-4 text-charcoal-500" />
939+
<XMarkIcon className="mt-0.5 size-4 min-w-4 text-charcoal-500" />
915940
)}
916941
<div
917942
className={cn(
@@ -925,26 +950,42 @@ function FeatureItem({
925950
);
926951
}
927952

928-
function ConcurrentRuns({ limits }: { limits: Limits }) {
953+
function ConcurrentRuns({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
929954
return (
930955
<FeatureItem checked>
931-
{limits.concurrentRuns.number}
932-
{limits.concurrentRuns.canExceed ? "+" : ""}{" "}
933-
<DefinitionTip
934-
title={pricingDefinitions.concurrentRuns.title}
935-
content={pricingDefinitions.concurrentRuns.content}
936-
>
937-
concurrent runs
938-
</DefinitionTip>
956+
<div className="flex flex-col gap-y-0.5">
957+
<div className="flex items-center gap-1">
958+
{limits.concurrentRuns.canExceed ? (
959+
<>
960+
{limits.concurrentRuns.number}
961+
{"+"}
962+
</>
963+
) : (
964+
<>{limits.concurrentRuns.number} </>
965+
)}{" "}
966+
<DefinitionTip
967+
title={pricingDefinitions.concurrentRuns.title}
968+
content={pricingDefinitions.concurrentRuns.content}
969+
>
970+
concurrent runs
971+
</DefinitionTip>
972+
</div>
973+
{children && <span className="text-xs text-text-dimmed">{children}</span>}
974+
</div>
939975
</FeatureItem>
940976
);
941977
}
942978

943-
function TeamMembers({ limits }: { limits: Limits }) {
979+
function TeamMembers({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
944980
return (
945981
<FeatureItem checked>
946-
{limits.teamMembers.number}
947-
{limits.concurrentRuns.canExceed ? "+" : ""} team members
982+
<div className="flex flex-col gap-y-0.5">
983+
<div className="flex items-center gap-1">
984+
{limits.teamMembers.number}
985+
{limits.teamMembers.canExceed ? "+" : ""} team members
986+
</div>
987+
{children && <span className="text-xs text-text-dimmed">{children}</span>}
988+
</div>
948989
</FeatureItem>
949990
);
950991
}
@@ -963,17 +1004,22 @@ function Environments({ limits }: { limits: Limits }) {
9631004
);
9641005
}
9651006

966-
function Schedules({ limits }: { limits: Limits }) {
1007+
function Schedules({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
9671008
return (
9681009
<FeatureItem checked>
969-
{limits.schedules.number}
970-
{limits.schedules.canExceed ? "+" : ""}{" "}
971-
<DefinitionTip
972-
title={pricingDefinitions.schedules.title}
973-
content={pricingDefinitions.schedules.content}
974-
>
975-
schedules
976-
</DefinitionTip>
1010+
<div className="flex flex-col gap-y-0.5">
1011+
<div className="flex items-center gap-1">
1012+
{limits.schedules.number}
1013+
{limits.schedules.canExceed ? "+" : ""}{" "}
1014+
<DefinitionTip
1015+
title={pricingDefinitions.schedules.title}
1016+
content={pricingDefinitions.schedules.content}
1017+
>
1018+
schedules
1019+
</DefinitionTip>
1020+
</div>
1021+
{children && <span className="text-xs text-text-dimmed">{children}</span>}
1022+
</div>
9771023
</FeatureItem>
9781024
);
9791025
}
@@ -1018,32 +1064,52 @@ function Alerts({ limits }: { limits: Limits }) {
10181064
);
10191065
}
10201066

1021-
function RealtimeConnecurrency({ limits }: { limits: Limits }) {
1067+
function RealtimeConcurrency({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
10221068
return (
10231069
<FeatureItem checked>
1024-
{limits.realtimeConcurrentConnections.number}
1025-
{limits.realtimeConcurrentConnections.canExceed ? "+" : ""}{" "}
1026-
<DefinitionTip
1027-
title={pricingDefinitions.realtime.title}
1028-
content={pricingDefinitions.realtime.content}
1029-
>
1030-
concurrent Realtime connections
1031-
</DefinitionTip>
1070+
<div className="flex flex-col gap-y-0.5">
1071+
<div className="flex items-start gap-1">
1072+
{limits.realtimeConcurrentConnections.canExceed ? (
1073+
<>
1074+
{limits.realtimeConcurrentConnections.number}
1075+
{"+"}
1076+
</>
1077+
) : (
1078+
<>{limits.realtimeConcurrentConnections.number} </>
1079+
)}{" "}
1080+
<DefinitionTip
1081+
title={pricingDefinitions.realtime.title}
1082+
content={pricingDefinitions.realtime.content}
1083+
>
1084+
concurrent Realtime connections
1085+
</DefinitionTip>
1086+
</div>
1087+
{children && <span className="text-xs text-text-dimmed">{children}</span>}
1088+
</div>
10321089
</FeatureItem>
10331090
);
10341091
}
10351092

1036-
function Branches({ limits }: { limits: Limits }) {
1093+
function Branches({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
10371094
return (
10381095
<FeatureItem checked={limits.branches.number > 0}>
1039-
{limits.branches.number}
1040-
{limits.branches.canExceed ? "+ " : " "}
1041-
<DefinitionTip
1042-
title={pricingDefinitions.branches.title}
1043-
content={pricingDefinitions.branches.content}
1044-
>
1045-
preview branches
1046-
</DefinitionTip>
1096+
<div className="flex flex-col gap-y-0.5">
1097+
<div className="flex items-center gap-1">
1098+
{limits.branches.number > 0 && (
1099+
<>
1100+
{limits.branches.number}
1101+
{limits.branches.canExceed ? "+ " : " "}
1102+
</>
1103+
)}
1104+
<DefinitionTip
1105+
title={pricingDefinitions.branches.title}
1106+
content={pricingDefinitions.branches.content}
1107+
>
1108+
{limits.branches.number > 0 ? "preview" : "Preview"} branches
1109+
</DefinitionTip>
1110+
</div>
1111+
{children && <span className="text-xs text-text-dimmed">{children}</span>}
1112+
</div>
10471113
</FeatureItem>
10481114
);
10491115
}

0 commit comments

Comments
 (0)