1- import { activePlans , Plan } from '@brunolemos/devhub-core'
1+ import {
2+ activePlans ,
3+ formatInterval ,
4+ formatPrice ,
5+ formatPriceAndInterval ,
6+ Plan ,
7+ } from '@brunolemos/devhub-core'
28import classNames from 'classnames'
39import qs from 'qs'
410import React from 'react'
511
612import { useAuth } from '../../../context/AuthContext'
7- import { useFormattedPlanPrice } from '../../../hooks/use-formatted -plan-price '
13+ import { useLocalizedPlanDetails } from '../../../hooks/use-localized -plan-details '
814import Button from '../../common/buttons/Button'
915import CheckLabel from '../../common/CheckLabel'
1016
1117export interface PricingPlanBlockProps {
1218 banner ?: string | boolean
1319 buttonLabel ?: string
1420 buttonLink : string
21+ forceShowAsMonthly ?: boolean
1522 plan : Plan
1623 totalNumberOfVisiblePlans ?: number
1724}
@@ -21,46 +28,52 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
2128 banner : _banner ,
2229 buttonLabel,
2330 buttonLink,
31+ forceShowAsMonthly = false ,
2432 plan,
2533 totalNumberOfVisiblePlans,
2634 } = props
2735
2836 const { authData } = useAuth ( )
2937
38+ const localizedPlan = useLocalizedPlanDetails ( plan )
3039 const userPlan = authData && authData . plan
3140 const userPlanIsActive =
3241 userPlan && userPlan . id && activePlans . find ( p => p . id === userPlan ! . id )
33- const isMyPlan = userPlan && userPlan . id === plan . id
42+ const isMyPlan = userPlan && userPlan . id === localizedPlan . id
3443
3544 const banner = userPlanIsActive
3645 ? isMyPlan
37- ? plan . interval
38- ? 'Current plan '
46+ ? localizedPlan . interval
47+ ? 'Current localizedPlan '
3948 : 'You bought this'
4049 : _banner || true
4150 : _banner
4251
43- const estimatedMonthlyPrice =
44- ( plan . interval === 'day'
45- ? plan . amount * 30
46- : plan . interval === 'week'
47- ? plan . amount * 4
48- : plan . interval === 'year'
49- ? plan . amount / 12
50- : plan . amount ) /
51- ( plan . intervalCount || 1 ) /
52- ( plan . transformUsage && plan . transformUsage . divideBy > 1
53- ? plan . transformUsage . divideBy
54- : 1 )
55-
56- const _priceLabel = useFormattedPlanPrice ( estimatedMonthlyPrice , plan )
57- const _roundedPriceLabelWithInterval = useFormattedPlanPrice (
58- plan . amount % 100 > 50
59- ? plan . amount + ( 100 - ( plan . amount % 100 ) )
60- : plan . amount ,
61- plan ,
62- { includeInterval : true } ,
63- )
52+ const modifiedAmount = forceShowAsMonthly
53+ ? ( localizedPlan . interval === 'day'
54+ ? localizedPlan . amount * 30
55+ : localizedPlan . interval === 'week'
56+ ? localizedPlan . amount * 4
57+ : localizedPlan . interval === 'year'
58+ ? localizedPlan . amount / 12
59+ : localizedPlan . amount ) /
60+ ( localizedPlan . intervalCount || 1 ) /
61+ ( localizedPlan . transformUsage && localizedPlan . transformUsage . divideBy > 1
62+ ? localizedPlan . transformUsage . divideBy
63+ : 1 )
64+ : localizedPlan . amount
65+
66+ const _priceLabel = formatPrice ( {
67+ ...localizedPlan ,
68+ amount : modifiedAmount ,
69+ } )
70+ const _roundedPriceLabelWithInterval = formatPriceAndInterval ( {
71+ ...localizedPlan ,
72+ amount :
73+ localizedPlan . amount % 100 > 50
74+ ? localizedPlan . amount + ( 100 - ( localizedPlan . amount % 100 ) )
75+ : localizedPlan . amount ,
76+ } )
6477
6578 const priceLabelCents =
6679 _priceLabel [ _priceLabel . length - 3 ] === '.'
@@ -72,40 +85,60 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
7285 : _priceLabel
7386
7487 const subtitle = `${
75- plan . type === 'team' ||
76- ( plan . transformUsage && plan . transformUsage . divideBy > 1 )
88+ localizedPlan . type === 'team' ||
89+ ( localizedPlan . transformUsage && localizedPlan . transformUsage . divideBy > 1 )
7790 ? '/user'
7891 : ''
79- } ${ plan . interval ? '/month' : '' } ${
80- estimatedMonthlyPrice !== plan . amount ? '*' : ''
81- } `. trim ( )
92+ } ${
93+ forceShowAsMonthly
94+ ? '/month'
95+ : localizedPlan . interval
96+ ? formatInterval ( localizedPlan )
97+ : ''
98+ } ${ modifiedAmount !== localizedPlan . amount ? '*' : '' } `. trim ( )
8299
83100 let footerText = ''
84101
85- if ( ! plan . amount && plan . trialPeriodDays ) {
102+ if ( ! localizedPlan . amount && localizedPlan . trialPeriodDays ) {
86103 footerText =
87104 ( footerText ? `${ footerText } \n` : footerText ) +
88- `Free for ${ plan . trialPeriodDays } days`
105+ `Free for ${ localizedPlan . trialPeriodDays } days`
89106 }
90107
91- if ( estimatedMonthlyPrice !== plan . amount ) {
108+ if ( modifiedAmount !== localizedPlan . amount ) {
92109 footerText =
93110 ( footerText ? `${ footerText } \n` : footerText ) +
94111 `*Billed ${
95- plan . amount % 100 > 50 ? '~' : ''
112+ localizedPlan . amount % 100 > 50 ? '~' : ''
96113 } ${ _roundedPriceLabelWithInterval } `
97114 }
98115
99- if ( ! plan . interval && plan . amount ) {
116+ if ( ! localizedPlan . interval && localizedPlan . amount ) {
100117 footerText =
101118 ( footerText ? `${ footerText } \n` : footerText ) +
102119 'One-time payment (no subscription)'
103120 }
104121
122+ if (
123+ ! footerText &&
124+ localizedPlan . interval &&
125+ localizedPlan . amount &&
126+ totalNumberOfVisiblePlans === 1
127+ ) {
128+ if ( localizedPlan . trialPeriodDays ) {
129+ footerText =
130+ ( footerText ? `${ footerText } \n` : footerText ) +
131+ `${ localizedPlan . trialPeriodDays } -day free trial`
132+ }
133+ footerText =
134+ ( footerText ? `${ footerText } \n` : footerText ) +
135+ 'Cancel anytime with one click'
136+ }
137+
105138 return (
106139 < section
107140 className = { classNames (
108- 'pricing-plan flex flex-col flex-shrink-0' ,
141+ 'pricing-localizedPlan flex flex-col flex-shrink-0' ,
109142 totalNumberOfVisiblePlans === 1 ? 'w-full lg:w-84' : 'w-72' ,
110143 ) }
111144 >
@@ -137,11 +170,11 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
137170
138171 < div className = "p-6 text-center" >
139172 < div className = "text-base leading-loose font-bold text-default" >
140- { plan . label }
173+ { localizedPlan . label }
141174 </ div >
142175
143176 < div className = "mb-2 text-sm text-muted-65 whitespace-pre-line" >
144- { plan . description }
177+ { localizedPlan . description }
145178 </ div >
146179
147180 < div className = "text-5xl leading-snug font-bold text-default" >
@@ -167,10 +200,10 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
167200 < div className = "mb-2 text-sm text-muted-65" >
168201 { subtitle }
169202 </ div >
170- { /* {plan .interval ? (
203+ { /* {localizedPlan .interval ? (
171204 <div className="text-sm text-muted-65">{`/${
172- plan .intervalCount > 1 ? `${plan .intervalCount}-` : ''
173- }${plan .interval}` }</div>
205+ localizedPlan .intervalCount > 1 ? `${localizedPlan .intervalCount}-` : ''
206+ }${localizedPlan .interval}` }</div>
174207 ) : (
175208 <div className="text-sm text-muted-65"> </div>
176209 )} */ }
@@ -191,11 +224,11 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
191224 < div className = "pb-6" />
192225
193226 { isMyPlan ? (
194- plan . type === 'team' ? (
227+ localizedPlan . type === 'team' ? (
195228 < Button
196229 type = "primary"
197230 href = { `/purchase${ qs . stringify (
198- { plan : userPlan && userPlan . id } ,
231+ { localizedPlan : userPlan && userPlan . id } ,
199232 { addQueryPrefix : true } ,
200233 ) } `}
201234 >
@@ -216,13 +249,15 @@ export function PricingPlanBlock(props: PricingPlanBlockProps) {
216249 </ div >
217250 </ div >
218251
219- { ! ! ( plan . featureLabels && plan . featureLabels . length ) && (
252+ { ! ! (
253+ localizedPlan . featureLabels && localizedPlan . featureLabels . length
254+ ) && (
220255 < div className = "p-4" >
221256 < div className = "pb-2" />
222257
223- { plan . featureLabels . map ( ( feature , index ) => (
258+ { localizedPlan . featureLabels . map ( ( feature , index ) => (
224259 < CheckLabel
225- key = { `pricing-plan -${ plan . id } -feature-${ index } ` }
260+ key = { `pricing-localizedPlan -${ localizedPlan . id } -feature-${ index } ` }
226261 label = { feature . label }
227262 checkProps = { {
228263 className : feature . available ? 'text-primary' : 'invisible' ,
0 commit comments