Skip to content

Commit 38b1d42

Browse files
committed
fix nullable fees in BillingPlan
1 parent 4731af2 commit 38b1d42

File tree

14 files changed

+61
-68
lines changed

14 files changed

+61
-68
lines changed

packages/clerk-js/src/core/resources/BillingPlan.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export class BillingPlan extends BaseResource implements BillingPlanResource {
88
id!: string;
99
name!: string;
1010
fee!: BillingMoneyAmount;
11-
annualFee!: BillingMoneyAmount;
12-
annualMonthlyFee!: BillingMoneyAmount;
11+
annualFee: BillingMoneyAmount | null = null;
12+
annualMonthlyFee: BillingMoneyAmount | null = null;
1313
description!: string;
1414
isDefault!: boolean;
1515
isRecurring!: boolean;
@@ -32,11 +32,17 @@ export class BillingPlan extends BaseResource implements BillingPlanResource {
3232
return this;
3333
}
3434

35+
console.log('data', {
36+
fee: data.fee,
37+
annual_fee: data.annual_fee,
38+
annual_monthly_fee: data.annual_monthly_fee,
39+
});
40+
3541
this.id = data.id;
3642
this.name = data.name;
3743
this.fee = billingMoneyAmountFromJSON(data.fee);
38-
this.annualFee = billingMoneyAmountFromJSON(data.annual_fee);
39-
this.annualMonthlyFee = billingMoneyAmountFromJSON(data.annual_monthly_fee);
44+
this.annualFee = data.annual_fee ? billingMoneyAmountFromJSON(data.annual_fee) : null;
45+
this.annualMonthlyFee = data.annual_monthly_fee ? billingMoneyAmountFromJSON(data.annual_monthly_fee) : null;
4046
this.description = data.description;
4147
this.isDefault = data.is_default;
4248
this.isRecurring = data.is_recurring;

packages/clerk-js/src/ui/components/Checkout/CheckoutForm.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ export const CheckoutForm = withCardStateProvider(() => {
3939
const showPastDue = !!totals.pastDue?.amount && totals.pastDue.amount > 0;
4040
const showDowngradeInfo = !isImmediatePlanChange;
4141

42-
const fee = planPeriod === 'month' ? plan.fee : plan.annualMonthlyFee;
42+
const fee =
43+
planPeriod === 'month'
44+
? plan.fee
45+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
46+
plan.annualMonthlyFee!;
4347

4448
return (
4549
<Drawer.Body>

packages/clerk-js/src/ui/components/PaymentAttempts/PaymentAttemptPage.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,10 @@ function PaymentAttemptBody({ subscriptionItem }: { subscriptionItem: BillingSub
215215
}
216216

217217
const fee =
218-
subscriptionItem.planPeriod === 'month' ? subscriptionItem.plan.fee : subscriptionItem.plan.annualMonthlyFee;
218+
subscriptionItem.planPeriod === 'month'
219+
? subscriptionItem.plan.fee
220+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
221+
subscriptionItem.plan.annualMonthlyFee!;
219222

220223
return (
221224
<Box

packages/clerk-js/src/ui/components/Plans/PlanDetails.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ const Header = React.forwardRef<HTMLDivElement, HeaderProps>((props, ref) => {
227227
const { plan, closeSlot, planPeriod, setPlanPeriod } = props;
228228

229229
const fee = useMemo(() => {
230-
if (plan.annualMonthlyFee.amount <= 0) {
230+
if (!plan.annualMonthlyFee) {
231231
return plan.fee;
232232
}
233233
return planPeriod === 'annual' ? plan.annualMonthlyFee : plan.fee;
@@ -333,7 +333,7 @@ const Header = React.forwardRef<HTMLDivElement, HeaderProps>((props, ref) => {
333333
</>
334334
</Flex>
335335

336-
{plan.annualMonthlyFee.amount > 0 ? (
336+
{plan.annualMonthlyFee ? (
337337
<Box
338338
elementDescriptor={descriptors.planDetailPeriodToggle}
339339
sx={t => ({

packages/clerk-js/src/ui/components/Plans/__tests__/PlanDetails.test.tsx

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -221,18 +221,8 @@ describe('PlanDetails', () => {
221221
currencySymbol: '$',
222222
currency: 'USD',
223223
},
224-
annualFee: {
225-
amount: 0,
226-
amountFormatted: '0.00',
227-
currencySymbol: '$',
228-
currency: 'USD',
229-
},
230-
annualMonthlyFee: {
231-
amount: 0,
232-
amountFormatted: '0.00',
233-
currencySymbol: '$',
234-
currency: 'USD',
235-
},
224+
annualFee: null,
225+
annualMonthlyFee: null,
236226
};
237227

238228
const { wrapper } = await createFixtures(f => {
@@ -265,18 +255,8 @@ describe('PlanDetails', () => {
265255
currencySymbol: '$',
266256
currency: 'USD',
267257
},
268-
annualFee: {
269-
amount: 0,
270-
amountFormatted: '0.00',
271-
currencySymbol: '$',
272-
currency: 'USD',
273-
},
274-
annualMonthlyFee: {
275-
amount: 0,
276-
amountFormatted: '0.00',
277-
currencySymbol: '$',
278-
currency: 'USD',
279-
},
258+
annualFee: null,
259+
annualMonthlyFee: null,
280260
isDefault: true,
281261
};
282262

packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,17 @@ const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>((props, ref
282282
const { plan, isCompact, planPeriod, setPlanPeriod, badge } = props;
283283
const { name, annualMonthlyFee } = plan;
284284

285-
const planSupportsAnnual = annualMonthlyFee.amount > 0;
285+
const planSupportsAnnual = Boolean(annualMonthlyFee);
286286

287287
const fee = React.useMemo(() => {
288288
if (!planSupportsAnnual) {
289289
return plan.fee;
290290
}
291-
return planPeriod === 'annual' ? plan.annualMonthlyFee : plan.fee;
291+
292+
return planPeriod === 'annual'
293+
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
294+
plan.annualMonthlyFee!
295+
: plan.fee;
292296
}, [planSupportsAnnual, planPeriod, plan.fee, plan.annualMonthlyFee]);
293297

294298
const feeFormatted = React.useMemo(() => {

packages/clerk-js/src/ui/components/PricingTable/PricingTableMatrix.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export function PricingTableMatrix({
6060

6161
const gridTemplateColumns = React.useMemo(() => `repeat(${plans.length + 1}, minmax(9.375rem,1fr))`, [plans.length]);
6262

63-
const renderBillingCycleControls = React.useMemo(() => plans.some(plan => plan.annualMonthlyFee.amount > 0), [plans]);
63+
const renderBillingCycleControls = React.useMemo(() => plans.some(plan => Boolean(plan.annualMonthlyFee)), [plans]);
6464

6565
const getAllFeatures = React.useMemo(() => {
6666
const featuresSet = new Set<string>();
@@ -156,12 +156,11 @@ export function PricingTableMatrix({
156156
</Box>
157157
{plans.map(plan => {
158158
const highlight = plan.slug === highlightedPlan;
159-
const planFee =
160-
plan.annualMonthlyFee.amount <= 0
161-
? plan.fee
162-
: planPeriod === 'annual'
163-
? plan.annualMonthlyFee
164-
: plan.fee;
159+
const planFee = !plan.annualMonthlyFee
160+
? plan.fee
161+
: planPeriod === 'annual'
162+
? plan.annualMonthlyFee
163+
: plan.fee;
165164

166165
return (
167166
<Box
@@ -253,7 +252,7 @@ export function PricingTableMatrix({
253252
})}
254253
localizationKey={localizationKeys('billing.month')}
255254
/>
256-
{plan.annualMonthlyFee.amount > 0 ? (
255+
{plan.annualMonthlyFee ? (
257256
<Box
258257
elementDescriptor={descriptors.pricingTableMatrixFeePeriodNotice}
259258
sx={[

packages/clerk-js/src/ui/components/PricingTable/utils/pricing-footer-state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const valueResolution = (params: UsePricingFooterStateParams): [boolean, boolean
3434
// Active subscription
3535
if (subscription.status === 'active') {
3636
const isCanceled = !!subscription.canceledAt;
37-
const isSwitchingPaidPeriod = planPeriod !== subscription.planPeriod && plan.annualMonthlyFee.amount > 0;
37+
const isSwitchingPaidPeriod = planPeriod !== subscription.planPeriod && Boolean(plan.annualMonthlyFee);
3838
const isActiveFreeTrial = plan.freeTrialEnabled && subscription.isFreeTrial;
3939

4040
if (isCanceled || isSwitchingPaidPeriod) {

packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -262,18 +262,8 @@ describe('SubscriptionDetails', () => {
262262
currencySymbol: '$',
263263
currency: 'USD',
264264
},
265-
annualFee: {
266-
amount: 0,
267-
amountFormatted: '0.00',
268-
currencySymbol: '$',
269-
currency: 'USD',
270-
},
271-
annualMonthlyFee: {
272-
amount: 0,
273-
amountFormatted: '0.00',
274-
currencySymbol: '$',
275-
currency: 'USD',
276-
},
265+
annualFee: null,
266+
annualMonthlyFee: null,
277267
description: 'Free Plan description',
278268
hasBaseFee: false,
279269
isRecurring: true,

packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ const SubscriptionCardActions = ({ subscription }: { subscription: BillingSubscr
374374
const canManageBilling = subscriberType === 'user' || canOrgManageBilling;
375375

376376
const isSwitchable =
377-
((subscription.planPeriod === 'month' && subscription.plan.annualMonthlyFee.amount > 0) ||
377+
((subscription.planPeriod === 'month' && Boolean(subscription.plan.annualMonthlyFee)) ||
378378
subscription.planPeriod === 'annual') &&
379379
subscription.status !== 'past_due';
380380
const isFree = isFreePlan(subscription.plan);
@@ -409,8 +409,10 @@ const SubscriptionCardActions = ({ subscription }: { subscription: BillingSubscr
409409
label:
410410
subscription.planPeriod === 'month'
411411
? localizationKeys('billing.switchToAnnualWithAnnualPrice', {
412-
price: normalizeFormatted(subscription.plan.annualFee.amountFormatted),
413-
currency: subscription.plan.annualFee.currencySymbol,
412+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
413+
price: normalizeFormatted(subscription.plan.annualFee!.amountFormatted),
414+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
415+
currency: subscription.plan.annualFee!.currencySymbol,
414416
})
415417
: localizationKeys('billing.switchToMonthlyWithPrice', {
416418
price: normalizeFormatted(subscription.plan.fee.amountFormatted),
@@ -480,7 +482,11 @@ const SubscriptionCardActions = ({ subscription }: { subscription: BillingSubscr
480482
const SubscriptionCard = ({ subscription }: { subscription: BillingSubscriptionItemResource }) => {
481483
const { t } = useLocalizations();
482484

483-
const fee = subscription.planPeriod === 'month' ? subscription.plan.fee : subscription.plan.annualFee;
485+
const fee =
486+
subscription.planPeriod === 'month'
487+
? subscription.plan.fee
488+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
489+
subscription.plan.annualFee!;
484490

485491
return (
486492
<Col

0 commit comments

Comments
 (0)