@stigg/react-sdk 4.3.0-beta.1 → 4.3.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 (169) hide show
  1. package/README.md +1 -1
  2. package/dist/components/common/Icon.d.ts +2 -3
  3. package/dist/components/common/PoweredByStigg.d.ts +1 -1
  4. package/dist/components/common/customIcons.d.ts +5 -17
  5. package/dist/components/common/mapExternalTheme.d.ts +1 -2
  6. package/dist/components/customerPortal/subscriptionOverview/tabs/SubscriptionTabs.d.ts +1 -1
  7. package/dist/components/{common/TiersSelectContainer.d.ts → paywall/TiersLayout.d.ts} +3 -2
  8. package/dist/components/paywall/paywallTextOverrides.d.ts +2 -0
  9. package/dist/components/{utils/priceTierUtils.d.ts → paywall/planPriceTier.d.ts} +1 -3
  10. package/dist/components/utils/calculateDiscountRate.d.ts +0 -1
  11. package/dist/components/utils/currencyUtils.d.ts +1 -1
  12. package/dist/index.d.ts +0 -1
  13. package/dist/react-sdk.cjs.development.js +207 -3479
  14. package/dist/react-sdk.cjs.development.js.map +1 -1
  15. package/dist/react-sdk.cjs.production.min.js +1 -1
  16. package/dist/react-sdk.cjs.production.min.js.map +1 -1
  17. package/dist/react-sdk.esm.js +213 -3619
  18. package/dist/react-sdk.esm.js.map +1 -1
  19. package/dist/stories/CustomerPortal.stories.d.ts +1 -1
  20. package/dist/theme/getResolvedTheme.d.ts +0 -1
  21. package/dist/theme/types.d.ts +0 -1
  22. package/package.json +22 -11
  23. package/src/components/StiggProvider.tsx +2 -0
  24. package/src/components/common/Icon.tsx +22 -17
  25. package/src/components/common/PoweredByStigg.tsx +1 -1
  26. package/src/components/common/Typography.tsx +1 -11
  27. package/src/components/common/customIcons.ts +28 -17
  28. package/src/components/common/mapExternalTheme.ts +8 -24
  29. package/src/components/customerPortal/subscriptionOverview/tabs/SubscriptionTabs.tsx +12 -6
  30. package/src/components/paywall/Paywall.tsx +1 -1
  31. package/src/components/paywall/PlanOffering.tsx +1 -1
  32. package/src/components/paywall/PlanOfferingButton.tsx +1 -1
  33. package/src/components/paywall/PlanPrice.tsx +13 -5
  34. package/src/components/{common/TiersSelectContainer.tsx → paywall/TiersLayout.tsx} +7 -8
  35. package/src/components/paywall/paywallTextOverrides.ts +1 -0
  36. package/src/components/{utils/priceTierUtils.ts → paywall/planPriceTier.ts} +3 -25
  37. package/src/components/paywall/utils/calculateUnitQuantityText.ts +4 -9
  38. package/src/components/utils/calculateDiscountRate.ts +1 -1
  39. package/src/components/utils/currencyUtils.ts +1 -1
  40. package/src/components/utils/getPaidPriceText.ts +2 -2
  41. package/src/index.ts +0 -1
  42. package/src/stories/CustomerPortal.stories.tsx +12 -12
  43. package/src/stories/Paywall.stories.tsx +4 -6
  44. package/src/stories/baseArgs.ts +1 -1
  45. package/src/theme/Fonts.tsx +1 -1
  46. package/src/theme/Theme.tsx +7 -9
  47. package/src/theme/getResolvedTheme.ts +0 -1
  48. package/src/theme/types.ts +0 -1
  49. package/dist/components/checkout/Checkout.d.ts +0 -5
  50. package/dist/components/checkout/CheckoutContainer.d.ts +0 -22
  51. package/dist/components/checkout/CheckoutContainer.style.d.ts +0 -26
  52. package/dist/components/checkout/CheckoutProvider.d.ts +0 -35
  53. package/dist/components/checkout/CheckoutSummary.d.ts +0 -9
  54. package/dist/components/checkout/components/Button.d.ts +0 -6
  55. package/dist/components/checkout/components/InputField.d.ts +0 -8
  56. package/dist/components/checkout/components/index.d.ts +0 -2
  57. package/dist/components/checkout/formatting.d.ts +0 -2
  58. package/dist/components/checkout/hooks/index.d.ts +0 -8
  59. package/dist/components/checkout/hooks/useAddonsStepModel.d.ts +0 -21
  60. package/dist/components/checkout/hooks/useCheckoutModel.d.ts +0 -9
  61. package/dist/components/checkout/hooks/useCouponModel.d.ts +0 -7
  62. package/dist/components/checkout/hooks/useLoadCheckout.d.ts +0 -11
  63. package/dist/components/checkout/hooks/usePaymentStepModel.d.ts +0 -16
  64. package/dist/components/checkout/hooks/usePlanStepModel.d.ts +0 -23
  65. package/dist/components/checkout/hooks/usePreviewSubscription.d.ts +0 -13
  66. package/dist/components/checkout/hooks/useProgressBarModel.d.ts +0 -26
  67. package/dist/components/checkout/hooks/useSubscriptionModel.d.ts +0 -5
  68. package/dist/components/checkout/hooks/useSubscriptionState.d.ts +0 -2
  69. package/dist/components/checkout/index.d.ts +0 -3
  70. package/dist/components/checkout/planHeader/PlanHeader.d.ts +0 -7
  71. package/dist/components/checkout/planHeader/PlanHeader.style.d.ts +0 -25
  72. package/dist/components/checkout/planHeader/index.d.ts +0 -1
  73. package/dist/components/checkout/progressBar/CheckoutProgressBar.d.ts +0 -2
  74. package/dist/components/checkout/progressBar/CheckoutProgressBar.style.d.ts +0 -45
  75. package/dist/components/checkout/promotionCode/AddPromotionCode.d.ts +0 -5
  76. package/dist/components/checkout/promotionCode/AddPromotionCodeButton.d.ts +0 -7
  77. package/dist/components/checkout/promotionCode/AppliedPromotionCode.d.ts +0 -6
  78. package/dist/components/checkout/promotionCode/PromotionCodeSection.d.ts +0 -5
  79. package/dist/components/checkout/promotionCode/index.d.ts +0 -1
  80. package/dist/components/checkout/steps/addons/CheckoutAddonsStep.d.ts +0 -2
  81. package/dist/components/checkout/steps/addons/CheckoutAddonsStep.style.d.ts +0 -93
  82. package/dist/components/checkout/steps/addons/addon.utils.d.ts +0 -15
  83. package/dist/components/checkout/steps/addons/index.d.ts +0 -1
  84. package/dist/components/checkout/steps/payment/PaymentMethods.d.ts +0 -19
  85. package/dist/components/checkout/steps/payment/PaymentMethods.style.d.ts +0 -113
  86. package/dist/components/checkout/steps/payment/PaymentStep.d.ts +0 -2
  87. package/dist/components/checkout/steps/payment/index.d.ts +0 -1
  88. package/dist/components/checkout/steps/payment/stripe/StripePaymentForm.d.ts +0 -2
  89. package/dist/components/checkout/steps/payment/stripe/index.d.ts +0 -3
  90. package/dist/components/checkout/steps/payment/stripe/stripe.utils.d.ts +0 -33
  91. package/dist/components/checkout/steps/payment/stripe/useStripeIntegration.d.ts +0 -5
  92. package/dist/components/checkout/steps/payment/stripe/useSubmit.d.ts +0 -10
  93. package/dist/components/checkout/steps/plan/BillingPeriodPicker.d.ts +0 -9
  94. package/dist/components/checkout/steps/plan/BillingPeriodPicker.style.d.ts +0 -52
  95. package/dist/components/checkout/steps/plan/CheckoutChargeList.d.ts +0 -16
  96. package/dist/components/checkout/steps/plan/CheckoutPlanStep.d.ts +0 -4
  97. package/dist/components/checkout/steps/plan/CheckoutPlanStep.style.d.ts +0 -12
  98. package/dist/components/checkout/steps/plan/index.d.ts +0 -1
  99. package/dist/components/checkout/steps/surprise/SurpriseStep.d.ts +0 -2
  100. package/dist/components/checkout/textOverrides.d.ts +0 -28
  101. package/dist/components/checkout/theme.d.ts +0 -12
  102. package/dist/components/hooks/useChargeSort.d.ts +0 -3
  103. package/dist/components/utils/priceUtils.d.ts +0 -2
  104. package/dist/stories/Checkout.stories.d.ts +0 -3
  105. package/src/assets/arrow-forward.svg +0 -3
  106. package/src/assets/arrow-right.svg +0 -6
  107. package/src/assets/close.svg +0 -3
  108. package/src/assets/nyancat.svg +0 -634
  109. package/src/assets/outlined-checked-circle.svg +0 -6
  110. package/src/assets/outlined-circle.svg +0 -3
  111. package/src/assets/payment-method.svg +0 -11
  112. package/src/assets/plus-icon.svg +0 -6
  113. package/src/assets/trash.svg +0 -8
  114. package/src/components/checkout/Checkout.tsx +0 -30
  115. package/src/components/checkout/CheckoutContainer.style.ts +0 -34
  116. package/src/components/checkout/CheckoutContainer.tsx +0 -88
  117. package/src/components/checkout/CheckoutProvider.tsx +0 -140
  118. package/src/components/checkout/CheckoutSummary.tsx +0 -361
  119. package/src/components/checkout/components/Button.tsx +0 -30
  120. package/src/components/checkout/components/InputField.tsx +0 -22
  121. package/src/components/checkout/components/index.ts +0 -2
  122. package/src/components/checkout/formatting.ts +0 -12
  123. package/src/components/checkout/hooks/index.ts +0 -8
  124. package/src/components/checkout/hooks/useAddonsStepModel.ts +0 -96
  125. package/src/components/checkout/hooks/useCheckoutModel.ts +0 -31
  126. package/src/components/checkout/hooks/useCouponModel.ts +0 -28
  127. package/src/components/checkout/hooks/useLoadCheckout.ts +0 -40
  128. package/src/components/checkout/hooks/usePaymentStepModel.ts +0 -49
  129. package/src/components/checkout/hooks/usePlanStepModel.ts +0 -170
  130. package/src/components/checkout/hooks/usePreviewSubscription.ts +0 -82
  131. package/src/components/checkout/hooks/useProgressBarModel.ts +0 -89
  132. package/src/components/checkout/hooks/useSubscriptionModel.ts +0 -16
  133. package/src/components/checkout/hooks/useSubscriptionState.ts +0 -26
  134. package/src/components/checkout/index.ts +0 -3
  135. package/src/components/checkout/planHeader/PlanHeader.style.tsx +0 -23
  136. package/src/components/checkout/planHeader/PlanHeader.tsx +0 -61
  137. package/src/components/checkout/planHeader/index.ts +0 -1
  138. package/src/components/checkout/progressBar/CheckoutProgressBar.style.ts +0 -29
  139. package/src/components/checkout/progressBar/CheckoutProgressBar.tsx +0 -48
  140. package/src/components/checkout/promotionCode/AddPromotionCode.tsx +0 -85
  141. package/src/components/checkout/promotionCode/AddPromotionCodeButton.tsx +0 -39
  142. package/src/components/checkout/promotionCode/AppliedPromotionCode.tsx +0 -37
  143. package/src/components/checkout/promotionCode/PromotionCodeSection.tsx +0 -27
  144. package/src/components/checkout/promotionCode/index.ts +0 -1
  145. package/src/components/checkout/steps/addons/CheckoutAddonsStep.style.tsx +0 -24
  146. package/src/components/checkout/steps/addons/CheckoutAddonsStep.tsx +0 -125
  147. package/src/components/checkout/steps/addons/addon.utils.ts +0 -68
  148. package/src/components/checkout/steps/addons/index.ts +0 -1
  149. package/src/components/checkout/steps/payment/PaymentMethods.style.ts +0 -26
  150. package/src/components/checkout/steps/payment/PaymentMethods.tsx +0 -83
  151. package/src/components/checkout/steps/payment/PaymentStep.tsx +0 -41
  152. package/src/components/checkout/steps/payment/index.ts +0 -1
  153. package/src/components/checkout/steps/payment/stripe/StripePaymentForm.tsx +0 -43
  154. package/src/components/checkout/steps/payment/stripe/index.ts +0 -3
  155. package/src/components/checkout/steps/payment/stripe/stripe.utils.ts +0 -109
  156. package/src/components/checkout/steps/payment/stripe/useStripeIntegration.ts +0 -27
  157. package/src/components/checkout/steps/payment/stripe/useSubmit.ts +0 -100
  158. package/src/components/checkout/steps/plan/BillingPeriodPicker.style.tsx +0 -46
  159. package/src/components/checkout/steps/plan/BillingPeriodPicker.tsx +0 -63
  160. package/src/components/checkout/steps/plan/CheckoutChargeList.tsx +0 -138
  161. package/src/components/checkout/steps/plan/CheckoutPlanStep.style.tsx +0 -6
  162. package/src/components/checkout/steps/plan/CheckoutPlanStep.tsx +0 -22
  163. package/src/components/checkout/steps/plan/index.ts +0 -1
  164. package/src/components/checkout/steps/surprise/SurpriseStep.tsx +0 -27
  165. package/src/components/checkout/textOverrides.ts +0 -58
  166. package/src/components/checkout/theme.ts +0 -43
  167. package/src/components/hooks/useChargeSort.ts +0 -17
  168. package/src/components/utils/priceUtils.ts +0 -10
  169. package/src/stories/Checkout.stories.tsx +0 -62
