Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pricing update #660

Merged
merged 6 commits into from
Aug 30, 2024
Merged
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
90 changes: 46 additions & 44 deletions app/components/AccountPlan/AccountPlan.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@ import {
import { LuCheck } from "react-icons/lu"
import { PayPlanType } from "~/models/portal/sdk"

// TODO_TECHDEBT: Remove all references to PayAsYouGoV0 and FreetierV0` after its live
type AccountPlanProps = {
fredteumer marked this conversation as resolved.
Show resolved Hide resolved
type: PayPlanType.PayAsYouGoV0 | PayPlanType.FreetierV0 | PayPlanType.Enterprise
type:
| PayPlanType.PayAsYouGoV0
| PayPlanType.FreetierV0
| PayPlanType.Enterprise
| PayPlanType.PlanUnlimited
| PayPlanType.PlanFree
onContinue?: () => void
disableFree?: boolean
}

/*
const AutoScaleList = () => {
return (
<List center icon={<LuCheck size="18px" />} size="sm" spacing="xl">
<List.Item>100,000 relays free per day</List.Item>
<List.Item>Auto-Scale at $7.456 / additional million</List.Item>
<List.Item>No throughput limit</List.Item>
{/*<List.Item>5 Applications</List.Item>*/}
{/*<List.Item>10 Team Members</List.Item>*/}
<List.Item>Direct Customer support</List.Item>
<List.Item>Access all supported chains</List.Item>
<List.Item>Global region support</List.Item>
Expand All @@ -40,67 +44,71 @@ const EnterpriseList = () => {
<List.Item>Custom relays per day</List.Item>
<List.Item>Custom volume plans</List.Item>
<List.Item>No throughput limit</List.Item>
{/*<List.Item>5 Applications</List.Item>*/}
{/*<List.Item>10 Team Members</List.Item>*/}
<List.Item>Direct Customer support</List.Item>
<List.Item>Access all supported chains</List.Item>
<List.Item>Global region support</List.Item>
<List.Item>ETH Trace supported</List.Item>
</List>
)
}
*/
const UnlimitedList = () => {
return (
<List center icon={<LuCheck size="18px" />} size="sm" spacing="xl">
<List.Item>Unlimited relays per month</List.Item>
<List.Item>First 100,000 relays per month free</List.Item>
<List.Item>No throughput limit</List.Item>
<List.Item>Community Discord support</List.Item>
<List.Item>Access all supported chains</List.Item>
</List>
)
}

const FreeList = () => (
<List center icon={<LuCheck size="18px" />} size="sm" spacing="xl">
<List.Item>100,000 relays free per day</List.Item>
<List.Item>Cap at 100,000 Relays, zero overages</List.Item>
<List.Item>30 request/sec throughput limit</List.Item>
{/*<List.Item>2 Applications</List.Item>*/}
{/*<List.Item>2 Team Members</List.Item>*/}
<List.Item>Community Discord support</List.Item>
<List.Item>Access all supported chains</List.Item>
<List.Item>Global region support</List.Item>
<List.Item>ETH Trace supported</List.Item>
</List>
)
const FreeList = () => {
return (
<List center icon={<LuCheck size="18px" />} size="sm" spacing="xl">
<List.Item>100,000 relays free per month</List.Item>
<List.Item>Cap at 100,000 Relays, zero overages</List.Item>
<List.Item>30 request/sec throughput limit</List.Item>
<List.Item>Community Discord support</List.Item>
<List.Item>Access all supported chains</List.Item>
</List>
)
}

