Skip to content

Commit 75b2a46

Browse files
feat: Remove annual option except for existing annual plans
1 parent 20b5921 commit 75b2a46

File tree

28 files changed

+558
-580
lines changed

28 files changed

+558
-580
lines changed

src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.test.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,6 @@ describe('TeamPlanCard', () => {
174174
wrapper,
175175
})
176176

177-
const yearlyPrice = await screen.findByText(/5/)
178-
expect(yearlyPrice).toBeInTheDocument()
179-
180177
const monthlyPrice = await screen.findByText(/6/)
181178
expect(monthlyPrice).toBeInTheDocument()
182179

src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,8 @@ const TeamPlanCard: React.FC = () => {
4747
<div className="flex flex-col gap-2 border-t pt-2 sm:border-0 sm:p-0">
4848
<p className="text-xs font-semibold">Pricing</p>
4949
<div>
50-
<p className="font-semibold">
51-
<span className="text-2xl">${teamPlanYear?.baseUnitPrice}</span>{' '}
52-
per user/month
53-
</p>
5450
<p className="text-ds-gray-senary">
55-
billed annually, or ${teamPlanMonth?.baseUnitPrice} per user
56-
billing monthly
51+
${teamPlanMonth?.baseUnitPrice} per user billing monthly
5752
</p>
5853
</div>
5954
</div>

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/ProPlanDetails/ProPlanDetails.jsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useAvailablePlans } from 'services/account/useAvailablePlans'
55
import { usePlanData } from 'services/account/usePlanData'
66
import BenefitList from 'shared/plan/BenefitList'
77
import ScheduledPlanDetails from 'shared/plan/ScheduledPlanDetails'
8-
import { findProPlans } from 'shared/utils/billing'
8+
import { BillingRate, findProPlans } from 'shared/utils/billing'
99
import { shouldRenderCancelLink } from 'shared/utils/upgradeForm'
1010
import A from 'ui/A'
1111
import Icon from 'ui/Icon'
@@ -22,6 +22,7 @@ function ProPlanDetails() {
2222
const cancelAtPeriodEnd =
2323
accountDetails?.subscriptionDetail?.cancelAtPeriodEnd
2424
const trialStatus = planData?.plan?.trialStatus
25+
const currentPlanBillingRate = planData?.plan?.billingRate
2526

2627
return (
2728
<div className="h-fit border md:w-[280px]">
@@ -30,14 +31,26 @@ function ProPlanDetails() {
3031
<div className="flex flex-col gap-6 p-4">
3132
<div>
3233
<p className="mb-2 text-xs font-semibold">Pricing</p>
33-
<p className="text-xs font-semibold">
34-
<span className="text-2xl">${proPlanYear?.baseUnitPrice}</span> per
35-
user/month
36-
</p>
37-
<p className="text-xs text-ds-gray-senary">
38-
billed annually, or ${proPlanMonth?.baseUnitPrice} for monthly
39-
billing
40-
</p>
34+
{currentPlanBillingRate === BillingRate.ANNUALLY ? (
35+
<>
36+
<p className="text-xs font-semibold">
37+
<span className="text-2xl">${proPlanYear?.baseUnitPrice}</span>{' '}
38+
per user/month
39+
</p>
40+
<p className="text-xs text-ds-gray-senary">
41+
billed annually, or ${proPlanMonth?.baseUnitPrice} for monthly
42+
billing
43+
</p>
44+
</>
45+
) : (
46+
<>
47+
<p className="text-xs font-semibold">
48+
<span className="text-2xl">${proPlanMonth?.baseUnitPrice}</span>{' '}
49+
per user/month
50+
</p>
51+
<p className="text-xs text-ds-gray-senary">billed monthly</p>
52+
</>
53+
)}
4154
</div>
4255
<div>
4356
<p className="mb-2 text-xs font-semibold">Includes</p>

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/ProPlanDetails/ProPlanDetails.test.jsx

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,14 @@ describe('ProPlanDetails', () => {
188188
hasScheduledPhase = false,
189189
hasUserCanceledAtPeriodEnd = false,
190190
isProPlan = false,
191+
billingRate = BillingRate.ANNUALLY,
191192
} = {
192193
isOngoingTrial: false,
193194
isSentryPlan: false,
194195
hasScheduledPhase: false,
195196
hasUserCanceledAtPeriodEnd: false,
196197
isProPlan: false,
198+
billingRate: BillingRate.ANNUALLY,
197199
}
198200
) {
199201
server.use(
@@ -204,6 +206,7 @@ describe('ProPlanDetails', () => {
204206
hasPrivateRepos: true,
205207
plan: {
206208
...mockPlanData,
209+
billingRate,
207210
isFreePlan: !isProPlan && !isSentryPlan,
208211
isTeamPlan: false,
209212
trialStatus: isOngoingTrial
@@ -289,24 +292,46 @@ describe('ProPlanDetails', () => {
289292
expect(benefitsList).toBeInTheDocument()
290293
})
291294

292-
it('shows price', async () => {
293-
setup({ isSentryPlan: false })
295+
describe('when current plan billing rate is annual', () => {
296+
it('shows annual price', async () => {
297+
setup({ isSentryPlan: false, billingRate: BillingRate.ANNUALLY })
294298

295-
render(<ProPlanDetails />, { wrapper: wrapper() })
299+
render(<ProPlanDetails />, { wrapper: wrapper() })
300+
301+
const price = await screen.findByText(/\$10/)
302+
expect(price).toBeInTheDocument()
303+
})
296304

297-
const price = await screen.findByText(/\$10/)
298-
expect(price).toBeInTheDocument()
305+
it('shows pricing disclaimer with monthly option', async () => {
306+
setup({ isSentryPlan: false, billingRate: BillingRate.ANNUALLY })
307+
308+
render(<ProPlanDetails />, { wrapper: wrapper() })
309+
310+
const disclaimer = await screen.findByText(
311+
/billed annually, or \$12 for monthly billing/i
312+
)
313+
expect(disclaimer).toBeInTheDocument()
314+
})
299315
})
300316

301-
it('shows pricing disclaimer', async () => {
302-
setup({ isSentryPlan: false })
317+
describe('when current plan billing rate is monthly', () => {
318+
it('shows monthly price', async () => {
319+
setup({ isSentryPlan: false, billingRate: BillingRate.MONTHLY })
303320

304-
render(<ProPlanDetails />, { wrapper: wrapper() })
321+
render(<ProPlanDetails />, { wrapper: wrapper() })
322+
323+
const price = await screen.findByText(/\$12/)
324+
expect(price).toBeInTheDocument()
325+
})
305326

306-
const disclaimer = await screen.findByText(
307-
/billed annually, or \$12 for monthly billing/i
308-
)
309-
expect(disclaimer).toBeInTheDocument()
327+
it('shows billed monthly disclaimer', async () => {
328+
setup({ isSentryPlan: false, billingRate: BillingRate.MONTHLY })
329+
330+
render(<ProPlanDetails />, { wrapper: wrapper() })
331+
332+
const disclaimer = await screen.findByText(/billed monthly/i)
333+
expect(disclaimer).toBeInTheDocument()
334+
})
310335
})
311336

312337
it('shows schedule phase when there is one', async () => {

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/SentryPlanDetails/SentryPlanDetails.jsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useAccountDetails } from 'services/account/useAccountDetails'
44
import { useAvailablePlans } from 'services/account/useAvailablePlans'
55
import { usePlanData } from 'services/account/usePlanData'
66
import BenefitList from 'shared/plan/BenefitList'
7-
import { findSentryPlans } from 'shared/utils/billing'
7+
import { BillingRate, findSentryPlans } from 'shared/utils/billing'
88
import { SENTRY_PRICE, shouldRenderCancelLink } from 'shared/utils/upgradeForm'
99
import A from 'ui/A'
1010
import Icon from 'ui/Icon'
@@ -14,11 +14,13 @@ function SentryPlanDetails() {
1414
const { data: accountDetails } = useAccountDetails({ provider, owner })
1515
const { data: planData } = usePlanData({ provider, owner })
1616
const { data: plans } = useAvailablePlans({ provider, owner })
17-
const { sentryPlanYear } = findSentryPlans({ plans })
17+
const { sentryPlanYear, sentryPlanMonth } = findSentryPlans({ plans })
1818

1919
const cancelAtPeriodEnd =
2020
accountDetails?.subscriptionDetail?.cancelAtPeriodEnd
2121
const trialStatus = planData?.plan?.trialStatus
22+
const currentPlanBillingRate = planData?.plan?.billingRate
23+
2224
return (
2325
<div className="h-fit border md:w-[280px]">
2426
<h3 className="p-4 font-semibold">
@@ -28,13 +30,27 @@ function SentryPlanDetails() {
2830
<div className="flex flex-col gap-6 p-4">
2931
<div>
3032
<p className="mb-2 text-xs font-semibold">Pricing</p>
31-
<p className="text-xs font-semibold">
32-
<span className="text-2xl">${SENTRY_PRICE}</span>/month
33-
</p>
34-
<p className="text-xs text-ds-gray-senary">
35-
over 5 users is ${sentryPlanYear?.baseUnitPrice} per user/month,
36-
billed annually
37-
</p>
33+
{currentPlanBillingRate === BillingRate.ANNUALLY ? (
34+
<>
35+
<p className="text-xs font-semibold">
36+
<span className="text-2xl">${SENTRY_PRICE}</span>/month
37+
</p>
38+
<p className="text-xs text-ds-gray-senary">
39+
over 5 users is ${sentryPlanYear?.baseUnitPrice} per user/month,
40+
billed annually
41+
</p>
42+
</>
43+
) : (
44+
<>
45+
<p className="text-xs font-semibold">
46+
<span className="text-2xl">${SENTRY_PRICE}</span>/month
47+
</p>
48+
<p className="text-xs text-ds-gray-senary">
49+
over 5 users is ${sentryPlanMonth?.baseUnitPrice} per
50+
user/month, billed monthly
51+
</p>
52+
</>
53+
)}
3854
</div>
3955
<div>
4056
<p className="mb-2 text-xs font-semibold">Includes</p>

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/SentryPlanDetails/SentryPlanDetails.test.jsx

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,12 @@ describe('SentryPlanDetails', () => {
183183
isOngoingTrial = false,
184184
hasUserCanceledAtPeriodEnd = false,
185185
isProPlan = false,
186+
billingRate = BillingRate.ANNUALLY,
186187
} = {
187188
isOngoingTrial: false,
188189
hasUserCanceledAtPeriodEnd: false,
189190
isProPlan: false,
191+
billingRate: BillingRate.ANNUALLY,
190192
}
191193
) {
192194
server.use(
@@ -197,6 +199,7 @@ describe('SentryPlanDetails', () => {
197199
hasPrivateRepos: true,
198200
plan: {
199201
...mockPlanData,
202+
billingRate,
200203
isFreePlan: !isProPlan,
201204
isTeamPlan: false,
202205
trialStatus: isOngoingTrial
@@ -258,20 +261,34 @@ describe('SentryPlanDetails', () => {
258261
expect(benefitsList).toBeInTheDocument()
259262
})
260263

261-
it('renders pricing disclaimer', async () => {
262-
setup()
264+
describe('when current plan billing rate is annual', () => {
265+
it('renders pricing disclaimer with annual billing', async () => {
266+
setup({ billingRate: BillingRate.ANNUALLY })
263267

264-
render(<SentryPlanDetails />, { wrapper: wrapper() })
268+
render(<SentryPlanDetails />, { wrapper: wrapper() })
269+
270+
const disclaimer = await screen.findByText(
271+
/over 5 users is \$10 per user\/month, billed annually/i
272+
)
273+
expect(disclaimer).toBeInTheDocument()
274+
})
275+
})
276+
277+
describe('when current plan billing rate is monthly', () => {
278+
it('renders pricing disclaimer with monthly billing', async () => {
279+
setup({ billingRate: BillingRate.MONTHLY })
265280

266-
const disclaimer = await screen.findByText(
267-
/over 5 users is \$10 per user\/month, billed annually/i
268-
)
269-
expect(disclaimer).toBeInTheDocument()
281+
render(<SentryPlanDetails />, { wrapper: wrapper() })
282+
283+
const disclaimer = await screen.findByText(
284+
/over 5 users is \$12 per user\/month, billed monthly/i
285+
)
286+
expect(disclaimer).toBeInTheDocument()
287+
})
270288
})
271289

272290
it('renders cancellation link when it is valid', async () => {
273291
setup({
274-
isSentryPlan: false,
275292
hasUserCanceledAtPeriodEnd: false,
276293
isOngoingTrial: false,
277294
isProPlan: true,
@@ -286,7 +303,6 @@ describe('SentryPlanDetails', () => {
286303

287304
it('should not render cancellation link when user is ongoing trial', () => {
288305
setup({
289-
isSentryPlan: false,
290306
isOngoingTrial: true,
291307
})
292308

@@ -298,7 +314,6 @@ describe('SentryPlanDetails', () => {
298314

299315
it('should not render cancellation link when user has already cancelled', () => {
300316
setup({
301-
isSentryPlan: false,
302317
hasUserCanceledAtPeriodEnd: true,
303318
})
304319

@@ -310,7 +325,6 @@ describe('SentryPlanDetails', () => {
310325

311326
it('should not render cancellation link when user is on developers plan', () => {
312327
setup({
313-
isSentryPlan: false,
314328
isOngoingTrial: false,
315329
isProPlan: false,
316330
})

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/TeamPlanDetails/TeamPlanDetails.jsx

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useAvailablePlans } from 'services/account/useAvailablePlans'
55
import { usePlanData } from 'services/account/usePlanData'
66
import BenefitList from 'shared/plan/BenefitList'
77
import ScheduledPlanDetails from 'shared/plan/ScheduledPlanDetails'
8-
import { findTeamPlans } from 'shared/utils/billing'
8+
import { BillingRate, findTeamPlans } from 'shared/utils/billing'
99
import { shouldRenderCancelLink } from 'shared/utils/upgradeForm'
1010
import A from 'ui/A'
1111
import Icon from 'ui/Icon'
@@ -22,6 +22,7 @@ function TeamPlanDetails() {
2222
const cancelAtPeriodEnd =
2323
accountDetails?.subscriptionDetail?.cancelAtPeriodEnd
2424
const trialStatus = planData?.plan?.trialStatus
25+
const currentPlanBillingRate = planData?.plan?.billingRate
2526

2627
return (
2728
<div className="h-fit border md:w-[280px]">
@@ -30,14 +31,28 @@ function TeamPlanDetails() {
3031
<div className="flex flex-col gap-6 p-4">
3132
<div>
3233
<p className="mb-2 text-xs font-semibold">Pricing</p>
33-
<p className="text-xs font-semibold">
34-
<span className="text-2xl">${teamPlanYear?.baseUnitPrice}</span> per
35-
user/month
36-
</p>
37-
<p className="text-xs text-ds-gray-senary">
38-
billed annually, or ${teamPlanMonth?.baseUnitPrice} for monthly
39-
billing
40-
</p>
34+
{currentPlanBillingRate === BillingRate.ANNUALLY ? (
35+
<>
36+
<p className="text-xs font-semibold">
37+
<span className="text-2xl">${teamPlanYear?.baseUnitPrice}</span>{' '}
38+
per user/month
39+
</p>
40+
<p className="text-xs text-ds-gray-senary">
41+
billed annually, or ${teamPlanMonth?.baseUnitPrice} for monthly
42+
billing
43+
</p>
44+
</>
45+
) : (
46+
<>
47+
<p className="text-xs font-semibold">
48+
<span className="text-2xl">
49+
${teamPlanMonth?.baseUnitPrice}
50+
</span>{' '}
51+
per user/month
52+
</p>
53+
<p className="text-xs text-ds-gray-senary">billed monthly</p>
54+
</>
55+
)}
4156
</div>
4257
<div>
4358
<p className="mb-2 text-xs font-semibold">Includes</p>

0 commit comments

Comments
 (0)