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

feat: update dev tier pricing #1128

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
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
76 changes: 35 additions & 41 deletions src/components/Packaging/tiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,58 +47,42 @@ type Segment = {
const SEGMENTS: Segment[] = [
{
name: 'Developers',
tiers: ['Free', 'Premium'],
color: '#52C7EA',
tiers: ['Developer'],
color: '#CDD9E7',
expanded: false,
text: 'The Developer editions of Ockam are intended to be used by individual developers, that are working on hobby projects, and not by companies. Support is via our community in Discord and GitHub, and does not come with an SLA. If you are using Portals for Mac you will need a developer edition license to use the application.',
text: 'The Developer edition of Ockam is intended to be used by individual developers, that are working on hobby projects, and not by companies. Support is via our community in Discord and GitHub, and does not come with an SLA. If you are using Portals for Mac you will need a developer edition license to use the application.',
},
{
name: 'Companies',
tiers: ['Bronze', 'Silver', 'Gold', 'Platinum'],
color: '#3AC6A3',
color: '#B7FDD7',
expanded: true,
text: "Ockam's Company Editions are built for production workloads, with direct support from the Ockam team, and can elastically scale to your needs. This product is purchased through your cloud marketplace vendor, so you can start building today with your 14 day free trial.",
},
{
name: 'Enterprises',
tiers: ['Enterprise', 'Business Critical'],
color: '#744D95',
color: '#B5EEFF',
expanded: false,
text: 'Ockam is offered in a bring-your-own-cloud (BYOC) Enterprise Edition for companies that are committed to running software entirely within their own network boundaries. These plans are highly customizable. Please contact Ockam’s sales team for a technical consultation.',
},
];
const TIERS: Tier[] = [
{
name: 'Free',
name: 'Developer',
text: 'The Tools for Builders',
price: 0,
price_interval: 'mo',
cta: {
text: 'Get started →',
url: '/get-started',
},
marketplaces: {
aws: {
link: 'https://aws.amazon.com/marketplace/pp/prodview-m3url7jixicii',
},
},
},

{
name: 'Premium',
text: 'The Tools for Builders',
price: 5,
price: 70,
price_interval: 'mo',
cta: {
text: 'Start 14-day trial →',
url: '/get-started',
},
marketplaceOnly: true,
marketplaces: {
aws: {
link: 'https://aws.amazon.com/marketplace/pp/prodview-m3url7jixicii',
},
},
sponsorship: true,
},

{
Expand Down Expand Up @@ -230,7 +214,7 @@ const FEATURES: Feature[] = [
tiers: ['Bronze', 'Silver', 'Gold', 'Platinum', 'Enterprise', 'Business Critical'],
onCard: true,
},
{ name: 'Pay-as-you-go', tiers: ['Free', 'Premium', 'Bronze', 'Silver', 'Gold'], onCard: true },
{ name: 'Pay-as-you-go', tiers: ['Developer', 'Bronze', 'Silver', 'Gold'], onCard: true },
{ name: 'Bring Your Own Cloud (BYOC) Relays', tiers: ['Business Critical'], onCard: true },
{
name: 'Bring Your Own Cloud (BYOC) Credential Authorities',
Expand Down Expand Up @@ -267,7 +251,7 @@ const FEATURES: Feature[] = [
// { name: 'Long-term contracts', tiers: ['Gold', 'Business Critical'], onCard: true },
// { name: 'Customized terms', tiers: ['Platinum', 'Enterprise', 'Business Critical'] },

{ name: 'Community-based support', tiers: ['Free', 'Premium'], onCard: true },
{ name: 'Community-based support', tiers: ['Developer'], onCard: true },
{ name: 'Dedicated nodes', tiers: ['Silver'], onCard: true },
{
name: 'Throughput optimized nodes',
Expand Down Expand Up @@ -322,13 +306,12 @@ const FEATURES: Feature[] = [
tiers: ['Bronze', 'Silver', 'Gold', 'Platinum', 'Enterprise', 'Business Critical'],
hasLimits: true,
},
{ name: 'Data transfer cap', tiers: ['Free', 'Premium'], hasLimits: true },
{ name: 'Data transfer cap', tiers: ['Developer'], hasLimits: true },
];

const LIMITS: { [id: string]: { [id: string]: string } } = {
Projects: {
Free: '1',
Premium: '1',
Developer: '1',
Bronze: '1',
Silver: '3',
Gold: '10',
Expand All @@ -337,8 +320,7 @@ const LIMITS: { [id: string]: { [id: string]: string } } = {
'Business Critical': 'Unlimited',
},
'Secure Channels': {
Free: '1',
Premium: '5',
Developer: '1',
Bronze: '10',
Silver: 'Unlimited',
Gold: 'Unlimited',
Expand All @@ -355,24 +337,21 @@ const LIMITS: { [id: string]: { [id: string]: string } } = {
},

'Project authority nodes': {
Free: 'Up to 1',
Premium: 'Up to 1',
Developer: 'Up to 1',
Bronze: 'Unlimited',
Silver: 'Unlimited',
Gold: 'Unlimited',
'Business Critical': 'Unlimited',
},
'Credential authorities': {
Free: 'Up to 1',
Premium: 'Up to 1',
Developer: 'Up to 1',
Bronze: 'Unlimited',
Silver: 'Unlimited',
Gold: 'Unlimited',
'Business Critical': 'Unlimited',
},
'Data transfer cap': {
Free: '1GB/day',
Premium: '1GB/day',
Developer: '1GB/day',
},
'Data transfer': {
Bronze: '$0.10/GB',
Expand All @@ -384,17 +363,25 @@ const LIMITS: { [id: string]: { [id: string]: string } } = {
},
};

const segmentForTier = (tier: Tier) => {
return SEGMENTS.find((s) => s.tiers.includes(tier.name));
};

const darken = (color: string): string | undefined =>
chroma(color).darken(0.75).saturate(0.75).hex();

const lighten = (color: string): string | undefined =>
chroma(color).brighten(2.5).desaturate(0.4).hex();
chroma(color).brighten(1).desaturate(0.2).hex();

const gentlyLighten = (color: string): string | undefined =>
chroma(color).brighten(1.5).desaturate(0.75).hex();
chroma(color).brighten(0.5).desaturate(0.3).hex();

const tierColor = (tier: Tier): string => segmentForTier(tier)!.color;

const tierColor = (tier: Tier): string | undefined =>
SEGMENTS.find((s) => s.tiers.includes(tier.name))?.color;
const peerTiers = (tier: Tier) => {
const segment = segmentForTier(tier);
if (segment) return tiersForSegment(segment.name);
};

const tierColorLight = (tier: Tier): string | undefined => lighten(tierColor(tier) || 'white');

Expand All @@ -409,6 +396,12 @@ const tiersForSegment = (segmentName: string): Tier[] => {
return [];
};

const isLastTierInSegment = (tier: Tier): boolean => {
const tiers = peerTiers(tier);
if (!tiers) return false;
return tiers!.indexOf(tier) === tiers!.length - 1;
};

const featuresForTier = (tierName: string, cardOnly: boolean = true): Feature[] =>
FEATURES.filter(
(f) => f.tiers.includes(tierName) && (f.onCard === cardOnly || cardOnly === false),
Expand Down Expand Up @@ -442,4 +435,5 @@ export {
tiersForSegment,
featuresForTier,
hasFeature,
isLastTierInSegment,
};
4 changes: 2 additions & 2 deletions src/pages/pricing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ const PricingPage: NextPageWithLayout<Props> = () => (
</Flex>
<DescriptionText>
<Box as="span" color="brand.500">
The Developer editions
The Developer edition
</Box>{' '}
of Ockam are intended to be used by individual developers, that are working on hobby
of Ockam is intended to be used by individual developers, that are working on hobby
projects, and not by companies. Support is via our community in Discord and GitHub,
and does not come with an SLA. If you are using Portals for Mac you will need a
developer edition license to use the application with your 14 day free trial.
Expand Down
42 changes: 3 additions & 39 deletions src/theme/components/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,15 @@ const Table = defineMultiStyleConfig({

// Developers Cell
'&:nth-child(2)': {
width: '12.75rem',
background: '#CDD9E7',
// width: '12.75rem',
},
// Companies Cell
'&:nth-child(3)': {
width: '25.25rem',
background: '#B7FDD7',
// width: '25.25rem',
},
// Enterprises Cell
'&:nth-child(4)': {
width: '12.75rem',
background: '#B5EEFF',
// width: '12.75rem',
},
},
},
Expand All @@ -63,24 +60,6 @@ const Table = defineMultiStyleConfig({
borderBottom: '1px solid',
borderColor: 'gray.100',
whiteSpace: 'break-spaces',
'&:nth-child(2),&:nth-child(6)': {
borderRight: '1px solid',
borderColor: 'gray.100',
},
// Developers Cells
'&:nth-child(1), &:nth-child(2)': {
background: '#E7EEF5',
},

// Companies Cells
'&:nth-child(3), &:nth-child(4), &:nth-child(5), &:nth-child(6)': {
background: '#DBFEEB',
},

// Enterprises Cells
'&:nth-child(7), &:nth-child(8)': {
background: '#DAF7FF',
},
},
},
},
Expand Down Expand Up @@ -109,21 +88,6 @@ const Table = defineMultiStyleConfig({
borderRight: '1px solid',
borderColor: 'gray.100',
},

// Developers Cells
'&:nth-child(2), &:nth-child(3)': {
background: '#FCFEFF',
},

// Companies Cells
'&:nth-child(4), &:nth-child(5), &:nth-child(6), &:nth-child(7)': {
background: '#F7FFFD',
},

// Enterprises Cells
'&:nth-child(8), &:nth-child(9)': {
background: '#F4FDFF',
},
},
},
},
Expand Down
39 changes: 34 additions & 5 deletions src/views/pricing/components/PricingTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import { Table, Thead, Tbody, Tr, Th, Td, Box } from '@chakra-ui/react';
import {
Feature,
FEATURES,
gentlyLighten,
hasFeature,
isLastTierInSegment,
SEGMENTS,
Tier,
tierColor,
tierColorLight,
tierLimit,
tiersForSegment,
} from '@root/components/Packaging/tiers';
Expand All @@ -17,25 +21,44 @@ const CheckIcon = (): ReactElement => <Box as={BaseCheckIcon} display="inline-bl

const tiers: Tier[] = SEGMENTS.map((segment) => tiersForSegment(segment.name)).flat();

const columnEdgeStyle = '1px solid #EFF1F1';

const PricingTable = (): ReactElement => {
const showFeatureState = (tier: Tier, feature: Feature): JSX.Element => {
const key = `tier-feature-${tier.name}-${feature.name}`;
if (hasFeature(tier, feature)) {
const limit = tierLimit(tier, feature);
if (limit) {
return (
<Td whiteSpace="nowrap" key={key}>
<Td
whiteSpace="nowrap"
key={key}
backgroundColor={tierColorLight(tier)}
style={{ borderRight: isLastTierInSegment(tier) ? columnEdgeStyle : 'none' }}
>
{limit}
</Td>
);
}
return (
<Td key={key}>
<Td
key={key}
backgroundColor={tierColorLight(tier)}
style={{ borderRight: isLastTierInSegment(tier) ? columnEdgeStyle : 'none' }}
>
<CheckIcon />
</Td>
);
}
return <Td key={key}>&ndash;</Td>;
return (
<Td
key={key}
backgroundColor={tierColorLight(tier)}
style={{ borderRight: isLastTierInSegment(tier) ? columnEdgeStyle : 'none' }}
>
&ndash;
</Td>
);
};

return (
Expand All @@ -51,14 +74,20 @@ const PricingTable = (): ReactElement => {
Plan Comparison
</Th>
{SEGMENTS.map((segment) => (
<Th colSpan={segment.tiers.length} key={`th-${segment.name}`}>
<Th
colSpan={segment.tiers.length}
key={`th-${segment.name}`}
backgroundColor={segment.color}
>
{segment.name}
</Th>
))}
</Tr>
<Tr>
{tiers.map((tier) => (
<Th key={`tier-${tier.name}`}>{tier.name}</Th>
<Th key={`tier-${tier.name}`} backgroundColor={gentlyLighten(tierColor(tier))}>
{tier.name}
</Th>
))}
</Tr>
</Thead>
Expand Down
Loading