export const AccountPlan = ({
type,
onContinue,
disableFree = false,
}: AccountPlanProps) => {
const isFree = type === PayPlanType.FreetierV0
const isPAYG = type === PayPlanType.PayAsYouGoV0
const isEnterprise = type === PayPlanType.Enterprise
const isUnlimited = type === PayPlanType.PlanUnlimited
const isFree = type === PayPlanType.PlanFree

return (
<Card
withBorder
radius="md"
shadow="sm"
style={(theme: MantineTheme) => ({
borderColor: isPAYG ? theme.colors.green[7] : "var(--app-shell-border-color)",
borderColor: isUnlimited
? theme.colors.green[7]
: "var(--app-shell-border-color)",
})}
>
<Stack align="center" gap="xl" mb="xl">
<Badge color="gray" variant="outline">
{isFree && "Builder"}
{isPAYG && "Pay as you go"}
{isEnterprise && "Custom"}
{isFree && "Free"}
{isUnlimited && "Unlimited"}
</Badge>
<Title order={3}>
{isFree && "Starter"}
{isPAYG && "Auto-Scale"}
{isEnterprise && "Enterprise"}
{isFree && "Free"}
{isUnlimited && "Unlimited"}
</Title>
</Stack>
<Text py="lg" ta="center">
{isFree &&
"For developers looking to get started reading and writing data from any integrated chains."}
{isPAYG &&
"For projects needing to scale, pay only for the RPC requests above the free threshold."}
{isEnterprise &&
"Drive innovation and partner with the top decentralized infrastructure in all web3."}
"Enjoy 100,000 free relays a month with Grove on the Unstoppable Pocket Network."}
{isUnlimited && "Unlimited relays with Grove on the Unstoppable Pocket Network."}
</Text>

{isFree && (
Expand All @@ -112,24 +120,18 @@ export const AccountPlan = ({
variant={disableFree ? "default" : "outline"}
onClick={onContinue}
>
{disableFree ? "Current plan" : "Continue with Starter"}
{disableFree ? "Current plan" : "Continue with Free"}
</Button>
)}
{isPAYG && (
{isUnlimited && (
<Button fullWidth radius="xl" onClick={onContinue}>
Continue with Auto-Scale
</Button>
)}
{isEnterprise && (
<Button fullWidth color="gray" radius="xl" variant="outline" onClick={onContinue}>
Talk to Sales
Continue with Unlimited
</Button>
)}

<Box mt="md">
{isFree && <FreeList />}
{isPAYG && <AutoScaleList />}
{isEnterprise && <EnterpriseList />}
{isUnlimited && <UnlimitedList />}
</Box>
</Card>
)
Expand Down
8 changes: 4 additions & 4 deletions app/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ const getStaticRoutes = (
activeAccount: Account,
userRole: RoleName,
): SidebarNavRoute[] => {
const isStarterAccount = activeAccount?.planType === PayPlanType.FreetierV0
const isFreeAccount = activeAccount?.planType === PayPlanType.PlanFree
return [
...(isStarterAccount && userRole !== RoleName.Member
...(isFreeAccount && userRole !== RoleName.Member
? [
{
to: `/account/${activeAccount?.id}/upgrade`,
label: "Upgrade to Auto-Scale",
label: "Upgrade to Unlimited",
end: true,
},
]
Expand All @@ -51,7 +51,7 @@ const getStaticRoutes = (
label: "Sandbox",
end: true,
},
...(!isStarterAccount && userRole !== RoleName.Member
...(!isFreeAccount && userRole !== RoleName.Member
? [
{
to: `/account/${activeAccount?.id}/billing`,
Expand Down
1 change: 1 addition & 0 deletions app/models/portal/portal.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ export const accountMockData: Account = {
name: "Staging",
planType: PayPlanType.FreetierV0,
enterpriseLimit: 0,
monthlyUserLimit: 0,
notifications: [
{
notificationType: NotificationType.Email,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { SimpleGrid, Stack, Text, Title } from "@mantine/core"
import { useNavigate } from "@remix-run/react"
import React from "react"
import { AccountPlan } from "~/components/AccountPlan"
import { Account, PayPlanType, RoleName } from "~/models/portal/sdk"
import FreePlanLimitCard from "~/routes/account.$accountId.settings.plan/components/FreePlanLimitCard"
import { AnalyticActions, AnalyticCategories, trackEvent } from "~/utils/analytics"
import { getPlanName } from "~/utils/planUtils"

type FreeAccountPlanProps = {
account: Account
userRole: RoleName
}

const FreeAccountPlan = ({ account, userRole }: FreeAccountPlanProps) => {
const navigate = useNavigate()

return userRole === "MEMBER" ? (
<Stack mt={"xl"}>
<FreePlanLimitCard account={account} />
</Stack>
) : (
<Stack align="center" mt={"xl"}>
<Stack gap="xs" ta="center">
<Title order={3}>Upgrade your plan</Title>
<Text>
Your current plan is {getPlanName(account.planType)}. <br /> Upgrade now to
Unlimited.
</Text>
</Stack>
<SimpleGrid cols={{ base: 1, lg: 3 }}>
<AccountPlan disableFree type={PayPlanType.PlanFree} />
<AccountPlan
type={PayPlanType.PlanUnlimited}
onContinue={() => {
trackEvent({
category: AnalyticCategories.account,
action: AnalyticActions.account_plan_upgrade,
label: account.id,
})
navigate(`/api/stripe/checkout-session?account-id=${account.id}`)
}}
/>
<AccountPlan
type={PayPlanType.Enterprise}
onContinue={() => {
trackEvent({
category: AnalyticCategories.account,
action: AnalyticActions.account_plan_enterprise,
label: account.id,
})
window.open("https://www.grove.city/enterprise", "_blank", "noreferrer")
}}
/>
</SimpleGrid>
</Stack>
)
}

export default FreeAccountPlan
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import FreeAccountPlan from "./FreeAccountPlan"
export * from "./FreeAccountPlan"
export default FreeAccountPlan
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Divider, Group, Text, Stack } from "@mantine/core"
import React from "react"
import { TitledCard } from "~/components/TitledCard"
import { Account } from "~/models/portal/sdk"
import { getPlanName } from "~/utils/planUtils"

type FreePlanLimitCardProps = {
account: Account
}

export const FreePlanLimitCard = ({ account }: FreePlanLimitCardProps) => {
const cardItems = [
{
label: "Plan Type",
value: getPlanName(account.planType),
},
// {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we want 100,000 here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is purely cosmetic -- im going to leave this out for now

// label: "Daily Limit",
// value: account.integrations.dailyLimit,
// },
]

return (
<TitledCard header={() => <Text fw={600}>Current plan</Text>}>
<Stack px={20} py={10}>
{cardItems.map(({ label, value }, index) => (
<React.Fragment key={`${label}-${index}`}>
<Group justify="space-between" p={12}>
<Text>{label}</Text> <Text>{value}</Text>
</Group>
{index !== cardItems.length - 1 && <Divider />}
</React.Fragment>
))}
</Stack>
</TitledCard>
)
}

export default FreePlanLimitCard
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import FreePlanLimitCard from "./FreePlanLimitCard"
export * from "./FreePlanLimitCard"
export default FreePlanLimitCard
Loading
Loading