@stigg/react-sdk 4.15.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.15.0",
2
+ "version": "5.0.0",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -112,7 +112,7 @@
112
112
  "@emotion/react": "^11.10.5",
113
113
  "@emotion/styled": "^11.10.5",
114
114
  "@mui/material": "^5.12.0",
115
- "@stigg/js-client-sdk": "2.25.0",
115
+ "@stigg/js-client-sdk": "3.0.0",
116
116
  "@stripe/react-stripe-js": "^2.1.1",
117
117
  "@stripe/stripe-js": "^1.54.1",
118
118
  "@types/styled-components": "^5.1.26",
@@ -1,9 +1,9 @@
1
1
  import keyBy from 'lodash/keyBy';
2
2
  import compact from 'lodash/compact';
3
- import { BillableFeatureInput, BillingPeriod, TiersMode } from '@stigg/api-client-js/src/generated/sdk';
3
+ import { BillableFeatureInput, BillingPeriod } from '@stigg/api-client-js/src/generated/sdk';
4
4
  import { BillableFeature, BillingModel, Plan, Price, Subscription } from '@stigg/js-client-sdk';
5
5
  import { useCheckoutContext } from '../CheckoutProvider';
6
- import { getTierByQuantity } from '../../utils/priceTierUtils';
6
+ import { getTierByQuantity, hasTierWithUnitPrice } from '../../utils/priceTierUtils';
7
7
  import { getValidPriceQuantity } from '../../utils/priceUtils';
8
8
 
