@stigg/react-sdk 7.7.1-beta.0 → 7.8.0-beta.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.
Files changed (289) hide show
  1. package/dist/index.d.mts +829 -0
  2. package/dist/index.d.ts +829 -935
  3. package/dist/stigg-sdk.cjs.js +5915 -0
  4. package/dist/stigg-sdk.esm.js +5915 -0
  5. package/package.json +18 -21
  6. package/dist/react-sdk.cjs.js +0 -3446
  7. package/dist/react-sdk.esm.js +0 -12191
  8. package/src/assets/add.svg +0 -3
  9. package/src/assets/addons.svg +0 -12
  10. package/src/assets/arrow-forward.svg +0 -3
  11. package/src/assets/arrow-right.svg +0 -6
  12. package/src/assets/billing-info-customer.svg +0 -11
  13. package/src/assets/check-stigg.svg +0 -3
  14. package/src/assets/check.svg +0 -5
  15. package/src/assets/close.svg +0 -3
  16. package/src/assets/contact-support.svg +0 -13
  17. package/src/assets/coupon.svg +0 -6
  18. package/src/assets/credit-card.svg +0 -10
  19. package/src/assets/dollar-coin.svg +0 -13
  20. package/src/assets/edit-icon.svg +0 -3
  21. package/src/assets/entitlement-check.svg +0 -3
  22. package/src/assets/lottie/checkout-success.json +0 -1
  23. package/src/assets/mini-schedule.svg +0 -3
  24. package/src/assets/outlined-checked-circle-disabled.svg +0 -6
  25. package/src/assets/outlined-checked-circle.svg +0 -6
  26. package/src/assets/outlined-circle.svg +0 -3
  27. package/src/assets/pay-as-you-go-charge.svg +0 -11
  28. package/src/assets/payment-method.svg +0 -4
  29. package/src/assets/plus-icon.svg +0 -6
  30. package/src/assets/powered-by-stigg.svg +0 -13
  31. package/src/assets/promotions.svg +0 -13
  32. package/src/assets/remove.svg +0 -3
  33. package/src/assets/restore.svg +0 -3
  34. package/src/assets/sand-clock.svg +0 -4
  35. package/src/assets/schedule-box.svg +0 -9
  36. package/src/assets/schedule.svg +0 -3
  37. package/src/assets/subscription-renews-icon.svg +0 -14
  38. package/src/assets/trash.svg +0 -8
  39. package/src/components/StiggProvider.tsx +0 -170
  40. package/src/components/checkout/Checkout.tsx +0 -37
  41. package/src/components/checkout/CheckoutContainer.style.ts +0 -51
  42. package/src/components/checkout/CheckoutContainer.tsx +0 -193
  43. package/src/components/checkout/CheckoutProvider.tsx +0 -181
  44. package/src/components/checkout/components/Button.tsx +0 -35
  45. package/src/components/checkout/components/ChangePlanButton.tsx +0 -30
  46. package/src/components/checkout/components/ContentLoadingSkeleton.tsx +0 -41
  47. package/src/components/checkout/components/DowngradeToFreeContainer.tsx +0 -115
  48. package/src/components/checkout/components/InputField.tsx +0 -26
  49. package/src/components/checkout/components/Skeletons.style.ts +0 -30
  50. package/src/components/checkout/components/StyledArrow.tsx +0 -9
  51. package/src/components/checkout/components/index.ts +0 -3
  52. package/src/components/checkout/configurations/steps.ts +0 -1
  53. package/src/components/checkout/configurations/textOverrides.ts +0 -150
  54. package/src/components/checkout/configurations/theme.ts +0 -46
  55. package/src/components/checkout/configurations/typography.ts +0 -30
  56. package/src/components/checkout/formatting.ts +0 -12
  57. package/src/components/checkout/hooks/index.ts +0 -8
  58. package/src/components/checkout/hooks/useAddonsStepModel.ts +0 -92
  59. package/src/components/checkout/hooks/useCheckoutModel.ts +0 -53
  60. package/src/components/checkout/hooks/useCouponModel.ts +0 -28
  61. package/src/components/checkout/hooks/useLoadCheckout.ts +0 -48
  62. package/src/components/checkout/hooks/usePaymentStepModel.ts +0 -68
  63. package/src/components/checkout/hooks/usePlanStepModel.ts +0 -184
  64. package/src/components/checkout/hooks/usePreviewSubscription.ts +0 -165
  65. package/src/components/checkout/hooks/useProgressBarModel.ts +0 -211
  66. package/src/components/checkout/hooks/useSubscriptionModel.ts +0 -22
  67. package/src/components/checkout/hooks/useSubscriptionState.ts +0 -26
  68. package/src/components/checkout/index.ts +0 -8
  69. package/src/components/checkout/planHeader/PlanHeader.tsx +0 -41
  70. package/src/components/checkout/planHeader/index.ts +0 -1
  71. package/src/components/checkout/progressBar/CheckoutProgressBar.style.ts +0 -35
  72. package/src/components/checkout/progressBar/CheckoutProgressBar.tsx +0 -82
  73. package/src/components/checkout/promotionCode/AddPromotionCode.tsx +0 -107
  74. package/src/components/checkout/promotionCode/AddPromotionCodeButton.tsx +0 -43
  75. package/src/components/checkout/promotionCode/AppliedPromotionCode.tsx +0 -49
  76. package/src/components/checkout/promotionCode/PromotionCodeSection.tsx +0 -40
  77. package/src/components/checkout/promotionCode/index.ts +0 -1
  78. package/src/components/checkout/steps/addons/CheckoutAddonsStep.style.tsx +0 -34
  79. package/src/components/checkout/steps/addons/CheckoutAddonsStep.tsx +0 -144
  80. package/src/components/checkout/steps/addons/addon.utils.ts +0 -67
  81. package/src/components/checkout/steps/addons/components/AddonInputContainer.tsx +0 -84
  82. package/src/components/checkout/steps/addons/components/AddonTextContainer.tsx +0 -45
  83. package/src/components/checkout/steps/addons/index.ts +0 -1
  84. package/src/components/checkout/steps/payment/PaymentMethods.style.ts +0 -36
  85. package/src/components/checkout/steps/payment/PaymentMethods.tsx +0 -106
  86. package/src/components/checkout/steps/payment/PaymentStep.tsx +0 -63
  87. package/src/components/checkout/steps/payment/index.ts +0 -1
  88. package/src/components/checkout/steps/payment/stripe/StripePaymentForm.tsx +0 -79
  89. package/src/components/checkout/steps/payment/stripe/index.ts +0 -3
  90. package/src/components/checkout/steps/payment/stripe/stripe.utils.ts +0 -122
  91. package/src/components/checkout/steps/payment/stripe/useStripeIntegration.ts +0 -33
  92. package/src/components/checkout/steps/payment/stripe/useSubmit.ts +0 -135
  93. package/src/components/checkout/steps/payment/zuora/ZuoraPaymentForm.tsx +0 -128
  94. package/src/components/checkout/steps/payment/zuora/index.ts +0 -9
  95. package/src/components/checkout/steps/payment/zuora/useZuoraIntegration.ts +0 -57
  96. package/src/components/checkout/steps/payment/zuora/useZuoraSubmit.ts +0 -125
  97. package/src/components/checkout/steps/payment/zuora/zuora.utils.ts +0 -72
  98. package/src/components/checkout/steps/plan/BillingPeriodPicker.style.tsx +0 -69
  99. package/src/components/checkout/steps/plan/BillingPeriodPicker.tsx +0 -86
  100. package/src/components/checkout/steps/plan/CheckoutChargeList.tsx +0 -223
  101. package/src/components/checkout/steps/plan/CheckoutPlanStep.style.tsx +0 -6
  102. package/src/components/checkout/steps/plan/CheckoutPlanStep.tsx +0 -31
  103. package/src/components/checkout/steps/plan/index.ts +0 -1
  104. package/src/components/checkout/summary/CheckoutSuccess.tsx +0 -82
  105. package/src/components/checkout/summary/CheckoutSummary.tsx +0 -458
  106. package/src/components/checkout/summary/CheckoutSummarySkeleton.tsx +0 -38
  107. package/src/components/checkout/summary/components/CheckoutCaptions.tsx +0 -145
  108. package/src/components/checkout/summary/components/GraduatedPriceBreakdown.tsx +0 -70
  109. package/src/components/checkout/summary/components/LineItems.tsx +0 -275
  110. package/src/components/checkout/summary/components/WithSkeleton.tsx +0 -16
  111. package/src/components/checkout/summary/components/getPriceBreakdownString.ts +0 -66
  112. package/src/components/checkout/summary/index.ts +0 -2
  113. package/src/components/checkout/types.ts +0 -82
  114. package/src/components/common/CollapsableSectionIcon.tsx +0 -9
  115. package/src/components/common/Icon.tsx +0 -61
  116. package/src/components/common/InformationTooltip.tsx +0 -28
  117. package/src/components/common/LongText.tsx +0 -100
  118. package/src/components/common/PoweredByStigg.tsx +0 -59
  119. package/src/components/common/ProgressBar.tsx +0 -41
  120. package/src/components/common/StatusChip.tsx +0 -29
  121. package/src/components/common/TiersSelectContainer.tsx +0 -39
  122. package/src/components/common/Typography.tsx +0 -117
  123. package/src/components/common/VolumeBulkSelect.tsx +0 -74
  124. package/src/components/common/VolumePerUnitInput.tsx +0 -42
  125. package/src/components/common/chart/chartjs.helpers.ts +0 -17
  126. package/src/components/common/chart/chartjs.plugins.ts +0 -34
  127. package/src/components/common/chart/chartjs.theme.ts +0 -41
  128. package/src/components/common/chart/chartjs.tooltip.plugin.tsx +0 -224
  129. package/src/components/common/customIcons.ts +0 -24
  130. package/src/components/common/iconColor.ts +0 -15
  131. package/src/components/common/mapExternalTheme.ts +0 -147
  132. package/src/components/common/mediaQuery.ts +0 -19
  133. package/src/components/common/table/DataRows.tsx +0 -33
  134. package/src/components/common/table/EmptyState.tsx +0 -19
  135. package/src/components/common/table/ErrorState.tsx +0 -19
  136. package/src/components/common/table/GenericTable.tsx +0 -155
  137. package/src/components/common/table/LoadingRows.tsx +0 -33
  138. package/src/components/common/table/index.ts +0 -6
  139. package/src/components/common/table/types.ts +0 -30
  140. package/src/components/credits/balance/CreditBalance.tsx +0 -70
  141. package/src/components/credits/balance/CreditBalanceValue.tsx +0 -60
  142. package/src/components/credits/creditUsageChart/CreditUsage.chartjs.ts +0 -223
  143. package/src/components/credits/creditUsageChart/CreditUsageChart.tsx +0 -128
  144. package/src/components/credits/creditUsageChart/CreditUsageChartEmptyState.tsx +0 -29
  145. package/src/components/credits/creditUsageChart/CreditUsageChartErrorState.tsx +0 -19
  146. package/src/components/credits/creditUsageChart/CreditUsageChartHeader.tsx +0 -104
  147. package/src/components/credits/creditUsageChart/CreditUsageChartTooltip.tsx +0 -93
  148. package/src/components/credits/creditUsageChart/CreditUsageLegend.tsx +0 -141
  149. package/src/components/credits/creditUsageChart/types.ts +0 -4
  150. package/src/components/credits/grants/CreditGrants.tsx +0 -64
  151. package/src/components/credits/grants/CreditGrantsTable.tsx +0 -101
  152. package/src/components/credits/grants/types.ts +0 -38
  153. package/src/components/credits/grants/utils.ts +0 -25
  154. package/src/components/credits/hooks/useCreditBalance.ts +0 -75
  155. package/src/components/credits/hooks/useCreditGrants.ts +0 -40
  156. package/src/components/credits/hooks/useCreditUsage.ts +0 -50
  157. package/src/components/credits/index.ts +0 -15
  158. package/src/components/credits/localization.ts +0 -25
  159. package/src/components/credits/utilization/CreditUtilization.tsx +0 -74
  160. package/src/components/credits/utilization/CreditUtilizationValue.tsx +0 -113
  161. package/src/components/credits/utils/creditBalanceUtils.ts +0 -31
  162. package/src/components/credits/utils/creditGrantUtils.ts +0 -27
  163. package/src/components/customerPortal/CustomerPortal.style.ts +0 -20
  164. package/src/components/customerPortal/CustomerPortal.tsx +0 -37
  165. package/src/components/customerPortal/CustomerPortalContainer.tsx +0 -77
  166. package/src/components/customerPortal/CustomerPortalContext.ts +0 -32
  167. package/src/components/customerPortal/CustomerPortalHeader.tsx +0 -18
  168. package/src/components/customerPortal/CustomerPortalProvider.tsx +0 -49
  169. package/src/components/customerPortal/billing/InformationGrid.tsx +0 -54
  170. package/src/components/customerPortal/billing/InvoicesSection.tsx +0 -41
  171. package/src/components/customerPortal/billing/PaymentDetailsSection.tsx +0 -140
  172. package/src/components/customerPortal/common/ExternalLinkButton.tsx +0 -34
  173. package/src/components/customerPortal/common/SectionContainer.tsx +0 -22
  174. package/src/components/customerPortal/common/SectionHeader.ts +0 -15
  175. package/src/components/customerPortal/common/SectionTitle.tsx +0 -23
  176. package/src/components/customerPortal/common/SkeletonButton.tsx +0 -5
  177. package/src/components/customerPortal/common/StyledButton.tsx +0 -13
  178. package/src/components/customerPortal/customerPortalTextOverrides.ts +0 -39
  179. package/src/components/customerPortal/customerPortalTheme.ts +0 -35
  180. package/src/components/customerPortal/hooks/useCustomerPortal.ts +0 -39
  181. package/src/components/customerPortal/index.ts +0 -16
  182. package/src/components/customerPortal/paywall/CustomerPortalPaywall.style.ts +0 -33
  183. package/src/components/customerPortal/paywall/CustomerPortalPaywall.tsx +0 -36
  184. package/src/components/customerPortal/subscriptionOverview/ContactCustomerSupport.tsx +0 -50
  185. package/src/components/customerPortal/subscriptionOverview/SubscriptionOverviewLoader.tsx +0 -28
  186. package/src/components/customerPortal/subscriptionOverview/SubscriptionsOverview.tsx +0 -106
  187. package/src/components/customerPortal/subscriptionOverview/SubscriptionsOverviewHeader.tsx +0 -48
  188. package/src/components/customerPortal/subscriptionOverview/charges/ChargeItem.tsx +0 -74
  189. package/src/components/customerPortal/subscriptionOverview/charges/ChargeList.tsx +0 -65
  190. package/src/components/customerPortal/subscriptionOverview/subscriptionScheduledUpdates/SubscriptionScheduledUpdateRow.tsx +0 -110
  191. package/src/components/customerPortal/subscriptionOverview/subscriptionScheduledUpdates/SubscriptionScheduledUpdatesAlert.tsx +0 -158
  192. package/src/components/customerPortal/subscriptionOverview/subscriptionView/SubscriptionView.style.ts +0 -6
  193. package/src/components/customerPortal/subscriptionOverview/subscriptionView/SubscriptionView.tsx +0 -37
  194. package/src/components/customerPortal/subscriptionOverview/subscriptionView/TrialPanel.tsx +0 -58
  195. package/src/components/customerPortal/subscriptionOverview/tabs/AddonsList.tsx +0 -28
  196. package/src/components/customerPortal/subscriptionOverview/tabs/Promotions.tsx +0 -62
  197. package/src/components/customerPortal/subscriptionOverview/tabs/SubscriptionTabs.style.tsx +0 -32
  198. package/src/components/customerPortal/subscriptionOverview/tabs/SubscriptionTabs.tsx +0 -100
  199. package/src/components/customerPortal/subscriptionOverview/types/customerPortal.types.ts +0 -4
  200. package/src/components/customerPortal/subscriptionOverview/upcomingBilling/NextEstimatedBill.tsx +0 -29
  201. package/src/components/customerPortal/subscriptionOverview/upcomingBilling/NoUpcomingBilling.tsx +0 -18
  202. package/src/components/customerPortal/subscriptionOverview/upcomingBilling/UpcomingBilling.tsx +0 -89
  203. package/src/components/customerPortal/types.ts +0 -20
  204. package/src/components/customerPortal/usage/CustomerUsageData.style.tsx +0 -22
  205. package/src/components/customerPortal/usage/CustomerUsageData.tsx +0 -124
  206. package/src/components/customerPortal/usage/featureUsage/EntitlementCTAButton.tsx +0 -62
  207. package/src/components/customerPortal/usage/featureUsage/FeatureUsage.helper.ts +0 -45
  208. package/src/components/customerPortal/usage/featureUsage/FeatureUsage.style.ts +0 -13
  209. package/src/components/customerPortal/usage/featureUsage/FeatureUsage.tsx +0 -96
  210. package/src/components/customerPortal/usage/featureUsage/FeatureUsageProgressBar.tsx +0 -56
  211. package/src/components/guards/BooleanEntitlementGuard.tsx +0 -21
  212. package/src/components/guards/EnumEntitlementGuard.tsx +0 -17
  213. package/src/components/guards/MeteredEntitlementGuard.tsx +0 -21
  214. package/src/components/guards/NumericEntitlementGuard.tsx +0 -21
  215. package/src/components/hooks/index.ts +0 -1
  216. package/src/components/hooks/useChargeSort.ts +0 -17
  217. package/src/components/hooks/useIsScreenWiderThan.ts +0 -6
  218. package/src/components/hooks/useWaitForCheckoutCompleted.ts +0 -65
  219. package/src/components/paywall/BillingPeriodPicker.tsx +0 -90
  220. package/src/components/paywall/EntitlementRow.tsx +0 -127
  221. package/src/components/paywall/Paywall.tsx +0 -189
  222. package/src/components/paywall/PaywallContainer.tsx +0 -119
  223. package/src/components/paywall/PaywallLoader.tsx +0 -96
  224. package/src/components/paywall/PlanCompatibleAddons.tsx +0 -127
  225. package/src/components/paywall/PlanEntitlements.tsx +0 -75
  226. package/src/components/paywall/PlanOffering.tsx +0 -256
  227. package/src/components/paywall/PlanOfferingButton.tsx +0 -232
  228. package/src/components/paywall/PlanPrice.tsx +0 -154
  229. package/src/components/paywall/hooks/useLoadPaywallData.ts +0 -75
  230. package/src/components/paywall/index.ts +0 -5
  231. package/src/components/paywall/paywallTextOverrides.ts +0 -79
  232. package/src/components/paywall/types.ts +0 -80
  233. package/src/components/paywall/utils/calculateTrialDaysLeft.ts +0 -5
  234. package/src/components/paywall/utils/calculateUnitQuantityText.ts +0 -23
  235. package/src/components/paywall/utils/computeDefaultBillingPeriod.ts +0 -36
  236. package/src/components/paywall/utils/getPlansToDisplay.ts +0 -13
  237. package/src/components/paywall/utils/hasPricePoints.ts +0 -10
  238. package/src/components/paywall/utils/mapPaywallData.ts +0 -126
  239. package/src/components/utils/calculateDiscountRate.ts +0 -49
  240. package/src/components/utils/currencyUtils.ts +0 -38
  241. package/src/components/utils/dateUtils.ts +0 -17
  242. package/src/components/utils/fixtures/price.fixtures.ts +0 -42
  243. package/src/components/utils/formatNumber.ts +0 -5
  244. package/src/components/utils/getFeatureName.ts +0 -26
  245. package/src/components/utils/getPaidPriceText.ts +0 -77
  246. package/src/components/utils/getPlanPrice.ts +0 -62
  247. package/src/components/utils/getSubscriptionScheduleUpdateTexts.tsx +0 -88
  248. package/src/components/utils/numberUtils.ts +0 -6
  249. package/src/components/utils/onWheelBlur.ts +0 -3
  250. package/src/components/utils/planPrices.ts +0 -10
  251. package/src/components/utils/priceTierUtils.spec.ts +0 -84
  252. package/src/components/utils/priceTierUtils.ts +0 -250
  253. package/src/components/utils/priceUtils.ts +0 -11
  254. package/src/custom.d.ts +0 -6
  255. package/src/hooks/index.ts +0 -8
  256. package/src/hooks/useActiveSubscriptions.ts +0 -21
  257. package/src/hooks/useBooleanEntitlement.ts +0 -20
  258. package/src/hooks/useCustomerPortal.ts +0 -21
  259. package/src/hooks/useEnumEntitlement.ts +0 -20
  260. package/src/hooks/useFetch.ts +0 -32
  261. package/src/hooks/useMeteredEntitlement.ts +0 -20
  262. package/src/hooks/useNumericEntitlement.ts +0 -20
  263. package/src/hooks/usePaywall.ts +0 -21
  264. package/src/hooks/useStiggContext.ts +0 -13
  265. package/src/index.ts +0 -103
  266. package/src/services/logger.ts +0 -22
  267. package/src/stories/Checkout.stories.tsx +0 -123
  268. package/src/stories/CreditBalance.stories.tsx +0 -248
  269. package/src/stories/CreditGrants.stories.tsx +0 -210
  270. package/src/stories/CreditUsageChart.stories.tsx +0 -347
  271. package/src/stories/CreditUtilization.stories.tsx +0 -287
  272. package/src/stories/CustomTheme.ts +0 -57
  273. package/src/stories/CustomerPortal.stories.tsx +0 -265
  274. package/src/stories/GenericTable.stories.tsx +0 -263
  275. package/src/stories/Paywall.stories.tsx +0 -147
  276. package/src/stories/ProgressBar.stories.tsx +0 -103
  277. package/src/stories/StatusChip.stories.tsx +0 -154
  278. package/src/stories/baseArgs.ts +0 -10
  279. package/src/stories/mocks/checkout/consts.ts +0 -15
  280. package/src/stories/mocks/checkout/mockCheckoutPreview.ts +0 -152
  281. package/src/stories/mocks/checkout/mockCheckoutState.ts +0 -212
  282. package/src/styles.css +0 -46
  283. package/src/theme/Fonts.tsx +0 -80
  284. package/src/theme/Theme.tsx +0 -64
  285. package/src/theme/emotion.d.ts +0 -17
  286. package/src/theme/getResolvedTheme.ts +0 -135
  287. package/src/theme/types.ts +0 -85
  288. package/src/types.ts +0 -22
  289. package/src/utils/styledUtils.ts +0 -64
