Skip to content

Commit 52eef4d

Browse files
committed
New pricing
1 parent 03ca5b9 commit 52eef4d

File tree

6 files changed

+98
-31
lines changed

6 files changed

+98
-31
lines changed

landing/src/components/sections/CTAButtons.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
activePaidPlans,
3+
activePlans,
34
constants,
45
freeTrialDays,
56
} from '@brunolemos/devhub-core'
@@ -88,7 +89,7 @@ export default function CTAButtons(props: CTAButtonsProps) {
8889
</Button>
8990
)}
9091

91-
{!!(freeTrialDays && activePaidPlans.some(plan => !plan.amount)) && (
92+
{!!(freeTrialDays && activePlans.some(plan => !plan.amount)) && (
9293
<Button
9394
type="neutral"
9495
href="/download?autostart"

landing/src/components/sections/features/FeaturesBlock.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export default function FeaturesBlock(_props: FeaturesBlockProps) {
7777
alt: 'DevHub - Label filter',
7878
}}
7979
title="Filter by labels and many other filters"
80-
subtitle="All columns support a common set of filters, like Label, Issue Status, Bot, Text, etc. The Issues & Pull Requests columns are special: they give you all the power of GitHub Advanced Search on your hands (filter by assignee, number of comments, ...)"
80+
subtitle="All columns support a common set of filters, like Bot, Label, Issue Status, Text, etc. The Issues & Pull Requests columns are special: they give you all the power of GitHub Advanced Search on your hands (filter by assignee, number of comments, ...)"
8181
/>
8282

8383
<div className="pb-16 md:pb-32" />

landing/src/components/sections/header/Header.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { activePaidPlans, freeTrialDays } from '@brunolemos/devhub-core'
1+
import {
2+
activePaidPlans,
3+
freeTrialDays,
4+
activePlans,
5+
} from '@brunolemos/devhub-core'
26
import classNames from 'classnames'
37
import Link from 'next/link'
48

@@ -92,7 +96,7 @@ export default function Header(props: HeaderProps) {
9296
</HeaderLink> */}
9397

9498
{!!(
95-
(freeTrialDays && activePaidPlans.some(plan => !plan.amount)) ||
99+
(freeTrialDays && activePlans.some(plan => !plan.amount)) ||
96100
(authData &&
97101
authData.appToken &&
98102
(freeTrialDays || (authData.plan && authData.plan.amount)))

landing/src/components/sections/pricing/PricingPlanBlock.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
9696
}${_roundedPriceLabelWithInterval}`
9797
}
9898

99-
if (!plan.interval) {
99+
if (!plan.interval && plan.amount) {
100100
footerText =
101101
(footerText ? `${footerText}\n` : footerText) +
102102
'One-time payment (no subscription)'
@@ -106,11 +106,7 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
106106
<section
107107
className={classNames(
108108
'pricing-plan flex flex-col flex-shrink-0',
109-
totalNumberOfVisiblePlans === 1
110-
? 'w-full lg:w-84'
111-
: totalNumberOfVisiblePlans && totalNumberOfVisiblePlans <= 3
112-
? 'w-72'
113-
: 'w-64',
109+
totalNumberOfVisiblePlans === 1 ? 'w-full lg:w-84' : 'w-72',
114110
)}
115111
>
116112
<div
@@ -187,7 +183,7 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
187183
footerText ||
188184
(totalNumberOfVisiblePlans && totalNumberOfVisiblePlans > 1)
189185
) && (
190-
<div className="mb-2 text-sm text-muted-65 italic">
186+
<div className="mb-2 text-sm text-muted-65 italic whitespace-pre-line">
191187
&nbsp;{footerText}&nbsp;
192188
</div>
193189
)}

landing/src/components/sections/subscribe/SubscribeForm.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ export const SubscribeForm = injectStripe<SubscribeFormProps>(
108108

109109
const minimumQuantity = showQuantityForm
110110
? Math.max(
111-
quantityStep > 1 ? quantityStep : 1,
111+
quantityStep > 1
112+
? quantityStep
113+
: plan.type === 'team' && plan.paddleProductId
114+
? 2
115+
: 1,
112116
Math.ceil(users.length / quantityStep) * quantityStep,
113117
)
114118
: 1
@@ -802,7 +806,9 @@ export const SubscribeForm = injectStripe<SubscribeFormProps>(
802806
!plan.stripeIds.length &&
803807
plan.paddleProductId &&
804808
plan.description,
805-
].filter(Boolean).join('\n')}
809+
]
810+
.filter(Boolean)
811+
.join('\n')}
806812
</p>
807813
)}
808814

packages/core/src/utils/plans.ts

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,29 @@ import { Plan } from '../types'
22
import * as constants from './constants'
33

44
export type ActivePlanID =
5-
| '5de54fc1d6c4fded37775e71'
6-
| '5de54fc29188ad514567ddb2'
5+
| 'free'
6+
| '5ded8bd7fcf793f771a0264c'
7+
| '5ded8e946bcd42efb0e6094a'
78
| '5de54fc278c2188b4ec17fc7'
89
| '5de54fc30cd5acc31a86e884'
910
| '5dd82d16eb2b11106f941f8d'
11+
| '5de552b6dde41be55811ed15'
1012

1113
export type InactivePlanID =
12-
| 'free'
1314
| '5d4b8e85d123d1d770d93825'
1415
| '5d4b8e44ab1ba20b9ef4a1ba'
1516
| '5d4b8e4de70bd8c61c13a6a9'
1617
| '5db0d55e138a98f7008a0e53'
1718
| '5dba30bd0621102b5cd0bc44'
1819
| '5dba30bf7deee78cb184291d'
1920
| '5dc89f56bae8d4ae5245423e'
20-
| '5dd44e11b2726bb02d540b5e'
2121
| '5db0d37ce59ab2d3c0bbd611'
2222
| '5db0d5fb957ac4e5ed7bbb05'
2323
| '5dd4618db3ebb145268eba7c'
2424
| '5dd467e799537b2378df8eea'
25-
| '5de552b6dde41be55811ed15'
25+
| '5de54fc1d6c4fded37775e71'
26+
| '5de54fc29188ad514567ddb2'
27+
| '5dd44e11b2726bb02d540b5e'
2628

2729
export type PlanID = ActivePlanID | InactivePlanID
2830

@@ -44,7 +46,7 @@ const _freePlan: Plan & { id: 'free' } = {
4446

4547
cannonicalId: 'free',
4648
label: 'Free',
47-
description: '',
49+
description: '\n\n',
4850
amount: 0,
4951
currency: 'usd',
5052
interval: undefined,
@@ -109,7 +111,7 @@ export const allPlansObj: Record<PlanID, Plan> = {
109111
currency: 'usd',
110112
interval: 'month',
111113
intervalCount: 1,
112-
trialPeriodDays: 7,
114+
trialPeriodDays: 0,
113115

114116
featureLabels: [
115117
{ id: 'columnsLimit', label: 'Up to 12 columns', available: true },
@@ -152,7 +154,7 @@ export const allPlansObj: Record<PlanID, Plan> = {
152154
currency: 'usd',
153155
interval: 'month',
154156
intervalCount: 1,
155-
trialPeriodDays: 7,
157+
trialPeriodDays: 0,
156158
featureLabels: [
157159
{
158160
id: 'columnsLimit',
@@ -203,7 +205,7 @@ export const allPlansObj: Record<PlanID, Plan> = {
203205
currency: 'usd',
204206
interval: 'month',
205207
intervalCount: 1,
206-
trialPeriodDays: 7,
208+
trialPeriodDays: 0,
207209
featureLabels: [
208210
{ id: 'columnsLimit', label: 'Up to 20 columns', available: true },
209211
{ id: 'enableFilters', label: 'All filters', available: true },
@@ -408,7 +410,7 @@ export const allPlansObj: Record<PlanID, Plan> = {
408410

409411
cannonicalId: 'yearly',
410412
label: 'Yearly',
411-
description: '',
413+
description: '\n\n',
412414
amount: 9000,
413415
currency: 'usd',
414416
interval: 'year',
@@ -554,7 +556,7 @@ export const allPlansObj: Record<PlanID, Plan> = {
554556
stripeIds: ['plan_GHtLrxHfn3DDkr', 'plan_GHsabiw9GfQH9N'],
555557
paddleProductId: undefined,
556558

557-
banner: '17% OFF',
559+
banner: '30% OFF',
558560

559561
cannonicalId: 'team-monthly',
560562
label: 'Team Monthly',
@@ -584,10 +586,10 @@ export const allPlansObj: Record<PlanID, Plan> = {
584586
id: '5de54fc30cd5acc31a86e884',
585587
type: 'team',
586588

587-
stripeIds: ['plan_GHtMaMxGQtAySy', 'plan_GHsqgnLvYnfu2q'],
589+
stripeIds: ['plan_GKEKN4EG1Rawje', 'plan_GHsqgnLvYnfu2q'],
588590
paddleProductId: undefined,
589591

590-
banner: '38% OFF',
592+
banner: '48% OFF',
591593

592594
cannonicalId: 'team-yearly',
593595
label: 'Team Yearly',
@@ -625,7 +627,7 @@ export const allPlansObj: Record<PlanID, Plan> = {
625627
cannonicalId: 'lifetime-v1',
626628
label: 'Lifetime v1',
627629
description: `Lifetime access from v0.9 to v1.9 \n(current: v${constants.APP_VERSION})`,
628-
amount: 9900,
630+
amount: 14900,
629631
currency: 'usd',
630632
interval: undefined,
631633
intervalCount: 1,
@@ -650,12 +652,12 @@ export const allPlansObj: Record<PlanID, Plan> = {
650652
stripeIds: [],
651653
paddleProductId: 577489,
652654

653-
banner: true,
655+
banner: '33% OFF',
654656

655657
cannonicalId: 'team-lifetime-v1',
656658
label: 'Team Lifetime v1',
657659
description: `Lifetime access from v0.9 to v1.9 \n(current: v${constants.APP_VERSION})`,
658-
amount: 19900,
660+
amount: 9900,
659661
currency: 'usd',
660662
interval: undefined,
661663
intervalCount: 1,
@@ -672,16 +674,74 @@ export const allPlansObj: Record<PlanID, Plan> = {
672674
enablePushNotifications: true,
673675
},
674676
},
677+
678+
'5ded8bd7fcf793f771a0264c': {
679+
id: '5ded8bd7fcf793f771a0264c',
680+
type: 'individual',
681+
682+
stripeIds: ['plan_GKEKNpDiuSZv46', 'plan_GKDvgmdNgDOOso'],
683+
paddleProductId: undefined,
684+
685+
banner: true,
686+
687+
cannonicalId: 'monthly',
688+
label: 'Monthly',
689+
description: '\n\n',
690+
amount: 1200,
691+
currency: 'usd',
692+
interval: 'month',
693+
intervalCount: 1,
694+
trialPeriodDays: 0,
695+
featureLabels: [],
696+
697+
featureFlags: {
698+
columnsLimit: constants.COLUMNS_LIMIT,
699+
enableFilters: true,
700+
enableSync: true,
701+
enablePrivateRepositories: true,
702+
enablePushNotifications: true,
703+
},
704+
},
705+
706+
'5ded8e946bcd42efb0e6094a': {
707+
id: '5ded8e946bcd42efb0e6094a',
708+
type: 'individual',
709+
710+
stripeIds: ['plan_GKELMpfqKbmnQe', 'plan_GKE7HnxNA4f9tN'],
711+
paddleProductId: undefined,
712+
713+
banner: '30% OFF',
714+
715+
cannonicalId: 'yearly',
716+
label: 'Yearly',
717+
description: '\n\n',
718+
amount: 9900,
719+
currency: 'usd',
720+
interval: 'year',
721+
intervalCount: 1,
722+
trialPeriodDays: 0,
723+
featureLabels: [],
724+
725+
featureFlags: {
726+
columnsLimit: constants.COLUMNS_LIMIT,
727+
enableFilters: true,
728+
enableSync: true,
729+
enablePrivateRepositories: true,
730+
enablePushNotifications: true,
731+
},
732+
},
675733
}
676734

677735
export const allPlans = Object.values(allPlansObj)
678736

679737
export const activePlans: Array<Plan & { id: ActivePlanID }> = [
680-
allPlansObj['5de54fc1d6c4fded37775e71'] as Plan & { id: ActivePlanID },
681-
allPlansObj['5de54fc29188ad514567ddb2'] as Plan & { id: ActivePlanID },
738+
freeTrialPlan,
739+
allPlansObj['5ded8bd7fcf793f771a0264c'] as Plan & { id: ActivePlanID },
740+
allPlansObj['5ded8e946bcd42efb0e6094a'] as Plan & { id: ActivePlanID },
682741
allPlansObj['5de54fc278c2188b4ec17fc7'] as Plan & { id: ActivePlanID },
683742
allPlansObj['5de54fc30cd5acc31a86e884'] as Plan & { id: ActivePlanID },
684743
allPlansObj['5dd82d16eb2b11106f941f8d'] as Plan & { id: ActivePlanID },
744+
allPlansObj['5de552b6dde41be55811ed15'] as Plan & { id: ActivePlanID },
685745
]
686746

687747
export const activePaidPlans = activePlans.filter(plan => plan.amount > 0)

0 commit comments

Comments
 (0)