@@ -1,361 +0,0 @@
1
- import partition from 'lodash/partition';
2
- import React from 'react';
3
- import styled from '@emotion/styled/macro';
4
- import { Box, CircularProgress, Divider, Grid, Paper, Skeleton } from '@mui/material';
5
- import { BillingModel, BillingPeriod, DiscountType, Price, SubscriptionPreview } from '@stigg/js-client-sdk';
6
- import { PoweredByStigg } from '../common/PoweredByStigg';
7
- import { Typography } from '../common/Typography';
8
- import { useChargesSort } from '../hooks/useChargeSort';
9
- import { currencyPriceFormatter } from '../utils/currencyUtils';
10
- import { Button } from './components';
11
- import {
12
- useCheckoutModel,
13
- useProgressBarModel,
14
- usePreviewSubscription,
15
- useSubscriptionModel,
16
- usePaymentStepModel,
17
- } from './hooks';
18
- import { PromotionCodeSection } from './promotionCode';
19
- import { useSubmit } from './steps/payment/stripe';
20
- import { CheckoutContainerProps } from './CheckoutContainer';
21
- import { getTierByQuantity } from '../utils/priceTierUtils';
22
-
23
- const SummaryCard = styled(Paper)`
24
- border-radius: 10px;
25
- background: ${({ theme }) => theme.stigg.palette.backgroundHighlight};
26
- padding: 16px;
27
- `;
28
-
29
- SummaryCard.defaultProps = {
30
- elevation: 0,
31
- };
32
-
33
- const PlanName = styled(Typography)`
34
- margin-bottom: 16px;
35
- `;
36
-
37
- const LineItemContainer = styled.div`
38
- & + & {
39
- margin-top: 8px;
40
- }
41
- `;
42
-
43
- const LineItemRow = styled.div`
44
- display: flex;
45
- align-items: center;
46
- justify-content: space-between;
47
- `;
48
-
49
- const StyledDivider = styled(Divider)`
50
- margin: 16px 0;
51
- `;
52
-
53
- const SubtotalText = styled(Typography)`
54
- margin-top: 24px;
55
- `;
56
-
57
- const TotalDueText = styled(Typography)`
58
- margin-bottom: 8px;
59
- `;
60
-
61
- export const getPriceString = ({
62
- amountPerMonth,
63
- price,
64
- quantity,
65
- }: {
66
- amountPerMonth: number;
67
- price: Price;
68
- quantity: number;
69
- }) => {
70
- const { billingPeriod } = price;
71
- let billingPeriodString = null;
72
-
73
- if (billingPeriod === BillingPeriod.Annually) {
74
- amountPerMonth = amountPerMonth / 12;
75
- billingPeriodString = '12 months';
76
- }
77
-
78
- const addonPriceFormat = currencyPriceFormatter({ amount: amountPerMonth, currency: price.currency });
79
-
80
- return `${quantity > 1 ? `${quantity} x ${addonPriceFormat} each` : addonPriceFormat}${
81
- billingPeriodString ? ` x ${billingPeriodString}` : ''
82
- }`;
83
- };
84
-
85
- const BilledPriceLineItem = ({ label, quantity, price }: { label: string; quantity: number; price: Price }) => {
86
- const { billingPeriod } = price;
87
-
88
- let amountPerMonth;
89
- if (price.isTieredPrice) {
90
- const tier = getTierByQuantity(price.tiers!, quantity);
91
- amountPerMonth = tier!.unitPrice.amount!;
92
- } else {
93
- amountPerMonth = price.amount!;
94
- }
95
-
96
- return (
97
- <LineItemContainer>
98
- <LineItemRow style={{ alignItems: 'flex-end' }}>
99
- <Grid item>
100
- <Typography variant="h6" color="primary">
101
- {label}
102
- </Typography>
103
- {(quantity > 1 || billingPeriod === BillingPeriod.Annually) && (
104
- <Typography variant="body1" color="secondary">
105
- {getPriceString({ amountPerMonth, price, quantity })}
106
- </Typography>
107
- )}
108
- </Grid>
109
- <Grid item>
110
- <Typography variant="body1" color="secondary" style={{ wordBreak: 'break-word' }}>
111
- {currencyPriceFormatter({ amount: quantity * amountPerMonth, currency: price.currency })}
112
- </Typography>
113
- </Grid>
114
- </LineItemRow>
115
- </LineItemContainer>
116
- );
117
- };
118
-
119
- const DiscountLineItem = ({
120
- subscriptionPreview,
121
- isFetchingSubscriptionPreview,
122
- }: {
123
- subscriptionPreview: SubscriptionPreview | null;
124
- isFetchingSubscriptionPreview: boolean;
125
- }) => {
126
- const { subTotal, discount } = subscriptionPreview || {};
127
- if (!subTotal || !discount) {
128
- return null;
129
- }
130
-
131
- let discountAmount: number;
132
- if (discount.type === DiscountType.Percentage) {
133
- discountAmount = -1 * Math.abs((discount.value / 100) * subTotal.amount);
134
- } else {
135
- discountAmount = -1 * Math.abs(discount.value);
136
- }
137
-
138
- return (
139
- <LineItemContainer>
140
- <LineItemRow>
141
- <Typography variant="body1" color="secondary">
142
- {`Discount${discount.type === DiscountType.Percentage ? ` (${discount.value}% off)` : ''}`}
143
- </Typography>
144
- <Typography variant="body1" color="secondary">
145
- {isFetchingSubscriptionPreview ? (
146
- <Skeleton width={50} height={16} />
147
- ) : (
148
- currencyPriceFormatter({ amount: discountAmount, currency: subTotal.currency })
149
- )}
150
- </Typography>
151
- </LineItemRow>
152
- </LineItemContainer>
153
- );
154
- };
155
-
156
- const TaxLineItem = ({
157
- subscriptionPreview,
158
- isFetchingSubscriptionPreview,
159
- }: {
160
- subscriptionPreview: SubscriptionPreview | null;
161
- isFetchingSubscriptionPreview: boolean;
162
- }) => {
163
- const { tax, taxDetails } = subscriptionPreview || {};
164
- if (!taxDetails || !tax) {
165
- return null;
166
- }
167
-
168
- return (
169
- <LineItemContainer>
170
- <LineItemRow>
171
- <Typography variant="body1" color="secondary">
172
- {`${taxDetails.displayName} (${taxDetails?.percentage}%)`}
173
- </Typography>
174
- <Typography variant="body1" color="secondary">
175
- {isFetchingSubscriptionPreview ? (
176
- <Skeleton width={50} height={16} />
177
- ) : (
178
- currencyPriceFormatter({ amount: tax?.amount, currency: tax?.currency })
179
- )}
180
- </Typography>
181
- </LineItemRow>
182
- </LineItemContainer>
183
- );
184
- };
185
-
186
- export const CheckoutSummary = ({ onCheckout, onCheckoutCompleted }: CheckoutContainerProps) => {
187
- const { setErrorMessage } = usePaymentStepModel();
188
- const progressBar = useProgressBarModel();
189
- const subscription = useSubscriptionModel();
190
- const { checkoutState, checkoutLocalization } = useCheckoutModel();
191
- const { plan, activeSubscription } = checkoutState || {};
192
- const planPrices = useChargesSort(
193
- plan?.pricePoints?.filter(price => price.billingPeriod === subscription.billingPeriod) || [],
194
- );
195
- const [baseCharges, usageCharges] = partition(planPrices, price => price.pricingModel === BillingModel.FlatFee);
196
- const [baseCharge] = baseCharges || [];
197
-
198
- const { subscriptionPreview, isFetchingSubscriptionPreview } = usePreviewSubscription();
199
-
200
- const { handleSubmit, isLoading } = useSubmit({ onCheckout, onCheckoutCompleted });
201
-
202
- const handleCheckout = async (e: any) => {
203
- const { errorMessage } = (await handleSubmit(e)) || {};
204
- if (errorMessage) {
205
- setErrorMessage(errorMessage);
206
- return;
207
- } else {
208
- setErrorMessage(undefined);
209
- }
210
- };
211
-
212
- const isLastStep = progressBar.isCheckoutComplete && progressBar.isLastStep;
213
-
214
- return (
215
- <Box flex={1}>
216
- <SummaryCard>
217
- <PlanName variant="h6">{plan?.displayName}</PlanName>
218
-
219
- {baseCharge && (
220
- <LineItemContainer>
221
- <LineItemRow>
222
- <Typography variant="h6" color="primary">
223
- {typeof checkoutLocalization.baseChargeText === 'function'
224
- ? checkoutLocalization.baseChargeText({ billingPeriod: subscription.billingPeriod })
225
- : checkoutLocalization.baseChargeText}
226
- </Typography>
227
- <Typography variant="body1" color="secondary">
228
- {currencyPriceFormatter({ amount: baseCharge.amount!, currency: baseCharge.currency })}
229
- </Typography>
230
- </LineItemRow>
231
- </LineItemContainer>
232
- )}
233
-
234
- {usageCharges.map(price => {
235
- const priceBillableFeature = subscription.billableFeatures?.find(
236
- billableFeature => billableFeature.featureId === price.feature?.featureId,
237
- );
238
-
239
- return (
240
- <BilledPriceLineItem
241
- key={price.feature?.featureId}
242
- label={price.feature?.displayName || ''}
243
- quantity={priceBillableFeature?.quantity || 1}
244
- price={price}
245
- />
246
- );
247
- })}
248
-
249
- {!!subscription.addons?.length && (
250
- <>
251
- <Grid display="flex" flexDirection="row" alignItems="center" marginY={1}>
252
- <Typography variant="body1" color="primary" style={{ paddingRight: '8px' }}>
253
- {checkoutLocalization.addonsSectionTitle}
254
- </Typography>
255
- <StyledDivider className="stigg-checkout-summary-divider" sx={{ flex: 1 }}></StyledDivider>
256
- </Grid>
257
- {subscription.addons.map(addon => {
258
- const addonPrice = addon.addon.pricePoints?.find(
259
- price => price.billingPeriod === subscription.billingPeriod,
260
- );
261
-
262
- if (!addonPrice) return null;
263
-
264
- return (
265
- <BilledPriceLineItem
266
- key={addon?.addon?.id}
267
- label={addon.addon.displayName}
268
- quantity={addon.quantity}
269
- price={addonPrice}
270
- />
271
- );
272
- })}
273
- </>
274
- )}
275
-
276
- <LineItemRow>
277
- <SubtotalText variant="h6">{checkoutLocalization.subTotalText}</SubtotalText>
278
- <SubtotalText variant="h6">
279
- {isFetchingSubscriptionPreview ? (
280
- <Skeleton width={50} height={16} />
281
- ) : (
282
- currencyPriceFormatter({ amount: 0, ...subscriptionPreview?.subTotal })
283
- )}
284
- </SubtotalText>
285
- </LineItemRow>
286
-
287
- <StyledDivider className="stigg-checkout-summary-divider" />
288
-
289
- <PromotionCodeSection checkoutLocalization={checkoutLocalization} />
290
-
291
- <StyledDivider className="stigg-checkout-summary-divider" />
292
-
293
- <DiscountLineItem
294
- subscriptionPreview={subscriptionPreview}
295
- isFetchingSubscriptionPreview={isFetchingSubscriptionPreview}
296
- />
297
-
298
- <TaxLineItem
299
- subscriptionPreview={subscriptionPreview}
300
- isFetchingSubscriptionPreview={isFetchingSubscriptionPreview}
301
- />
302
-
303
- <LineItemContainer>
304
- <LineItemRow>
305
- <TotalDueText variant="h6">{checkoutLocalization.totalText}</TotalDueText>
306
- <TotalDueText variant="h6">
307
- {isFetchingSubscriptionPreview ? (
308
- <Skeleton width={50} height={16} />
309
- ) : (
310
- currencyPriceFormatter({ amount: 0, ...subscriptionPreview?.total })
311
- )}
312
- </TotalDueText>
313
- </LineItemRow>
314
- </LineItemContainer>
315
-
316
- {!!subscriptionPreview?.hasScheduledUpdates && activeSubscription?.currentBillingPeriodEnd && (
317
- <Typography variant="caption">
318
- {typeof checkoutLocalization.changesWillApplyAtEndOfBillingPeriod === 'function'
319
- ? checkoutLocalization.changesWillApplyAtEndOfBillingPeriod({
320
- billingPeriodEnd: activeSubscription.currentBillingPeriodEnd,
321
- })
322
- : checkoutLocalization.changesWillApplyAtEndOfBillingPeriod}
323
- </Typography>
324
- )}
325
- <Button
326
- disableRipple={isLoading}
327
- $isLoading={isLoading}
328
- className="stigg-checkout-summary-cta-button"
329
- sx={{ textTransform: 'none', borderRadius: '10px', marginTop: '24px' }}
330
- variant="contained"
331
- size="medium"
332
- onClick={async (e: any) => {
333
- if (isLoading) {
334
- return;
335
- }
336
-
337
- if (isLastStep) {
338
- await handleCheckout(e);
339
- } else {
340
- progressBar.goNext();
341
- }
342
- }}
343
- fullWidth
344
- >
345
- <Typography className="stigg-checkout-summary-cta-button-text" color="white" style={{ display: 'flex' }}>
346
- {isLoading && <CircularProgress size={20} />}
347
- {!isLoading &&
348
- (isLastStep
349
- ? checkoutLocalization.checkoutButton.purchaseText
350
- : checkoutLocalization.checkoutButton.nextText)}
351
- </Typography>
352
- </Button>
353
- </SummaryCard>
354
- <PoweredByStigg
355
- source="checkout"
356
- showWatermark
357
- style={{ marginTop: 8, display: 'flex', justifyContent: 'center' }}
358
- />
359
- </Box>
360
- );
361
- };
@@ -1,30 +0,0 @@
1
- import React from 'react';
2
-
3
- import styled from '@emotion/styled/macro';
4
- import { Button as MuiButton, ButtonProps, css } from '@mui/material';
5
-
6
- export type StyledButtonProps = { $isLoading?: boolean };
7
-
8
- const StyledButton = styled(MuiButton)<StyledButtonProps>`
9
- border-radius: 10px;
10
- text-transform: none;
11
-
12
- ${({ theme, $isLoading }) => {
13
- if ($isLoading) {
14
- return css`
15
- background-color: ${theme.stigg.palette.primaryDark};
16
- cursor: no-drop;
17
-
18
- &:hover {
19
- background-color: ${theme.stigg.palette.primaryDark};
20
- }
21
- `;
22
- }
23
-
24
- return '';
25
- }}
26
- `;
27
-
28
- export const Button = ({ variant = 'outlined', ...props }: ButtonProps & StyledButtonProps) => {
29
- return <StyledButton variant={variant} {...props} />;
30
- };
@@ -1,22 +0,0 @@
1
- import styled from '@emotion/styled';
2
- import { OutlinedInputProps, TextField } from '@mui/material';
3
-
4
- export const InputField = styled(TextField)<OutlinedInputProps>(({ theme }) => ({
5
- '& .MuiOutlinedInput-root': {
6
- height: '42px',
7
- borderRadius: theme.stigg.border.radius,
8
- fieldset: {
9
- borderColor: theme.stigg.palette.outlinedBorder,
10
- },
11
- '&:not(.Mui-focused):hover fieldset': {
12
- borderColor: theme.stigg.palette.outlinedRestingBorder,
13
- },
14
- },
15
- '& .MuiInputBase-input': {
16
- padding: '8px 12px',
17
- borderRadius: theme.stigg.border.radius,
18
- fontFamily: theme.stigg.typography.fontFamily,
19
- color: theme.stigg.palette.text.primary,
20
- ...theme.stigg.typography.body,
21
- },
22
- }));
@@ -1,2 +0,0 @@
1
- export * from './Button';
2
- export * from './InputField';
@@ -1,12 +0,0 @@
1
- import { BillingPeriod } from '@stigg/js-client-sdk';
2
-
3
- export function formatBillingPeriod(billingPeriod: BillingPeriod) {
4
- switch (billingPeriod) {
5
- case BillingPeriod.Annually:
6
- return 'Annual';
7
- case BillingPeriod.Monthly:
8
- return 'Monthly';
9
- default:
10
- return '';
11
- }
12
- }
@@ -1,8 +0,0 @@
1
- export * from './useAddonsStepModel';
2
- export * from './useCheckoutModel';
3
- export * from './useLoadCheckout';
4
- export * from './usePlanStepModel';
5
- export * from './useProgressBarModel';
6
- export * from './useSubscriptionModel';
7
- export * from './usePreviewSubscription';
8
- export * from './usePaymentStepModel';
@@ -1,96 +0,0 @@
1
- import cloneDeep from 'lodash/cloneDeep';
2
- import remove from 'lodash/remove';
3
- import { Addon, BillingPeriod, Currency, Plan, Subscription, SubscriptionAddon } from '@stigg/js-client-sdk';
4
- import { useCheckoutContext } from '../CheckoutProvider';
5
- import {
6
- filterAddons,
7
- filterSubscriptionAddons,
8
- sortAddons,
9
- sortSubscriptionAddons,
10
- } from '../steps/addons/addon.utils';
11
-
12
- export type AddonsStepState = {
13
- addons: SubscriptionAddon[];
14
- initialAddons?: SubscriptionAddon[];
15
- availableAddons?: Addon[];
16
- };
17
-
18
- type getAddonsStepInitialStateProps = {
19
- plan?: Plan;
20
- billingPeriod: BillingPeriod;
21
- activeSubscription?: Subscription | null;
22
- billingCountryCode?: string;
23
- };
24
-
25
- export function getAddonsStepInitialState({
26
- activeSubscription,
27
- plan,
28
- billingPeriod,
29
- billingCountryCode,
30
- }: getAddonsStepInitialStateProps): AddonsStepState {
31
- let addons: SubscriptionAddon[] = [];
32
- const currency = plan?.pricePoints?.[0]?.currency || Currency.Usd;
33
- const availableAddons = sortAddons(
34
- filterAddons({
35
- addons: plan?.compatibleAddons,
36
- billingPeriod,
37
- billingCountryCode,
38
- currency,
39
- }),
40
- );
41
-
42
- const activeSubscriptionAddons = filterSubscriptionAddons({
43
- addons: activeSubscription?.addons,
44
- billingPeriod,
45
- billingCountryCode,
46
- currency,
47
- });
48
-
49
- if (activeSubscriptionAddons?.length && availableAddons?.length) {
50
- addons = sortSubscriptionAddons(
51
- activeSubscriptionAddons.filter((addon) => availableAddons.some((planAddon) => planAddon.id === addon.addon.id)),
52
- );
53
- }
54
-
55
- return { addons, initialAddons: cloneDeep(addons), availableAddons };
56
- }
57
-
58
- function useSetAddon() {
59
- const [, setState] = useCheckoutContext();
60
-
61
- return (addon: Addon, quantity: number) =>
62
- setState((draft) => {
63
- const addonToUpdate = draft.addonsStep.addons.find((currentAddon) => currentAddon.addon.id === addon.id);
64
-
65
- if (addonToUpdate) {
66
- addonToUpdate.quantity = quantity;
67
- } else {
68
- draft.addonsStep.addons.push({ addon, quantity });
69
- draft.addonsStep.addons = sortSubscriptionAddons(draft.addonsStep.addons);
70
- }
71
- });
72
- }
73
-
74
- function useRemoveAddon() {
75
- const [, setState] = useCheckoutContext();
76
-
77
- return (addonId: string) =>
78
- setState((draft) => {
79
- remove(draft.addonsStep.addons, (addon) => addon.addon.id === addonId);
80
- });
81
- }
82
-
83
- function useAddonsState() {
84
- const [{ addonsStep }] = useCheckoutContext();
85
- return addonsStep;
86
- }
87
-
88
- export function useAddonsStepModel() {
89
- const state = useAddonsState();
90
-
91
- return {
92
- ...state,
93
- setAddon: useSetAddon(),
94
- removeAddon: useRemoveAddon(),
95
- };
96
- }
@@ -1,31 +0,0 @@
1
- import { useCheckoutContext } from '../CheckoutProvider';
2
-
3
- export type WidgetState = {
4
- isLoading?: boolean;
5
- };
6
-
7
- function useCheckoutState() {
8
- const [{ checkout, widgetState, checkoutLocalization }] = useCheckoutContext();
9
- return { checkoutState: checkout, widgetState, checkoutLocalization };
10
- }
11
-
12
- function useSetWidgetLoading() {
13
- const [, setState] = useCheckoutContext();
14
-
15
- return (isLoading: boolean) =>
16
- setState((draft) => {
17
- draft.widgetState.isLoading = isLoading;
18
- });
19
- }
20
-
21
- export function useCheckoutModel() {
22
- const { checkoutState, widgetState, checkoutLocalization } = useCheckoutState();
23
- const setWidgetLoading = useSetWidgetLoading();
24
-
25
- return {
26
- checkoutState,
27
- widgetState,
28
- checkoutLocalization,
29
- setWidgetLoading,
30
- };
31
- }
@@ -1,28 +0,0 @@
1
- import { useCheckoutContext } from '../CheckoutProvider';
2
-
3
- export type PromotionCodeState = {
4
- promotionCode?: string;
5
- };
6
-
7
- function usePromotionCodeState() {
8
- const [{ promotionCode }] = useCheckoutContext();
9
- return promotionCode;
10
- }
11
-
12
- function useSetPromotionCode() {
13
- const [, setState] = useCheckoutContext();
14
-
15
- return (promotionCode: string) =>
16
- setState(draft => {
17
- draft.promotionCode = promotionCode;
18
- });
19
- }
20
-
21
- export function usePromotionCodeModel() {
22
- const promotionCode = usePromotionCodeState();
23
-
24
- return {
25
- promotionCode,
26
- setPromotionCode: useSetPromotionCode(),
27
- };
28
- }
@@ -1,40 +0,0 @@
1
- import { GetCheckoutStateResults } from '@stigg/js-client-sdk';
2
- import { useEffect, useState } from 'react';
3
- import logger from '../../../services/logger';
4
- import { useStiggContext } from '../../StiggProvider';
5
-
6
- type useLoadCheckoutProps = {
7
- planId: string;
8
- resourceId?: string;
9
- billingCountryCode?: string;
10
- };
11
-
12
- export function useLoadCheckout({ planId, resourceId, billingCountryCode }: useLoadCheckoutProps) {
13
- const { stigg } = useStiggContext();
14
- const [isLoading, setIsLoading] = useState(false);
15
- const [checkout, setCheckout] = useState<GetCheckoutStateResults | null>();
16
-
17
- useEffect(() => {
18
- const loadCheckout = async () => {
19
- if (stigg.isCustomerLoaded) {
20
- try {
21
- setIsLoading(true);
22
-
23
- const checkout = await stigg.getCheckoutState({ planId, resourceId, billingCountryCode });
24
- setCheckout(checkout);
25
- } catch (err) {
26
- logger.error(`Failed to load checkout ${(err as any)?.message}`, err as any);
27
- } finally {
28
- setIsLoading(false);
29
- }
30
- }
31
- };
32
-
33
- void loadCheckout();
34
- }, [stigg, stigg.isCustomerLoaded, resourceId]);
35
-
36
- return {
37
- checkout,
38
- isLoading,
39
- };
40
- }
@@ -1,49 +0,0 @@
1
- import { Customer } from '@stigg/js-client-sdk';
2
-
3
- import { useCheckoutContext } from '../CheckoutProvider';
4
-
5
- export type PaymentStepState = {
6
- useNewPaymentMethod: boolean;
7
- errorMessage?: string;
8
- };
9
-
10
- type getPaymentStepInitialStateProps = {
11
- customer?: Customer;
12
- };
13
-
14
- export function getPaymentStepInitialState({ customer }: getPaymentStepInitialStateProps): PaymentStepState {
15
- return { useNewPaymentMethod: !customer?.paymentMethodDetails };
16
- }
17
-
18
- function useSetUseNewPaymentMethod() {
19
- const [, setState] = useCheckoutContext();
20
-
21
- return (useNewPaymentMethod: boolean) =>
22
- setState((draft) => {
23
- draft.paymentStep.useNewPaymentMethod = useNewPaymentMethod;
24
- });
25
- }
26
-
27
- function useSetErrorMessage() {
28
- const [, setState] = useCheckoutContext();
29
-
30
- return (errorMessage?: string) =>
31
- setState((draft) => {
32
- draft.paymentStep.errorMessage = errorMessage;
33
- });
34
- }
35
-
36
- function usePaymentState() {
37
- const [{ paymentStep }] = useCheckoutContext();
38
- return paymentStep;
39
- }
40
-
41
- export function usePaymentStepModel() {
42
- const state = usePaymentState();
43
-
44
- return {
45
- ...state,
46
- setUseNewPaymentMethod: useSetUseNewPaymentMethod(),
47
- setErrorMessage: useSetErrorMessage(),
48
- };
49
- }