@@ -1,13 +0,0 @@
1
- import { BillingPeriod, PricingType } from '@stigg/js-client-sdk';
2
- import { ShouldHidePlanFn, PaywallPlan } from '../types';
3
- import { hasPricePoints } from './hasPricePoints';
4
-
5
- export function getPlansToDisplay(
6
- plans: PaywallPlan[],
7
- selectedBillingPeriod: BillingPeriod,
8
- shouldHidePlan?: ShouldHidePlanFn,
9
- ): PaywallPlan[] {
10
- return plans
11
- .filter((plan) => plan.pricingType !== PricingType.Paid || hasPricePoints(plan, selectedBillingPeriod))
12
- .filter((plan) => !shouldHidePlan || !shouldHidePlan({ plan }));
13
- }
@@ -1,10 +0,0 @@
1
- import { BillingPeriod } from '@stigg/js-client-sdk';
2
- import { PaywallPlan } from '../types';
3
-
4
- export function hasPricePoints(plan: PaywallPlan, billingPeriod: BillingPeriod): boolean {
5
- return plan.pricePoints.some((pricePoint) => pricePoint.billingPeriod === billingPeriod);
6
- }
7
-
8
- export function hasPricePointsForPlans(plans: PaywallPlan[], billingPeriod: BillingPeriod): boolean {
9
- return plans.some((plan) => hasPricePoints(plan, billingPeriod));
10
- }
@@ -1,126 +0,0 @@
1
- import {
2
- BillingPeriod,
3
- SubscriptionStatus,
4
- Paywall,
5
- Plan,
6
- Subscription,
7
- SubscriptionScheduleType,
8
- } from '@stigg/js-client-sdk';
9
- import isNil from 'lodash/isNil';
10
- import sortBy from 'lodash/sortBy';
11
- import { CurrentSubscriptionOverride, CurrentSubscriptionOverrideFn, PaywallPlan } from '../types';
12
- import { calculateTrialDaysLeft } from './calculateTrialDaysLeft';
13
- import { BillingPeriodChangeVariables, DeepPartial, DowngradeChangeVariables } from '../../../types';
14
- import { StiggTheme } from '../../../theme/types';
15
- import { mapPaywallConfiguration } from '../../common/mapExternalTheme';
16
-
17
- function getCustomerSubscriptionDetails(activeSubscriptions?: Subscription[] | null) {
18
- let isCustomerOnTrial = true;
19
- let currentSubscription: Subscription | null =
20
- activeSubscriptions?.find((s) => s.status === SubscriptionStatus.InTrial) || null;
21
- let currentPlan = currentSubscription?.plan;
22
- const trialDaysLeft = currentSubscription?.trialEndDate
23
- ? calculateTrialDaysLeft(currentSubscription.trialEndDate)
24
- : undefined;
25
- if (!currentPlan) {
26
- isCustomerOnTrial = false;
27
- currentSubscription = activeSubscriptions?.find((s) => s.status === SubscriptionStatus.Active) || null;
28
- currentPlan = currentSubscription?.plan;
29
- }
30
-
31
- return {
32
- currentSubscription,
33
- currentPlan,
34
- isCustomerOnTrial,
35
- trialDaysLeft,
36
- };
37
- }
38
-
39
- type PaywallData = {
40
- currentPlan?: Plan;
41
- currentSubscription: Subscription | null;
42
- currentSubscriptionOverride: CurrentSubscriptionOverride | null | undefined;
43
- isCustomerOnTrial: boolean;
44
- plans: PaywallPlan[];
45
- paywallConfiguration?: DeepPartial<StiggTheme>;
46
- };
47
-
48
- export function mapPaywallData(
49
- paywall: Paywall | null,
50
- showOnlyEligiblePlans?: boolean,
51
- currentSubscriptionOverrideFn?: CurrentSubscriptionOverrideFn,
52
- ): PaywallData {
53
- const { plans, currency, configuration, customer, activeSubscriptions, paywallCalculatedPricePoints } = paywall || {};
54
- const { currentSubscription, currentPlan, isCustomerOnTrial, trialDaysLeft } =
55
- getCustomerSubscriptionDetails(activeSubscriptions);
56
-
57
- const currentSubscriptionOverride = currentSubscriptionOverrideFn?.({ currentSubscription });
58
-
59
- const scheduledUpdates = currentSubscription?.scheduledUpdates || [];
60
- const currentCustomerPlanBillingPeriod = currentSubscription?.price?.billingPeriod;
61
- const downgradeSchedule = scheduledUpdates.find(
62
- ({ subscriptionScheduleType }) => subscriptionScheduleType === SubscriptionScheduleType.Downgrade,
63
- );
64
- const billingChangedSchedule = scheduledUpdates.find(
65
- ({ subscriptionScheduleType }) => subscriptionScheduleType === SubscriptionScheduleType.BillingPeriod,
66
- );
67
-
68
- let paywallPlans: PaywallPlan[] = sortBy(plans, (plan) => plan.order).map((plan) => {
69
- const eligibleForProductTrial = customer?.eligibleForTrial?.find(
70
- (productTrial) => productTrial.productId === plan.product.id,
71
- );
72
- const isCurrentCustomerPlan = currentSubscriptionOverride?.planId
73
- ? currentSubscriptionOverride?.planId === plan.id
74
- : plan.id === currentPlan?.id;
75
-
76
- const isNextPlan = (currentBillingPeriod: BillingPeriod) => {
77
- const downgradeVariables = downgradeSchedule?.scheduleVariables as DowngradeChangeVariables;
78
- const billingChangedVariables = billingChangedSchedule?.scheduleVariables as BillingPeriodChangeVariables;
79
- const isPlanHasBillingPeriodPrice = plan.pricePoints.some(
80
- (price) => price.billingPeriod === currentBillingPeriod,
81
- );
82
-
83
- return downgradeSchedule
84
- ? downgradeSchedule.targetPackage?.refId === plan.id &&
85
- (!isPlanHasBillingPeriodPrice || downgradeVariables.billingPeriod === currentBillingPeriod)
86
- : billingChangedSchedule && isCurrentCustomerPlan
87
- ? billingChangedVariables.billingPeriod === currentBillingPeriod
88
- : false;
89
- };
90
-
91
- return {
92
- ...plan,
93
- paywallCalculatedPricePoints: paywallCalculatedPricePoints?.filter((pricePoint) => pricePoint.planId === plan.id),
94
- isTriable: !isNil(plan.defaultTrialConfig) && (!eligibleForProductTrial || eligibleForProductTrial.eligible),
95
- isCurrentCustomerPlan,
96
- currentCustomerPlanBillingPeriod,
97
- isUpcomingPlan: false,
98
- trialDaysLeft,
99
- isNextPlan,
100
- paywallCurrency: currency,
101
- scheduledUpdate: downgradeSchedule || billingChangedSchedule,
102
- };
103
- });
104
- if (plans && currentPlan) {
105
- const currentPlanOrder = currentPlan && plans?.find((x) => x.id === currentPlan?.id)?.order;
106
- if (!isNil(currentPlanOrder)) {
107
- paywallPlans = paywallPlans.map<PaywallPlan>((plan) => ({
108
- ...plan,
109
- isLowerThanCurrentPlan: currentPlanOrder > plan.order,
110
- }));
111
- if (showOnlyEligiblePlans) {
112
- paywallPlans = paywallPlans.filter((plan) => plan.order >= currentPlanOrder);
113
- }
114
- }
115
- }
116
- const paywallConfiguration = configuration ? mapPaywallConfiguration(configuration) : undefined;
117
-
118
- return {
119
- currentPlan,
120
- currentSubscription,
121
- currentSubscriptionOverride,
122
- isCustomerOnTrial,
123
- plans: paywallPlans,
124
- paywallConfiguration,
125
- };
126
- }
@@ -1,49 +0,0 @@
1
- import { BillingPeriod, PaywallCalculatedPricePoint, Price } from '@stigg/js-client-sdk';
2
- import isNil from 'lodash/isNil';
3
- import { PaywallPlan } from '../paywall';
4
- import { calculateTierPrice } from './priceTierUtils';
5
-
6
- export function calculateDiscountRate(monthlyPrice?: number | null, annuallyPrice?: number | null) {
7
- if (!isNil(monthlyPrice) && !isNil(annuallyPrice)) {
8
- const annuallyPerMonthPrice = annuallyPrice / 12;
9
- return Math.round(((monthlyPrice - annuallyPerMonthPrice) / monthlyPrice) * 100);
10
- }
11
-
12
- return null;
13
- }
14
-
15
- function getPlanBillingPeriodAmount(plan: PaywallPlan, billingPeriod: BillingPeriod) {
16
- let pricePoint: PaywallCalculatedPricePoint | Price | undefined;
17
-
18
- pricePoint = plan.paywallCalculatedPricePoints?.find((price) => price.billingPeriod === billingPeriod);
19
-
20
- if (!pricePoint) {
21
- pricePoint = plan.pricePoints.find((price) => price.billingPeriod === billingPeriod);
22
- }
23
-
24
- if (!pricePoint?.amount) {
25
- const tieredPrice = plan.pricePoints.find((price) => {
26
- return price.isTieredPrice && price.billingPeriod === billingPeriod;
27
- });
28
-
29
- if (tieredPrice) {
30
- return calculateTierPrice(tieredPrice, 1);
31
- }
32
- }
33
-
34
- return pricePoint?.amount;
35
- }
36
-
37
- export function calculatePaywallDiscountRate(plans: PaywallPlan[]) {
38
- return plans.reduce((maxDiscount, plan) => {
39
- const monthlyAmount = getPlanBillingPeriodAmount(plan, BillingPeriod.Monthly);
40
- const annuallyAmount = getPlanBillingPeriodAmount(plan, BillingPeriod.Annually);
41
-
42
- const discountRate = calculateDiscountRate(monthlyAmount, annuallyAmount);
43
- if (discountRate) {
44
- maxDiscount = Math.max(maxDiscount, discountRate);
45
- }
46
-
47
- return maxDiscount;
48
- }, 0);
49
- }
@@ -1,38 +0,0 @@
1
- import { Currency } from '@stigg/js-client-sdk';
2
- import getSymbolFromCurrency from 'currency-symbol-map';
3
-
4
- export const currencyPriceFormatter = ({
5
- amount,
6
- currency = Currency.Usd,
7
- locale,
8
- maximumFractionDigits = 5,
9
- minimumFractionDigits = 0,
10
- removeTrailingZero,
11
- }: {
12
- amount: number;
13
- currency?: Currency | string;
14
- locale?: string;
15
- maximumFractionDigits?: number;
16
- minimumFractionDigits?: number;
17
- removeTrailingZero?: boolean;
18
- }) => {
19
- const currencyString = currency.toString();
20
- const currencySymbol = getSymbolFromCurrency(currencyString);
21
- let formattedPrice = new Intl.NumberFormat(locale, {
22
- maximumFractionDigits,
23
- minimumFractionDigits,
24
- style: 'currency',
25
- currency: currencyString,
26
- trailingZeroDisplay: removeTrailingZero ? 'stripIfInteger' : 'auto',
27
- ...(currencySymbol ? { currencyDisplay: 'code' } : {}),
28
- } as Intl.NumberFormatOptions).format(amount || 0);
29
-
30
- if (currencySymbol) {
31
- formattedPrice = formattedPrice.replace(currencyString, currencySymbol);
32
- }
33
-
34
- // remove space between currency symbol and price
35
- formattedPrice = formattedPrice.replace(/\s/g, '');
36
-
37
- return formattedPrice;
38
- };
@@ -1,17 +0,0 @@
1
- import moment, { MomentInput } from 'moment';
2
-
3
- /**
4
- * Formats a date with time in the format "MMM D, YYYY h:mmA"
5
- * Example: "Aug 2, 2025 3:45PM"
6
- */
7
- export function formatDateTime(date: any): string {
8
- return moment(date as MomentInput).format('MMM D, YYYY h:mmA');
9
- }
10
-
11
- /**
12
- * Formats a date without time in the format "MMM D, YYYY"
13
- * Example: "Aug 2, 2025"
14
- */
15
- export function formatDateOnly(date: any): string {
16
- return moment(date as MomentInput).format('MMM D, YYYY');
17
- }
@@ -1,42 +0,0 @@
1
- import { Currency, Price, TiersMode } from '@stigg/js-client-sdk';
2
-
3
- export const money = (amount: number, currency: Currency) => ({ amount, currency });
4
-
5
- export const priceTiersFlat = (tiersMode: TiersMode, currency: Currency): Pick<Price, 'tiers' | 'tiersMode'> => {
6
- return {
7
- tiersMode,
8
- tiers: [
9
- {
10
- upTo: 10,
11
- flatPrice: money(100, currency),
12
- },
13
- {
14
- upTo: 20,
15
- flatPrice: money(180, currency),
16
- },
17
- {
18
- upTo: 30,
19
- flatPrice: money(240, currency),
20
- },
21
- ],
22
- };
23
- };
24
-
25
- export const priceTiersUnit = (tiersMode: TiersMode, currency: Currency): Pick<Price, 'tiers' | 'tiersMode'> => {
26
- return {
27
- tiersMode,
28
- tiers: [
29
- {
30
- upTo: 10,
31
- unitPrice: money(10, currency),
32
- },
33
- {
34
- upTo: 20,
35
- unitPrice: money(9, currency),
36
- },
37
- {
38
- unitPrice: money(8, currency),
39
- },
40
- ],
41
- };
42
- };
@@ -1,5 +0,0 @@
1
- export function formatNumber(usageLimit: number | null | undefined) {
2
- return usageLimit?.toLocaleString('en-US', {
3
- maximumFractionDigits: 0,
4
- });
5
- }
@@ -1,26 +0,0 @@
1
- import { FeatureFragment } from '@stigg/api-client-js/src/generated/sdk';
2
- import lowercase from 'lodash/lowerCase';
3
-
4
- export function getFeatureDisplayNameText(
5
- featureDisplayName: string,
6
- featureUnits: string | undefined | null,
7
- featureUnitsPlural: string | undefined | null,
8
- ) {
9
- if (!featureUnits && !featureUnitsPlural) {
10
- return featureDisplayName;
11
- }
12
-
13
- const displayNameLowerCase = lowercase(featureDisplayName);
14
- if (
15
- displayNameLowerCase === lowercase(featureUnits || '') ||
16
- displayNameLowerCase === lowercase(featureUnitsPlural || '')
17
- ) {
18
- return featureDisplayName;
19
- }
20
-
21
- return `${featureDisplayName} (${featureUnitsPlural})`;
22
- }
23
-
24
- export function getFeatureDisplayName(feature: FeatureFragment) {
25
- return getFeatureDisplayNameText(feature.displayName, feature.featureUnits, feature.featureUnitsPlural);
26
- }
@@ -1,77 +0,0 @@
1
- import { BillingModel, BillingPeriod, PaywallCalculatedPricePoint, Price } from '@stigg/js-client-sdk';
2
- import { currencyPriceFormatter } from './currencyUtils';
3
- import { PlanPriceText } from './getPlanPrice';
4
- import { calculateTierPrice, getPriceFeatureUnit } from './priceTierUtils';
5
- import { PaywallLocalization } from '../paywall';
6
- import { numberFormatter } from './numberUtils';
7
-
8
- type GetPaidPriceTextParams = {
9
- planPrices: Price[];
10
- paywallCalculatedPrice?: PaywallCalculatedPricePoint;
11
- selectedBillingPeriod: BillingPeriod;
12
- locale: string;
13
- shouldShowMonthlyPriceAmount: boolean;
14
- paywallLocale: PaywallLocalization;
15
- perUnitQuantityByFeature?: Record<string, number>;
16
- };
17
-
18
- export function getPaidPriceText({
19
- planPrices,
20
- paywallCalculatedPrice,
21
- selectedBillingPeriod,
22
- locale,
23
- shouldShowMonthlyPriceAmount,
24
- paywallLocale,
25
- perUnitQuantityByFeature,
26
- }: GetPaidPriceTextParams): PlanPriceText {
27
- const { amount, currency } = paywallCalculatedPrice || planPrices[0];
28
- const priceAmount = amount || 0;
29
-
30
- const isSinglePrice = planPrices.length === 1;
31
- let priceNumber =
32
- selectedBillingPeriod === BillingPeriod.Annually && shouldShowMonthlyPriceAmount ? priceAmount / 12 : priceAmount;
33
-
34
- let tiers;
35
- let tierUnits;
36
- const pricePeriod = paywallLocale.price.pricePeriod(
37
- shouldShowMonthlyPriceAmount ? BillingPeriod.Monthly : BillingPeriod.Annually,
38
- );
39
- let unit = pricePeriod;
40
-
41
- for (const price of planPrices) {
42
- if (price.isTieredPrice && price.tiers) {
43
- const quantity = perUnitQuantityByFeature?.[price.feature!.featureId] || 1;
44
- tiers = price.tiers;
45
- tierUnits = getPriceFeatureUnit(price);
46
-
47
- priceNumber += calculateTierPrice(price, quantity, selectedBillingPeriod, shouldShowMonthlyPriceAmount);
48
- }
49
- }
50
-
51
- if (isSinglePrice) {
52
- const price = planPrices[0];
53
- const formattedUnits =
54
- price.blockSize && price.blockSize > 1
55
- ? `for ${numberFormatter(price.blockSize)} ${price.feature?.unitsPlural || price.feature?.units || ''}`
56
- : `per ${price.feature?.units || ''}`;
57
-
58
- if (price.pricingModel === BillingModel.PerUnit && !price.isTieredPrice) {
59
- unit = `${formattedUnits} ${pricePeriod}`;
60
- } else if (price.pricingModel === BillingModel.UsageBased) {
61
- unit = `${formattedUnits}`;
62
- }
63
- }
64
-
65
- return {
66
- price: currencyPriceFormatter({
67
- amount: priceNumber,
68
- currency,
69
- locale,
70
- minimumFractionDigits: 2,
71
- removeTrailingZero: true,
72
- }),
73
- unit,
74
- tiers,
75
- tierUnits,
76
- };
77
- }
@@ -1,62 +0,0 @@
1
- import { BillingPeriod, PriceTierFragment, PricingType } from '@stigg/js-client-sdk';
2
- import { getPaidPriceText } from './getPaidPriceText';
3
- import { PaywallPlan, PaywallLocalization } from '../paywall';
4
-
5
- export type PlanPriceText = {
6
- price: string;
7
- unit?: string;
8
- tiers?: PriceTierFragment[] | null | undefined;
9
- tierUnits?: string;
10
- };
11
-
12
- export function getPlanPrice(
13
- plan: PaywallPlan,
14
- billingPeriod: BillingPeriod,
15
- paywallLocale: PaywallLocalization,
16
- locale: string,
17
- shouldShowMonthlyPriceAmount: boolean,
18
- perUnitQuantityByFeature?: Record<string, number>,
19
- ): PlanPriceText {
20
- switch (plan.pricingType) {
21
- case PricingType.Free:
22
- if (typeof paywallLocale.price.free === 'function') {
23
- return paywallLocale.price.free(plan.paywallCurrency);
24
- }
25
-
26
- return paywallLocale.price.free;
27
- case PricingType.Custom:
28
- return {
29
- price:
30
- typeof paywallLocale.price.custom === 'function'
31
- ? paywallLocale.price.custom({ plan, selectedBillingPeriod: billingPeriod })
32
- : paywallLocale.price.custom,
33
- };
34
- case PricingType.Paid: {
35
- const planPrices = plan.pricePoints.filter((pricePoint) => pricePoint.billingPeriod === billingPeriod);
36
- const paywallCalculatedPrice = plan.paywallCalculatedPricePoints?.find(
37
- (pricePoint) => pricePoint.billingPeriod === billingPeriod,
38
- );
39
-
40
- if (!planPrices?.length && !paywallCalculatedPrice) {
41
- return {
42
- price: paywallLocale.price.priceNotSet,
43
- };
44
- }
45
-
46
- const paidParams = {
47
- planPrices,
48
- paywallCalculatedPrice,
49
- selectedBillingPeriod: billingPeriod,
50
- perUnitQuantityByFeature: perUnitQuantityByFeature || {},
51
- };
52
-
53
- return paywallLocale.price.paid
54
- ? paywallLocale.price.paid({ ...paidParams, plan })
55
- : getPaidPriceText({ ...paidParams, locale, shouldShowMonthlyPriceAmount, paywallLocale });
56
- }
57
- default:
58
- return {
59
- price: '',
60
- };
61
- }
62
- }
@@ -1,88 +0,0 @@
1
- import moment, { MomentInput } from 'moment';
2
- import { isNil, compact } from 'lodash';
3
- import {
4
- CustomerPortalSubscription,
5
- CustomerPortalSubscriptionScheduledUpdateDataFragment,
6
- SubscriptionScheduleType,
7
- } from '@stigg/js-client-sdk';
8
- import { CustomerPortalSubscriptionPriceFragment } from '@stigg/api-client-js/src/generated/sdk';
9
- import { BillingPeriodChangeVariables, UnitAmountChangeVariables } from '../../types';
10
- import { FeatureType } from '../customerPortal/subscriptionOverview/types/customerPortal.types';
11
-
12
- const formatDate = (date: string) => moment.utc(date).format('MMMM Do, yyyy');
13
-
14
- type GetSubscriptionScheduleUpdateTextsProps = {
15
- scheduledUpdate: CustomerPortalSubscriptionScheduledUpdateDataFragment | undefined;
16
- subscriptionPrices?: CustomerPortalSubscriptionPriceFragment[];
17
- billingPeriodRange?: CustomerPortalSubscription['billingPeriodRange'];
18
- options?: { withDate?: boolean; postfix?: string };
19
- };
20
-
21
- export function getSubscriptionScheduleUpdateTexts({
22
- scheduledUpdate,
23
- subscriptionPrices,
24
- billingPeriodRange,
25
- options = {},
26
- }: GetSubscriptionScheduleUpdateTextsProps) {
27
- if (!scheduledUpdate) {
28
- return {};
29
- }
30
- const { withDate, postfix = '' } = options;
31
-
32
- switch (scheduledUpdate.subscriptionScheduleType) {
33
- case SubscriptionScheduleType.Downgrade: {
34
- let shouldShowDate = withDate;
35
- if (isNil(shouldShowDate) && billingPeriodRange?.end) {
36
- shouldShowDate = !moment(scheduledUpdate.scheduledExecutionTime as MomentInput).isSame(
37
- billingPeriodRange?.end as MomentInput,
38
- 'day',
39
- );
40
- }
41
-
42
- const line1 = (
43
- <>
44
- Your subscription will be downgraded to the <b>{scheduledUpdate.targetPackage?.displayName} plan</b>{' '}
45
- {shouldShowDate ? <>on {formatDate(scheduledUpdate.scheduledExecutionTime as string)}</> : postfix}.
46
- </>
47
- );
48
- const line2 = `Until then you still have access to your current plan.`;
49
-
50
- return { line1, line2 };
51
- }
52
-
53
- case SubscriptionScheduleType.BillingPeriod: {
54
- const variables = scheduledUpdate.scheduleVariables as BillingPeriodChangeVariables;
55
- const line1 = (
56
- <>
57
- Your billing cycle will change to <b>{variables.billingPeriod?.toLocaleLowerCase()}</b>{' '}
58
- {withDate ? <>on {formatDate(scheduledUpdate.scheduledExecutionTime as string)}</> : postfix}.
59
- </>
60
- );
61
-
62
- return { line1 };
63
- }
64
-
65
- case SubscriptionScheduleType.UnitAmount: {
66
- const variables = scheduledUpdate.scheduleVariables as UnitAmountChangeVariables;
67
- const features: FeatureType[] = compact(subscriptionPrices?.map(({ feature }) => feature));
68
- const feature = features.find(({ id }) => id === variables.featureId);
69
- const { featureUnits, featureUnitsPlural } = feature || {};
70
- const unitsText = variables.newUnitAmount === 1 ? featureUnits : featureUnitsPlural;
71
-
72
- const line1 = (
73
- <>
74
- Your subscription will be updated to <b>{variables.newUnitAmount}</b> {unitsText}{' '}
75
- {withDate ? <>on {formatDate(scheduledUpdate.scheduledExecutionTime as string)}</> : postfix}.
76
- </>
77
- );
78
-
79
- const line2 = `Until then you still have access to your current ${featureUnits} count.`;
80
-
81
- return { line1, line2 };
82
- }
83
-
84
- default: {
85
- return {};
86
- }
87
- }
88
- }
@@ -1,6 +0,0 @@
1
- export function numberFormatter(
2
- number: number,
3
- { locale, maximumFractionDigits }: { locale?: string; maximumFractionDigits?: number } = {},
4
- ) {
5
- return new Intl.NumberFormat(locale, { maximumFractionDigits }).format(number);
6
- }
@@ -1,3 +0,0 @@
1
- import React from 'react';
2
-
3
- export const ON_WHEEL_BLUR = (e: React.WheelEvent<HTMLInputElement>) => (e.target as HTMLElement).blur();
@@ -1,10 +0,0 @@
1
- import { Plan } from '@stigg/js-client-sdk';
2
- import { BillingPeriod } from '@stigg/api-client-js/src/generated/sdk';
3
-
4
- export const hasMonthlyPrices = (plan?: Plan) =>
5
- !!plan?.pricePoints.some((pricePoint) => pricePoint.billingPeriod === BillingPeriod.Monthly);
6
-
7
- export const hasAnnualPrices = (plan?: Plan) =>
8
- !!plan?.pricePoints.some((pricePoint) => pricePoint.billingPeriod === BillingPeriod.Annually);
9
-
10
- export const hasMultipleBillingPeriods = (plan?: Plan) => hasMonthlyPrices(plan) && hasAnnualPrices(plan);
@@ -1,84 +0,0 @@
1
- import { Currency, TiersMode } from '@stigg/js-client-sdk';
2
- import { priceTiersFlat, priceTiersUnit } from './fixtures/price.fixtures';
3
- import { calculateTierPrice, calculateTierPriceGraduated } from './priceTierUtils';
4
-
5
- describe('getPrice tests', () => {
6
- describe('volume flat price', () => {
7
- test('should get total price', () => {
8
- const price = priceTiersFlat(TiersMode.Volume, Currency.Usd);
9
- expect(calculateTierPrice(price, 1)).toEqual(100);
10
- expect(calculateTierPrice(price, 3)).toEqual(100);
11
- expect(calculateTierPrice(price, 7)).toEqual(100);
12
- expect(calculateTierPrice(price, 10)).toEqual(100);
13
- expect(calculateTierPrice(price, 11)).toEqual(180);
14
- expect(calculateTierPrice(price, 14)).toEqual(180);
15
- expect(calculateTierPrice(price, 20)).toEqual(180);
16
- expect(calculateTierPrice(price, 21)).toEqual(240);
17
- expect(calculateTierPrice(price, 25)).toEqual(240);
18
- expect(calculateTierPrice(price, 30)).toEqual(240);
19
-
20
- // questionable behaviour, but that's the current implementation :)
21
- expect(calculateTierPrice(price, 35)).toEqual(240);
22
- expect(calculateTierPrice(price, 250)).toEqual(240);
23
- });
24
- });
25
-
26
- describe('volume per unit', () => {
27
- test('should get total price', () => {
28
- const price = priceTiersUnit(TiersMode.Volume, Currency.Usd);
29
- expect(calculateTierPrice(price, 1)).toEqual(10);
30
- expect(calculateTierPrice(price, 3)).toEqual(30);
31
- expect(calculateTierPrice(price, 7)).toEqual(70);
32
- expect(calculateTierPrice(price, 10)).toEqual(100);
33
- expect(calculateTierPrice(price, 11)).toEqual(99);
34
- expect(calculateTierPrice(price, 14)).toEqual(126);
35
- expect(calculateTierPrice(price, 20)).toEqual(180);
36
- expect(calculateTierPrice(price, 21)).toEqual(168);
37
- expect(calculateTierPrice(price, 25)).toEqual(200);
38
- expect(calculateTierPrice(price, 30)).toEqual(240);
39
- expect(calculateTierPrice(price, 35)).toEqual(280);
40
- expect(calculateTierPrice(price, 240)).toEqual(1_920);
41
- });
42
- });
43
-
44
- describe('graduated', () => {
45
- test('should get total price', () => {
46
- const price = priceTiersUnit(TiersMode.Graduated, Currency.Usd);
47
- expect(calculateTierPrice(price, 1)).toEqual(10);
48
- expect(calculateTierPrice(price, 3)).toEqual(30);
49
- expect(calculateTierPrice(price, 7)).toEqual(70);
50
- expect(calculateTierPrice(price, 10)).toEqual(100);
51
- expect(calculateTierPrice(price, 11)).toEqual(109);
52
- expect(calculateTierPrice(price, 14)).toEqual(136);
53
- expect(calculateTierPrice(price, 20)).toEqual(190);
54
- expect(calculateTierPrice(price, 21)).toEqual(198);
55
- expect(calculateTierPrice(price, 25)).toEqual(230);
56
- expect(calculateTierPrice(price, 30)).toEqual(270);
57
- expect(calculateTierPrice(price, 35)).toEqual(310);
58
- expect(calculateTierPrice(price, 240)).toEqual(1_950);
59
- });
60
-
61
- test('should return nested breakdown', () => {
62
- const price = priceTiersUnit(TiersMode.Graduated, Currency.Usd);
63
-
64
- const result1 = calculateTierPriceGraduated(price.tiers!, 10);
65
- expect(result1.total).toEqual(100);
66
- expect(result1.breakdown).toEqual([{ unitQuantity: 10, amount: 100 }]);
67
-
68
- const result2 = calculateTierPriceGraduated(price.tiers!, 13);
69
- expect(result2.total).toEqual(127);
70
- expect(result2.breakdown).toEqual([
71
- { unitQuantity: 10, amount: 100 },
72
- { unitQuantity: 3, amount: 27 },
73
- ]);
74
-
75
- const result3 = calculateTierPriceGraduated(price.tiers!, 35);
76
- expect(result3.total).toEqual(310);
77
- expect(result3.breakdown).toEqual([
78
- { unitQuantity: 10, amount: 100 },
79
- { unitQuantity: 10, amount: 90 },
80
- { unitQuantity: 15, amount: 120 },
81
- ]);
82
- });
83
- });
84
- });