9
9
  export type PlanStepState = {
@@ -73,7 +73,7 @@ function getBillableFeatures(
73
73
 
74
74
  quantity = getValidPriceQuantity(price, preconfiguredQuantity || 1);
75
75
 
76
- if (price.isTieredPrice && price.tiersMode === TiersMode.Volume) {
76
+ if (price.isTieredPrice && !hasTierWithUnitPrice(price.tiers)) {
77
77
  const tier = getTierByQuantity(price.tiers!, quantity);
78
78
  quantity = tier!.upTo!;
79
79
  }
@@ -10,7 +10,7 @@ import {
10
10
  } from '@stigg/js-client-sdk';
11
11
  import { Typography } from '../../../common/Typography';
12
12
  import { currencyPriceFormatter } from '../../../utils/currencyUtils';
13
- import { getTierByQuantity } from '../../../utils/priceTierUtils';
13
+ import { calculateTierPriceVolume, getTierByQuantity } from '../../../utils/priceTierUtils';
14
14
  import { WithSkeleton } from './WithSkeleton';
15
15
  import { Skeleton } from '../../components/Skeletons.style';
16
16
  import { CheckoutLocalization } from '../../configurations/textOverrides';
@@ -33,6 +33,10 @@ export const getPriceString = ({ amount, price, quantity }: { amount: number; pr
33
33
  const { billingPeriod } = price;
34
34
  let billingPeriodString = null;
35
35
 
36
+ if (quantity) {
37
+ amount /= quantity;
38
+ }
39
+
36
40
  if (billingPeriod === BillingPeriod.Annually) {
37
41
  amount /= 12;
38
42
  billingPeriodString = '12 months';
@@ -71,7 +75,7 @@ export const BilledPriceLineItem = ({
71
75
  let amount;
72
76
  if (price.isTieredPrice) {
73
77
  const tier = getTierByQuantity(price.tiers!, quantity);
74
- amount = tier!.unitPrice.amount!;
78
+ amount = calculateTierPriceVolume(tier!, quantity);
75
79
  } else {
76
80
  amount = price.amount!;
77
81
  }
@@ -92,7 +96,7 @@ export const BilledPriceLineItem = ({
92
96
  <Grid item display="flex" gap={1} alignItems="center">
93
97
  {isPayAsYouGo && <PayAsYouGoPriceTooltip checkoutLocalization={checkoutLocalization} />}
94
98
  <Typography variant="body1" color="secondary" style={{ wordBreak: 'break-word' }}>
95
- {currencyPriceFormatter({ amount: quantity * amount, currency: price.currency, minimumFractionDigits: 2 })}
99
+ {currencyPriceFormatter({ amount, currency: price.currency, minimumFractionDigits: 2 })}
96
100
  {isPayAsYouGo && ' / unit'}
97
101
  </Typography>
98
102
  </Grid>
@@ -1,7 +1,7 @@
1
1
  import { PriceTierFragment, TiersMode } from '@stigg/js-client-sdk';
2
2
  import React from 'react';
3
3
  import styled from '@emotion/styled/macro';
4
- import { getTierByQuantity } from '../utils/priceTierUtils';
4
+ import { getTierByQuantity, hasTierWithUnitPrice } from '../utils/priceTierUtils';
5
5
  import { Typography } from './Typography';
6
6
  import { VolumePerUnitInput } from './VolumePerUnitInput';
7
7
  import { VolumeBulkSelect } from './VolumeBulkSelect';
@@ -23,27 +23,20 @@ const TiersSelectLayout = styled(Typography)`
23
23
  `;
24
24
 
25
25
  export function TiersSelectContainer(props: TiersSelectContainerProps) {
26
- const { tiers, tiersMode, handleTierChange } = props;
26
+ const { tiers, handleTierChange } = props;
27
27
  const handleChange = (quantity: number) => {
28
28
  if (!tiers) return;
29
29
 
30
30
  handleTierChange(getTierByQuantity(tiers, quantity)!);
31
31
  };
32
32
 
33
- const getContent = () => {
34
- switch (tiersMode) {
35
- case TiersMode.VolumePerUnit:
36
- return <VolumePerUnitInput handleChange={handleChange} {...props} />;
37
- case TiersMode.Volume:
38
- return <VolumeBulkSelect handleChange={handleChange} {...props} />;
39
- default:
40
- return <div />;
41
- }
42
- };
43
-
44
33
  return (
45
34
  <TiersSelectLayout as="div" className="stigg-price-tier-select">
46
- {getContent()}
35
+ {hasTierWithUnitPrice(tiers) ? (
36
+ <VolumePerUnitInput handleChange={handleChange} {...props} />
37
+ ) : (
38
+ <VolumeBulkSelect handleChange={handleChange} {...props} />
39
+ )}
47
40
  </TiersSelectLayout>
48
41
  );
49
42
  }
@@ -1,6 +1,7 @@
1
1
  import { BillingPeriod, PaywallCalculatedPricePoint, Price } from '@stigg/js-client-sdk';
2
2
  import isNil from 'lodash/isNil';
3
3
  import { PaywallPlan } from '../paywall';
4
+ import { calculateTierPriceVolume } from './priceTierUtils';
4
5
 
5
6
  export function calculateDiscountRate(monthlyPrice?: number | null, annuallyPrice?: number | null) {
6
7
  if (!isNil(monthlyPrice) && !isNil(annuallyPrice)) {
@@ -26,7 +27,7 @@ function getPlanBillingPeriodAmount(plan: PaywallPlan, billingPeriod: BillingPer
26
27
  });
27
28
 
28
29
  if (tieredPrice) {
29
- return tieredPrice.tiers![0].unitPrice.amount;
30
+ return calculateTierPriceVolume(tieredPrice.tiers![0], 1);
30
31
  }
31
32
  }
32
33
 
@@ -60,7 +60,7 @@ export function getPaidPriceText({
60
60
  currentTier,
61
61
  selectedBillingPeriod,
62
62
  shouldShowMonthlyPriceAmount,
63
- perUnitQuantityByFeature?.[price.feature!.featureId],
63
+ perUnitQuantityByFeature?.[price.feature!.featureId] || 1,
64
64
  );
65
65
  }
66
66
  }
@@ -1,4 +1,5 @@
1
1
  import { BillingModel, TiersMode, BillingPeriod, Price, PriceTierFragment, Subscription } from '@stigg/js-client-sdk';
2
+ import isNil from 'lodash/isNil';
2
3
  import { PaywallPlan } from '../paywall';
3
4
  import { SelectDefaultTierIndexFn } from '../paywall/types';
4
5
 
@@ -27,23 +28,45 @@ export function getTierByQuantity(tiers: PriceTierFragment[], quantity: number)
27
28
  return ascendingTiers[ascendingTiers.length - 1];
28
29
  }
29
30
 
31
+ function getAmount(amount: number, selectedBillingPeriod?: BillingPeriod, shouldShowMonthlyPriceAmount?: boolean) {
32
+ return selectedBillingPeriod === BillingPeriod.Annually && shouldShowMonthlyPriceAmount ? amount / 12 : amount;
33
+ }
34
+
35
+ export function calculateTierPriceVolume(
36
+ currentTier: PriceTierFragment,
37
+ perUnitQuantity: number,
38
+ selectedBillingPeriod?: BillingPeriod,
39
+ shouldShowMonthlyPriceAmount?: boolean,
40
+ ): number {
41
+ let amount = 0;
42
+
43
+ if (currentTier.unitPrice) {
44
+ const unitPrice = getAmount(currentTier.unitPrice.amount, selectedBillingPeriod, shouldShowMonthlyPriceAmount);
45
+ amount += unitPrice * perUnitQuantity;
46
+ }
47
+
48
+ if (currentTier.flatPrice) {
49
+ amount += getAmount(currentTier.flatPrice.amount, selectedBillingPeriod, shouldShowMonthlyPriceAmount);
50
+ }
51
+
52
+ return amount;
53
+ }
54
+
30
55
  export function calculateTierPrice(
31
56
  price: Price,
32
57
  currentTier: PriceTierFragment,
33
58
  selectedBillingPeriod: BillingPeriod,
34
59
  shouldShowMonthlyPriceAmount: boolean,
35
- perUnitQuantity?: number,
60
+ perUnitQuantity: number,
36
61
  ): number {
37
- const unitPrice =
38
- selectedBillingPeriod === BillingPeriod.Annually && shouldShowMonthlyPriceAmount
39
- ? currentTier.unitPrice.amount / 12
40
- : currentTier.unitPrice.amount;
41
62
  switch (price.tiersMode) {
42
63
  case TiersMode.Volume: {
43
- return unitPrice * (currentTier.upTo || 1);
44
- }
45
- case TiersMode.VolumePerUnit: {
46
- return unitPrice * (perUnitQuantity || 1);
64
+ return calculateTierPriceVolume(
65
+ currentTier,
66
+ perUnitQuantity,
67
+ selectedBillingPeriod,
68
+ shouldShowMonthlyPriceAmount,
69
+ );
47
70
  }
48
71
  default:
49
72
  return 0;
@@ -78,6 +101,10 @@ export function getSelectedTierQuantityBeFeature(
78
101
  return result;
79
102
  }
80
103
 
104
+ export function hasTierWithUnitPrice(tiers: PriceTierFragment[] | null | undefined) {
105
+ return tiers?.some(({ unitPrice, upTo }) => unitPrice && !isNil(upTo));
106
+ }
107
+
81
108
  export function getSelectedTier(
82
109
  plan: PaywallPlan,
83
110
  billingPeriod: BillingPeriod,
@@ -142,7 +169,7 @@ export function compareSelectedTierToCurrentTier(
142
169
  }
143
170
 
144
171
  const { featureId, unitQuantity } = currentTierPrice.feature!;
145
- const { tiersMode } = currentTierPrice;
172
+ const { tiers } = currentTierPrice;
146
173
 
147
174
  if (!unitQuantity) {
148
175
  return PriceTierComparison.Equal;
@@ -154,20 +181,13 @@ export function compareSelectedTierToCurrentTier(
154
181
  return PriceTierComparison.Equal;
155
182
  }
156
183
 
157
- if (tiersMode === TiersMode.Volume) {
158
- if (selectedTier.upTo && selectedTier.upTo < unitQuantity) {
159
- return PriceTierComparison.Lower;
160
- }
184
+ const effectiveQuantity = hasTierWithUnitPrice(tiers) ? selectedQuantity : selectedTier.upTo;
161
185
 
162
- if (selectedTier.upTo && selectedTier.upTo > unitQuantity) {
163
- return PriceTierComparison.Higher;
164
- }
165
- } else if (tiersMode === TiersMode.VolumePerUnit) {
166
- if (selectedQuantity && selectedQuantity < unitQuantity) {
186
+ if (!isNil(effectiveQuantity)) {
187
+ if (effectiveQuantity < unitQuantity) {
167
188
  return PriceTierComparison.Lower;
168
189
  }
169
-
170
- if (selectedQuantity && selectedQuantity > unitQuantity) {
190
+ if (effectiveQuantity > unitQuantity) {
171
191
  return PriceTierComparison.Higher;
172
192
  }
173
193
  }
@@ -116,8 +116,8 @@ function tieredPricing(): Price[] {
116
116
  tiersMode: TiersMode.Volume,
117
117
  tiers: TIERS.map((tier, index) => ({
118
118
  upTo: tier,
119
- unitPrice: {
120
- amount: TIERS_PRICE_MONTHLY[index] / tier,
119
+ flatPrice: {
120
+ amount: TIERS_PRICE_MONTHLY[index],
121
121
  currency: Currency.Usd,
122
122
  },
123
123
  })),
@@ -131,8 +131,8 @@ function tieredPricing(): Price[] {
131
131
  tiersMode: TiersMode.Volume,
132
132
  tiers: TIERS.map((tier, index) => ({
133
133
  upTo: tier,
134
- unitPrice: {
135
- amount: TIERS_PRICE_YEARLY[index] / tier,
134
+ flatPrice: {
135
+ amount: TIERS_PRICE_YEARLY[index],
136
136
  currency: Currency.Usd,
137
137
  },
138
138
  })),