Skip to content
This repository was archived by the owner on Jan 31, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/hub/src/components/intro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ export function Intro({ initialStep, initialProjectName }: IntroProps) {
}}
config={{
[RivetEe.ee.billing.Plan.Trial]: {
cancelLabel: "Continue",
cancelLabel: "Get Started",
onCancel: () => {
navigate({
to: "/projects/$projectNameId/environments/$environmentNameId",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Flex,
SmallText,
Text,
cn,
} from "@rivet-gg/components";
import { Icon, type IconProp } from "@rivet-gg/icons";
import type { ReactNode } from "@tanstack/react-router";
Expand All @@ -16,7 +17,12 @@ export interface BillingPlanCardProps {
lead?: string;
price: string;
priceLead?: string;
features: { key?: string; name: ReactNode; icon?: IconProp }[];
features: {
key?: string;
name: ReactNode;
icon?: IconProp;
bold?: boolean;
}[];
type?: "custom" | "active";
onSubscribe?: () => void;
onCancel?: () => void;
Expand All @@ -37,13 +43,13 @@ export function BillingPlanCard({
return (
<Card className="flex flex-col group hover:border-primary transition-colors">
<CardHeader>
<Text className="font-bold text-3xl">{title}</Text>
<Text className="font-semibold text-2xl">{title}</Text>
{lead ? <SmallText>{lead}</SmallText> : null}
<div className="pt-8 min-h-[7rem]">
<p>
<span className="text-5xl font-bold mr-1 ">{price}</span>
<span className="text-muted-foreground">
{type !== "custom" ? "/month" : null}
{type !== "custom" ? "/mo" : null}
</span>
</p>
{priceLead ? (
Expand All @@ -52,13 +58,18 @@ export function BillingPlanCard({
</div>
</CardHeader>
<CardContent className="flex-1">
<Flex direction="col" gap="2" asChild>
<Flex direction="col" gap="4" asChild>
<ul>
{features.map(({ key, name, icon }) => (
{features.map(({ key, name, bold, icon }) => (
<Flex items="center" gap="2" key={key || name} asChild>
<li>
<li
className={cn(
bold && "font-semibold",
bold ? "text-foreground" : "text-muted-foreground",
)}
>
{icon ? <Icon icon={icon} className="size-5 " /> : null}
<span className="text-muted-foreground">{name}</span>
<span>{name}</span>
</li>
</Flex>
))}
Expand All @@ -80,7 +91,7 @@ export function BillingPlanCard({
{cancelLabel || "Cancel"}
</Button>
) : null}
{!type ? <Button onClick={onSubscribe}>Subscribe</Button> : null}
{!type ? <Button onClick={onSubscribe}>Upgrade</Button> : null}
</CardFooter>
</Card>
);
Expand Down
77 changes: 56 additions & 21 deletions apps/hub/src/domains/project/components/billing/billing-plans.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ import { Rivet as RivetEe } from "@rivet-gg/api-ee";
import { Flex, Grid, H2, Link } from "@rivet-gg/components";
import {
faBadgeCheck,
faChartMixed,
faCheckCircle,
faClock,
faComments,
faComputerClassic,
faDatabase,
faEnvelope,
faGift,
faGlobe,
faHeadset,
faInfinity,
faLockA,
faRocketLaunch,
faServer,
faShareFromSquare,
faShield,
} from "@rivet-gg/icons";
import { PRICE_MAP } from "../../data/billing-calculate-usage";
import { useBilling } from "./billing-context";
Expand Down Expand Up @@ -67,11 +68,17 @@ export function BillingPlans({
type={plan === RivetEe.ee.billing.Plan.Trial ? "active" : undefined}
features={[
{
name: "50,000 Free Actors",
name: (
<span>
50,000 Free Actors
<span className="text-xs text-muted-foreground font-normal ml-0.5">
/mo
</span>
</span>
),
bold: true,
icon: faGift,
},
{ name: "DDoS Mitigation", icon: faShield },
{ name: "Automatic SSL", icon: faLockA },
{ name: "Community Support", icon: faComments },
]}
{...config?.[RivetEe.ee.billing.Plan.Trial]}
Expand All @@ -93,12 +100,20 @@ export function BillingPlans({
priceLead="+ Actor Usage"
features={[
{
name: "200,000 Free Actors",
name: (
<span>
200,000 Free Actors
<span className="text-xs text-muted-foreground font-normal ml-0.5">
/mo
</span>
</span>
),
bold: true,
icon: faGift,
},
{ name: "Analytics", icon: faChartMixed },
{ name: "Everything in Community", icon: faCheckCircle },
{ name: "No Usage Limits", icon: faInfinity },
{ name: "Email Support", icon: faEnvelope },
{ name: "Share Features", icon: faShareFromSquare },
]}
{...config?.[RivetEe.ee.billing.Plan.Indie]}
/>
Expand All @@ -119,38 +134,58 @@ export function BillingPlans({
priceLead="+ Actor Usage"
features={[
{
name: "AWS + G Cloud + Azure",
icon: faServer,
name: (
<span>
200,000 Free Actors
<span className="text-xs text-muted-foreground font-normal ml-0.5">
/mo
</span>
</span>
),
bold: true,
icon: faGift,
},
{ name: "Analytics", icon: faChartMixed },
{ name: "Everything in Pro", icon: faCheckCircle },
{ name: "No Usage Limits", icon: faInfinity },
{ name: "Advanced Support", icon: faHeadset },
{ name: "Share Features", icon: faShareFromSquare },
{
name: "Dedicated Hardware",
icon: faServer,
},
{ name: "Custom Regions", icon: faGlobe },
]}
{...config?.[RivetEe.ee.billing.Plan.Studio]}
/>
<BillingPlanCard
title="Enterprise"
price="Custom"
features={[
{
name: "Unlimited Projects",
icon: faInfinity,
},
{ name: "Everything in Team", icon: faCheckCircle },
{
name: "Priority Support",
icon: faHeadset,
},
{
name: "99.99% SLA",
name: "SLA",
icon: faBadgeCheck,
},
{ name: "No Usage Limits", icon: faInfinity },
{
name: "OIDC SSO Provider",
icon: faLockA,
},
{
name: "Dedicated Hardware",
icon: faComputerClassic,
name: "On-Perm Deployment",
icon: faRocketLaunch,
},
{
name: "Custom Storage Reads, Writes and Stored Data",
icon: faDatabase,
},

{
name: "Custom Log Retention",
icon: faClock,
},
]}
type="custom"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ function ProjectBuildLatestButton({
);
}

return <Icon icon={faCheckCircle} className="fill-primary" />;
return <Icon icon={faCheckCircle} className="fill-primary text-primary" />;
}

export const Route = createFileRoute(
Expand Down
Loading