@stigg/react-sdk 4.4.0-beta.1 → 4.4.0-beta.11
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/dist/components/checkout/Checkout.d.ts +1 -1
- package/dist/components/checkout/CheckoutContainer.d.ts +7 -2
- package/dist/components/checkout/CheckoutProvider.d.ts +3 -1
- package/dist/components/checkout/components/Button.d.ts +0 -1
- package/dist/components/checkout/components/ChangePlanButton.d.ts +8 -0
- package/dist/components/checkout/components/DowngradeToFreeContainer.d.ts +28 -0
- package/dist/components/checkout/components/StyledArrow.d.ts +5 -0
- package/dist/components/checkout/hooks/useCheckoutModel.d.ts +2 -0
- package/dist/components/checkout/hooks/usePaymentStepModel.d.ts +8 -2
- package/dist/components/checkout/hooks/usePreviewSubscription.d.ts +8 -1
- package/dist/components/checkout/hooks/useProgressBarModel.d.ts +3 -0
- package/dist/components/checkout/hooks/useSubscriptionModel.d.ts +2 -1
- package/dist/components/checkout/index.d.ts +2 -0
- package/dist/components/checkout/progressBar/CheckoutProgressBar.style.d.ts +3 -2
- package/dist/components/checkout/steps/payment/PaymentMethods.d.ts +3 -2
- package/dist/components/checkout/steps/payment/PaymentStep.d.ts +2 -1
- package/dist/components/checkout/steps/payment/stripe/StripePaymentForm.d.ts +2 -1
- package/dist/components/checkout/steps/payment/stripe/stripe.utils.d.ts +4 -0
- package/dist/components/checkout/steps/payment/stripe/useSubmit.d.ts +4 -3
- package/dist/components/checkout/steps/plan/BillingPeriodPicker.style.d.ts +1 -0
- package/dist/components/checkout/steps/plan/CheckoutChargeList.d.ts +6 -1
- package/dist/components/checkout/summary/CheckoutSuccess.d.ts +4 -1
- package/dist/components/checkout/summary/CheckoutSummary.d.ts +3 -1
- package/dist/components/checkout/summary/components/CheckoutCaptions.d.ts +2 -1
- package/dist/components/checkout/summary/components/LineItems.d.ts +8 -8
- package/dist/components/checkout/textOverrides.d.ts +28 -3
- package/dist/components/checkout/theme.d.ts +0 -1
- package/dist/components/checkout/types.d.ts +7 -0
- package/dist/components/customerPortal/subscriptionOverview/subscriptionView/SubscriptionView.style.d.ts +1 -1
- package/dist/components/paywall/paywallTextOverrides.d.ts +4 -0
- package/dist/components/utils/getPaidPriceText.d.ts +3 -1
- package/dist/react-sdk.cjs.development.js +1234 -599
- package/dist/react-sdk.cjs.development.js.map +1 -1
- package/dist/react-sdk.cjs.production.min.js +1 -1
- package/dist/react-sdk.cjs.production.min.js.map +1 -1
- package/dist/react-sdk.esm.js +1273 -622
- package/dist/react-sdk.esm.js.map +1 -1
- package/dist/theme/getResolvedTheme.d.ts +1 -0
- package/dist/theme/types.d.ts +1 -0
- package/package.json +2 -2
- package/src/assets/payment-method.svg +3 -10
- package/src/components/checkout/Checkout.tsx +2 -1
- package/src/components/checkout/CheckoutContainer.style.ts +1 -0
- package/src/components/checkout/CheckoutContainer.tsx +59 -28
- package/src/components/checkout/CheckoutProvider.tsx +18 -18
- package/src/components/checkout/components/Button.tsx +19 -35
- package/src/components/checkout/components/ChangePlanButton.tsx +32 -0
- package/src/components/checkout/components/DowngradeToFreeContainer.tsx +115 -0
- package/src/components/checkout/components/Skeletons.style.ts +4 -1
- package/src/components/checkout/components/StyledArrow.tsx +9 -0
- package/src/components/checkout/hooks/useCheckoutModel.ts +12 -2
- package/src/components/checkout/hooks/usePaymentStepModel.ts +22 -3
- package/src/components/checkout/hooks/usePlanStepModel.ts +25 -10
- package/src/components/checkout/hooks/usePreviewSubscription.ts +112 -40
- package/src/components/checkout/hooks/useProgressBarModel.ts +18 -0
- package/src/components/checkout/hooks/useSubscriptionModel.ts +8 -2
- package/src/components/checkout/hooks/useSubscriptionState.ts +2 -1
- package/src/components/checkout/index.ts +2 -0
- package/src/components/checkout/planHeader/PlanHeader.tsx +19 -34
- package/src/components/checkout/progressBar/CheckoutProgressBar.style.ts +6 -3
- package/src/components/checkout/progressBar/CheckoutProgressBar.tsx +13 -9
- package/src/components/checkout/promotionCode/AddPromotionCode.tsx +8 -8
- package/src/components/checkout/steps/addons/CheckoutAddonsStep.tsx +58 -11
- package/src/components/checkout/steps/payment/PaymentMethods.style.ts +1 -0
- package/src/components/checkout/steps/payment/PaymentMethods.tsx +13 -6
- package/src/components/checkout/steps/payment/PaymentStep.tsx +3 -1
- package/src/components/checkout/steps/payment/stripe/StripePaymentForm.tsx +35 -4
- package/src/components/checkout/steps/payment/stripe/stripe.utils.ts +4 -3
- package/src/components/checkout/steps/payment/stripe/useSubmit.ts +61 -48
- package/src/components/checkout/steps/plan/BillingPeriodPicker.style.tsx +27 -6
- package/src/components/checkout/steps/plan/BillingPeriodPicker.tsx +26 -5
- package/src/components/checkout/steps/plan/CheckoutChargeList.tsx +62 -12
- package/src/components/checkout/summary/CheckoutSuccess.tsx +52 -6
- package/src/components/checkout/summary/CheckoutSummary.tsx +74 -48
- package/src/components/checkout/summary/components/CheckoutCaptions.tsx +30 -29
- package/src/components/checkout/summary/components/LineItems.tsx +18 -33
- package/src/components/checkout/textOverrides.ts +33 -13
- package/src/components/checkout/theme.ts +0 -4
- package/src/components/checkout/types.ts +9 -0
- package/src/components/common/Icon.tsx +4 -6
- package/src/components/common/mapExternalTheme.ts +1 -2
- package/src/components/paywall/PlanPrice.tsx +10 -2
- package/src/components/paywall/paywallTextOverrides.ts +3 -0
- package/src/components/utils/getPaidPriceText.ts +8 -2
- package/src/components/utils/getPlanPrice.ts +1 -1
- package/src/stories/Checkout.stories.tsx +6 -5
- package/src/theme/Theme.tsx +10 -1
- package/src/theme/getResolvedTheme.ts +1 -0
- package/src/theme/types.ts +1 -0
- package/dist/components/checkout/planHeader/PlanHeader.style.d.ts +0 -25
- package/dist/components/checkout/steps/surprise/SurpriseStep.d.ts +0 -2
- package/src/assets/nyancat.svg +0 -634
- package/src/components/checkout/planHeader/PlanHeader.style.tsx +0 -23
- package/src/components/checkout/steps/surprise/SurpriseStep.tsx +0 -27
|
@@ -4,6 +4,7 @@ export declare const getResolvedTheme: (customizedTheme?: {
|
|
|
4
4
|
palette?: {
|
|
5
5
|
primary?: string | undefined;
|
|
6
6
|
primaryDark?: string | undefined;
|
|
7
|
+
primaryLight?: string | undefined;
|
|
7
8
|
backgroundPaper?: string | undefined;
|
|
8
9
|
backgroundHighlight?: string | undefined;
|
|
9
10
|
backgroundSection?: string | undefined;
|
package/dist/theme/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.4.0-beta.
|
|
2
|
+
"version": "4.4.0-beta.11",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"typings": "dist/index.d.ts",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"@emotion/react": "^11.10.5",
|
|
102
102
|
"@emotion/styled": "^11.10.5",
|
|
103
103
|
"@mui/material": "^5.10.13",
|
|
104
|
-
"@stigg/js-client-sdk": "2.
|
|
104
|
+
"@stigg/js-client-sdk": "2.23.0",
|
|
105
105
|
"@stripe/react-stripe-js": "^2.1.1",
|
|
106
106
|
"@stripe/stripe-js": "^1.54.1",
|
|
107
107
|
"@types/styled-components": "^5.1.26",
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
<svg width="24" height="
|
|
2
|
-
<
|
|
3
|
-
<path d="
|
|
4
|
-
</g>
|
|
5
|
-
<path opacity="0.3" d="M18.75 12.4286H16.5C16.0125 12.4286 15.75 12.2 15.75 11.6667C15.75 11.1334 16.0125 10.9048 16.5 10.9048H18.75C19.2375 10.9048 19.5 11.1334 19.5 11.6667C19.5 12.2 19.2375 12.4286 18.75 12.4286ZM14.25 12.4286H12C11.5125 12.4286 11.25 12.2 11.25 11.6667C11.25 11.1334 11.5125 10.9048 12 10.9048H14.25C14.7375 10.9048 15 11.1334 15 11.6667C15 12.2 14.7375 12.4286 14.25 12.4286ZM9.75 12.4286H7.5C7.0125 12.4286 6.75 12.2 6.75 11.6667C6.75 11.1334 7.0125 10.9048 7.5 10.9048H9.75C10.2375 10.9048 10.5 11.1334 10.5 11.6667C10.5 12.2 10.2375 12.4286 9.75 12.4286ZM5.25 12.4286H3C2.5125 12.4286 2.25 12.2 2.25 11.6667C2.25 11.1334 2.5125 10.9048 3 10.9048H5.25C5.7375 10.9048 6 11.1334 6 11.6667C6 12.2 5.7375 12.4286 5.25 12.4286Z" fill="black"/>
|
|
6
|
-
<defs>
|
|
7
|
-
<clipPath id="clip0_239_13697">
|
|
8
|
-
<rect width="24" height="16" fill="white"/>
|
|
9
|
-
</clipPath>
|
|
10
|
-
</defs>
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M21.1667 4H2.83333C1.82081 4 1 4.89543 1 6V18C1 19.1046 1.82081 20 2.83333 20H21.1667C22.1792 20 23 19.1046 23 18V6C23 4.89543 22.1792 4 21.1667 4Z" fill="#C6C6C7"/>
|
|
3
|
+
<path opacity="0.3" d="M19.75 16.4286H17.5C17.0125 16.4286 16.75 16.2 16.75 15.6667C16.75 15.1334 17.0125 14.9048 17.5 14.9048H19.75C20.2375 14.9048 20.5 15.1334 20.5 15.6667C20.5 16.2 20.2375 16.4286 19.75 16.4286ZM15.25 16.4286H13C12.5125 16.4286 12.25 16.2 12.25 15.6667C12.25 15.1334 12.5125 14.9048 13 14.9048H15.25C15.7375 14.9048 16 15.1334 16 15.6667C16 16.2 15.7375 16.4286 15.25 16.4286ZM10.75 16.4286H8.5C8.0125 16.4286 7.75 16.2 7.75 15.6667C7.75 15.1334 8.0125 14.9048 8.5 14.9048H10.75C11.2375 14.9048 11.5 15.1334 11.5 15.6667C11.5 16.2 11.2375 16.4286 10.75 16.4286ZM6.25 16.4286H4C3.5125 16.4286 3.25 16.2 3.25 15.6667C3.25 15.1334 3.5125 14.9048 4 14.9048H6.25C6.7375 14.9048 7 15.1334 7 15.6667C7 16.2 6.7375 16.4286 6.25 16.4286Z" fill="black"/>
|
|
11
4
|
</svg>
|
|
@@ -12,6 +12,7 @@ export const Checkout = ({
|
|
|
12
12
|
preferredBillingPeriod,
|
|
13
13
|
billingCountryCode,
|
|
14
14
|
billableFeatures,
|
|
15
|
+
billingInformation,
|
|
15
16
|
...containerProps
|
|
16
17
|
}: CheckoutProps) => {
|
|
17
18
|
return (
|
|
@@ -23,7 +24,7 @@ export const Checkout = ({
|
|
|
23
24
|
preferredBillingPeriod={preferredBillingPeriod}
|
|
24
25
|
billingCountryCode={billingCountryCode}
|
|
25
26
|
billableFeatures={billableFeatures}
|
|
26
|
-
|
|
27
|
+
billingInformation={billingInformation}>
|
|
27
28
|
<CheckoutContainer {...containerProps} />
|
|
28
29
|
</CheckoutProvider>
|
|
29
30
|
);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Elements } from '@stripe/react-stripe-js';
|
|
3
|
-
import { ApplySubscription, CheckoutStatePlan } from '@stigg/js-client-sdk';
|
|
3
|
+
import { ApplySubscription, BillingAddress, CheckoutStatePlan, PricingType } from '@stigg/js-client-sdk';
|
|
4
4
|
import { CheckoutContent, CheckoutLayout, CheckoutPanel } from './CheckoutContainer.style';
|
|
5
5
|
import { CheckoutProgressBar } from './progressBar/CheckoutProgressBar';
|
|
6
6
|
import { CheckoutSummary, CheckoutSummarySkeleton } from './summary';
|
|
7
|
-
import { useProgressBarModel } from './hooks';
|
|
7
|
+
import { CheckoutStep, CheckoutStepKey, useCheckoutModel, useProgressBarModel } from './hooks';
|
|
8
8
|
import { PlanHeader } from './planHeader';
|
|
9
9
|
import { CheckoutAddonsStep } from './steps/addons';
|
|
10
10
|
import { PaymentStep } from './steps/payment';
|
|
@@ -12,22 +12,24 @@ import { useStripeIntegration } from './steps/payment/stripe';
|
|
|
12
12
|
import { CheckoutPlanStep } from './steps/plan';
|
|
13
13
|
import { useCheckoutContext } from './CheckoutProvider';
|
|
14
14
|
import { ContentLoadingSkeleton } from './components';
|
|
15
|
-
|
|
16
|
-
// import { SurpriseStep } from './steps/surprise/SurpriseStep';
|
|
15
|
+
import { DowngradeToFreePlan } from './components/DowngradeToFreeContainer';
|
|
17
16
|
|
|
18
17
|
type StepProps = {
|
|
19
18
|
allowChangePlan?: boolean;
|
|
20
19
|
content: React.ReactNode;
|
|
21
20
|
};
|
|
22
21
|
|
|
23
|
-
const getStepProps = (
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const getStepProps = (
|
|
23
|
+
currentStep: CheckoutStep,
|
|
24
|
+
{ onBillingAddressChange }: Pick<CheckoutContainerProps, 'onBillingAddressChange'>,
|
|
25
|
+
): StepProps => {
|
|
26
|
+
switch (currentStep.key) {
|
|
27
|
+
case CheckoutStepKey.PLAN:
|
|
26
28
|
return { allowChangePlan: true, content: <CheckoutPlanStep /> };
|
|
27
|
-
case
|
|
29
|
+
case CheckoutStepKey.ADDONS:
|
|
28
30
|
return { content: <CheckoutAddonsStep /> };
|
|
29
|
-
case
|
|
30
|
-
return { content: <PaymentStep /> };
|
|
31
|
+
case CheckoutStepKey.PAYMENT:
|
|
32
|
+
return { content: <PaymentStep onBillingAddressChange={onBillingAddressChange} /> };
|
|
31
33
|
default:
|
|
32
34
|
return { content: null };
|
|
33
35
|
}
|
|
@@ -43,26 +45,51 @@ export type CheckoutContainerProps = {
|
|
|
43
45
|
onCheckout?: (params: OnCheckoutParams) => Promise<CheckoutResult>;
|
|
44
46
|
onCheckoutCompleted: (params: OnCheckoutCompletedParams) => Promise<void>;
|
|
45
47
|
onChangePlan?: (params: { currentPlan: CheckoutStatePlan | undefined }) => void;
|
|
48
|
+
onBillingAddressChange?: (params: { billingAddress: BillingAddress }) => Promise<void>;
|
|
49
|
+
disablePromotionCode?: boolean;
|
|
50
|
+
disableSuccessAnimation?: boolean;
|
|
46
51
|
};
|
|
47
52
|
|
|
48
|
-
export function CheckoutContainer({
|
|
53
|
+
export function CheckoutContainer({
|
|
54
|
+
onCheckout,
|
|
55
|
+
onCheckoutCompleted,
|
|
56
|
+
onChangePlan,
|
|
57
|
+
onBillingAddressChange,
|
|
58
|
+
disablePromotionCode,
|
|
59
|
+
disableSuccessAnimation,
|
|
60
|
+
}: CheckoutContainerProps) {
|
|
49
61
|
const { stripePromise, setupIntentClientSecret } = useStripeIntegration();
|
|
50
62
|
const [{ stiggTheme, widgetState }] = useCheckoutContext();
|
|
51
|
-
const {
|
|
52
|
-
|
|
63
|
+
const { currentStep } = useProgressBarModel();
|
|
64
|
+
|
|
53
65
|
const { isLoadingCheckoutData } = widgetState;
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
const { checkoutState, checkoutLocalization } = useCheckoutModel();
|
|
68
|
+
const { plan, activeSubscription } = checkoutState || {};
|
|
69
|
+
const isFreeDowngrade =
|
|
70
|
+
!!plan &&
|
|
71
|
+
plan.pricingType === PricingType.Free &&
|
|
72
|
+
!!activeSubscription &&
|
|
73
|
+
activeSubscription.pricingType !== PricingType.Free;
|
|
59
74
|
|
|
60
|
-
const { content, allowChangePlan } = getStepProps(
|
|
75
|
+
const { content, allowChangePlan } = getStepProps(currentStep, { onBillingAddressChange });
|
|
61
76
|
|
|
62
77
|
const checkoutContent = (
|
|
63
78
|
<>
|
|
64
|
-
|
|
65
|
-
|
|
79
|
+
{isFreeDowngrade ? (
|
|
80
|
+
<DowngradeToFreePlan
|
|
81
|
+
checkoutLocalization={checkoutLocalization}
|
|
82
|
+
freePlan={plan!}
|
|
83
|
+
activeSubscription={activeSubscription!}
|
|
84
|
+
allowChangePlan={allowChangePlan}
|
|
85
|
+
onChangePlan={onChangePlan}
|
|
86
|
+
/>
|
|
87
|
+
) : (
|
|
88
|
+
<>
|
|
89
|
+
<PlanHeader allowChangePlan={allowChangePlan} onChangePlan={onChangePlan} />
|
|
90
|
+
{content}
|
|
91
|
+
</>
|
|
92
|
+
)}
|
|
66
93
|
</>
|
|
67
94
|
);
|
|
68
95
|
|
|
@@ -82,15 +109,19 @@ export function CheckoutContainer({ onCheckout, onCheckoutCompleted, onChangePla
|
|
|
82
109
|
},
|
|
83
110
|
}}>
|
|
84
111
|
<CheckoutLayout className="stigg-checkout-layout">
|
|
85
|
-
<CheckoutProgressBar />
|
|
112
|
+
{!isFreeDowngrade && <CheckoutProgressBar />}
|
|
86
113
|
<CheckoutContent>
|
|
87
|
-
<CheckoutPanel>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
114
|
+
<CheckoutPanel>{isLoadingCheckoutData ? <ContentLoadingSkeleton /> : checkoutContent}</CheckoutPanel>
|
|
115
|
+
{isLoadingCheckoutData ? (
|
|
116
|
+
<CheckoutSummarySkeleton />
|
|
117
|
+
) : (
|
|
118
|
+
<CheckoutSummary
|
|
119
|
+
disablePromotionCode={disablePromotionCode}
|
|
120
|
+
disableSuccessAnimation={disableSuccessAnimation}
|
|
121
|
+
onCheckout={onCheckout}
|
|
122
|
+
onCheckoutCompleted={onCheckoutCompleted}
|
|
123
|
+
isFreeDowngrade={isFreeDowngrade}
|
|
124
|
+
/>
|
|
94
125
|
)}
|
|
95
126
|
</CheckoutContent>
|
|
96
127
|
</CheckoutLayout>
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { produce } from 'immer';
|
|
2
|
-
import React, { useCallback, useContext, useMemo, useState } from 'react';
|
|
3
|
-
|
|
2
|
+
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
4
3
|
import { BillableFeature, BillingPeriod, GetCheckoutStateResults } from '@stigg/js-client-sdk';
|
|
5
|
-
|
|
6
4
|
import { CustomizedTheme, SdkThemeProvider, useStiggTheme } from '../../theme/Theme';
|
|
7
5
|
import { DeepPartial } from '../../types';
|
|
8
6
|
import { mapCheckoutConfiguration } from '../common/mapExternalTheme';
|
|
@@ -21,6 +19,7 @@ import {
|
|
|
21
19
|
import { CheckoutLocalization, getResolvedCheckoutLocalize } from './textOverrides';
|
|
22
20
|
import { CheckoutTheme, getResolvedCheckoutTheme } from './theme';
|
|
23
21
|
import { StiggTheme } from '../../theme/types';
|
|
22
|
+
import { BillingInformation } from './types';
|
|
24
23
|
|
|
25
24
|
export interface CheckoutContextState {
|
|
26
25
|
checkout?: GetCheckoutStateResults | null;
|
|
@@ -58,12 +57,16 @@ const CheckoutContextProvider: React.FC<{ children: React.ReactNode; initialStat
|
|
|
58
57
|
}) => {
|
|
59
58
|
const [state, innerSetState] = useState(initialState);
|
|
60
59
|
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
innerSetState(initialState);
|
|
62
|
+
}, [initialState]);
|
|
63
|
+
|
|
61
64
|
const setState = useCallback(
|
|
62
65
|
(updater: (state: CheckoutContextState) => void) => innerSetState((old) => produce(old, (draft) => updater(draft))),
|
|
63
66
|
[innerSetState],
|
|
64
67
|
);
|
|
65
68
|
|
|
66
|
-
const [contextValue, setContextValue] = useMemo(() => [state, setState], [state]);
|
|
69
|
+
const [contextValue, setContextValue] = useMemo(() => [state, setState], [setState, state]);
|
|
67
70
|
|
|
68
71
|
return <CheckoutContext.Provider value={[contextValue, setContextValue]}>{children}</CheckoutContext.Provider>;
|
|
69
72
|
};
|
|
@@ -76,17 +79,19 @@ export type CheckoutProviderProps = {
|
|
|
76
79
|
preferredBillingPeriod?: BillingPeriod;
|
|
77
80
|
billingCountryCode?: string;
|
|
78
81
|
billableFeatures?: BillableFeature[];
|
|
82
|
+
billingInformation?: BillingInformation;
|
|
79
83
|
};
|
|
80
84
|
|
|
81
85
|
export function CheckoutProvider({
|
|
82
86
|
children,
|
|
83
87
|
textOverrides,
|
|
84
88
|
theme,
|
|
89
|
+
preferredBillingPeriod,
|
|
90
|
+
billableFeatures,
|
|
85
91
|
resourceId,
|
|
86
92
|
planId,
|
|
87
|
-
preferredBillingPeriod,
|
|
88
93
|
billingCountryCode,
|
|
89
|
-
|
|
94
|
+
billingInformation,
|
|
90
95
|
}: {
|
|
91
96
|
children: React.ReactNode;
|
|
92
97
|
} & CheckoutProviderProps) {
|
|
@@ -111,7 +116,10 @@ export function CheckoutProvider({
|
|
|
111
116
|
billingPeriod: planStep.billingPeriod,
|
|
112
117
|
activeSubscription: checkout?.activeSubscription,
|
|
113
118
|
});
|
|
114
|
-
const paymentStep = getPaymentStepInitialState({
|
|
119
|
+
const paymentStep = getPaymentStepInitialState({
|
|
120
|
+
customer: checkout?.customer,
|
|
121
|
+
taxPercentage: billingInformation?.taxDetails?.taxPercentage,
|
|
122
|
+
});
|
|
115
123
|
const progressBar = getProgressBarInitialState({
|
|
116
124
|
availableAddons: isLoading ? undefined : addonsStep.availableAddons,
|
|
117
125
|
});
|
|
@@ -126,20 +134,12 @@ export function CheckoutProvider({
|
|
|
126
134
|
addonsStep,
|
|
127
135
|
paymentStep,
|
|
128
136
|
resourceId: checkout?.resource?.id,
|
|
129
|
-
widgetState: { readOnly: false, isLoadingCheckoutData: isLoading },
|
|
137
|
+
widgetState: { readOnly: false, isValid: true, isLoadingCheckoutData: isLoading },
|
|
130
138
|
};
|
|
131
139
|
|
|
132
140
|
return initialState;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
textOverrides,
|
|
136
|
-
preferredBillingPeriod,
|
|
137
|
-
billingCountryCode,
|
|
138
|
-
billableFeatures,
|
|
139
|
-
globalTheme,
|
|
140
|
-
checkout,
|
|
141
|
-
isLoading,
|
|
142
|
-
]);
|
|
141
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
142
|
+
}, [preferredBillingPeriod, billingCountryCode, checkout, isLoading, billingInformation?.taxDetails?.taxPercentage]);
|
|
143
143
|
|
|
144
144
|
return (
|
|
145
145
|
<SdkThemeProvider key={checkout?.plan.id} componentTheme={configuration}>
|
|
@@ -1,49 +1,33 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import styled from '@emotion/styled/macro';
|
|
4
|
-
import { Button as MuiButton, ButtonProps
|
|
4
|
+
import { Button as MuiButton, ButtonProps } from '@mui/material';
|
|
5
5
|
|
|
6
|
-
export type StyledButtonProps = { $
|
|
6
|
+
export type StyledButtonProps = { $success?: boolean; $error?: boolean };
|
|
7
7
|
|
|
8
|
-
const StyledButton = styled(MuiButton)<StyledButtonProps>`
|
|
8
|
+
const StyledButton = styled(MuiButton, { shouldForwardProp: (prop) => !prop.startsWith('$') })<StyledButtonProps>`
|
|
9
9
|
border-radius: 10px;
|
|
10
10
|
text-transform: none;
|
|
11
11
|
|
|
12
|
-
${({ theme, $
|
|
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
|
-
|
|
12
|
+
background-color: ${({ theme, $success, $error }) => {
|
|
24
13
|
if ($success) {
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
&:hover {
|
|
30
|
-
background-color: ${theme.stigg.palette.successDark};
|
|
31
|
-
}
|
|
32
|
-
`;
|
|
14
|
+
return theme.stigg.palette.success;
|
|
15
|
+
} else if ($error) {
|
|
16
|
+
return theme.stigg.palette.error;
|
|
33
17
|
}
|
|
34
|
-
|
|
35
|
-
if ($error) {
|
|
36
|
-
return css`
|
|
37
|
-
background-color: ${theme.stigg.palette.error};
|
|
38
|
-
|
|
39
|
-
&:hover {
|
|
40
|
-
background-color: ${theme.stigg.palette.errorDark};
|
|
41
|
-
}
|
|
42
|
-
`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
18
|
return '';
|
|
46
|
-
}}
|
|
19
|
+
}};
|
|
20
|
+
|
|
21
|
+
&:hover {
|
|
22
|
+
background-color: ${({ theme, $success, $error }) => {
|
|
23
|
+
if ($success) {
|
|
24
|
+
return theme.stigg.palette.successDark;
|
|
25
|
+
} else if ($error) {
|
|
26
|
+
return theme.stigg.palette.errorDark;
|
|
27
|
+
}
|
|
28
|
+
return '';
|
|
29
|
+
}};
|
|
30
|
+
}
|
|
47
31
|
`;
|
|
48
32
|
|
|
49
33
|
export const Button = ({ variant = 'outlined', ...props }: ButtonProps & StyledButtonProps) => {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Button } from '@mui/material';
|
|
2
|
+
import { Typography } from '../../common/Typography';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { CheckoutLocalization } from '../textOverrides';
|
|
5
|
+
import { ButtonProps } from '@mui/material/Button';
|
|
6
|
+
|
|
7
|
+
export const ChangePlanButton = ({
|
|
8
|
+
onClick,
|
|
9
|
+
checkoutLocalization,
|
|
10
|
+
size,
|
|
11
|
+
}: {
|
|
12
|
+
onClick: () => void;
|
|
13
|
+
checkoutLocalization: CheckoutLocalization;
|
|
14
|
+
size: ButtonProps['size'];
|
|
15
|
+
}) => {
|
|
16
|
+
return (
|
|
17
|
+
<Button
|
|
18
|
+
className="stigg-checkout-change-plan-button"
|
|
19
|
+
sx={{ textTransform: 'none' }}
|
|
20
|
+
variant="text"
|
|
21
|
+
size={size}
|
|
22
|
+
onClick={onClick}>
|
|
23
|
+
<Typography
|
|
24
|
+
className="stigg-checkout-change-plan-button-text"
|
|
25
|
+
color="primary.main"
|
|
26
|
+
variant="body1"
|
|
27
|
+
style={{ lineHeight: '24px' }}>
|
|
28
|
+
{checkoutLocalization.changePlan}
|
|
29
|
+
</Typography>
|
|
30
|
+
</Button>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyledArrowRightIcon } from './StyledArrow';
|
|
3
|
+
import styled from '@emotion/styled/macro';
|
|
4
|
+
import { Alert, Box } from '@mui/material';
|
|
5
|
+
import { Typography } from '../../common/Typography';
|
|
6
|
+
import { CheckoutStatePlan, Subscription } from '@stigg/js-client-sdk';
|
|
7
|
+
import { CheckoutLocalization } from '../textOverrides';
|
|
8
|
+
import { CheckoutContainerProps } from '../CheckoutContainer';
|
|
9
|
+
import { ChangePlanButton } from './ChangePlanButton';
|
|
10
|
+
|
|
11
|
+
const DowngradeToFreePlansContainer = styled(Box)`
|
|
12
|
+
display: flex;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
const DowngradeToFreeAlert = styled(Alert)`
|
|
16
|
+
margin-bottom: 16px;
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export const DowngradeToFreePlanBox = styled(Box)`
|
|
20
|
+
padding: 16px;
|
|
21
|
+
border-radius: 10px;
|
|
22
|
+
width: 100%;
|
|
23
|
+
border: ${({ theme }) => `1px solid ${theme.stigg.palette.outlinedBorder}`};
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
export const DowngradeToFreeContent = ({
|
|
27
|
+
headerText,
|
|
28
|
+
planName,
|
|
29
|
+
priceText,
|
|
30
|
+
}: {
|
|
31
|
+
headerText: string;
|
|
32
|
+
planName: string;
|
|
33
|
+
priceText: string;
|
|
34
|
+
}) => {
|
|
35
|
+
return (
|
|
36
|
+
<DowngradeToFreePlanBox className="stigg-checkout-downgrade-to-free-container">
|
|
37
|
+
<Typography
|
|
38
|
+
className="stigg-checkout-downgrade-to-free-text-header"
|
|
39
|
+
style={{ opacity: 0.8 }}
|
|
40
|
+
variant="caption"
|
|
41
|
+
color="disabled">
|
|
42
|
+
{headerText}
|
|
43
|
+
</Typography>
|
|
44
|
+
<Typography className="stigg-checkout-downgrade-to-free-plan-name" bold variant="h3" color="primary">
|
|
45
|
+
{planName}
|
|
46
|
+
</Typography>
|
|
47
|
+
<Typography className="stigg-checkout-downgrade-to-free-price-text" color="secondary">
|
|
48
|
+
{priceText}
|
|
49
|
+
</Typography>
|
|
50
|
+
</DowngradeToFreePlanBox>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
type DowngradeToFreePlanProps = {
|
|
55
|
+
checkoutLocalization: CheckoutLocalization;
|
|
56
|
+
activeSubscription: Subscription;
|
|
57
|
+
freePlan: CheckoutStatePlan;
|
|
58
|
+
allowChangePlan?: boolean;
|
|
59
|
+
} & Pick<CheckoutContainerProps, 'onChangePlan'>;
|
|
60
|
+
|
|
61
|
+
export const DowngradeToFreePlan = ({
|
|
62
|
+
checkoutLocalization,
|
|
63
|
+
activeSubscription,
|
|
64
|
+
freePlan,
|
|
65
|
+
allowChangePlan = false,
|
|
66
|
+
onChangePlan,
|
|
67
|
+
}: DowngradeToFreePlanProps) => {
|
|
68
|
+
let alertAction;
|
|
69
|
+
if (allowChangePlan && onChangePlan) {
|
|
70
|
+
alertAction = (
|
|
71
|
+
<ChangePlanButton
|
|
72
|
+
onClick={() => {
|
|
73
|
+
onChangePlan({ currentPlan: freePlan });
|
|
74
|
+
}}
|
|
75
|
+
checkoutLocalization={checkoutLocalization}
|
|
76
|
+
size="small"
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const paidBillingPeriod =
|
|
82
|
+
activeSubscription.prices.length > 0 ? activeSubscription.prices[0].billingPeriod : undefined;
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<>
|
|
86
|
+
<DowngradeToFreeAlert action={alertAction} className="stigg-checkout-downgrade-to-free-alert" severity="info">
|
|
87
|
+
<Typography span color="secondary">
|
|
88
|
+
{checkoutLocalization.downgradeToFree.alertText({ plan: activeSubscription.plan })}
|
|
89
|
+
</Typography>
|
|
90
|
+
</DowngradeToFreeAlert>
|
|
91
|
+
|
|
92
|
+
<DowngradeToFreePlansContainer className="stigg-checkout-downgrade-to-free-plans-container">
|
|
93
|
+
<DowngradeToFreeContent
|
|
94
|
+
headerText={checkoutLocalization.downgradeToFree.paidPlanHeader({ plan: activeSubscription.plan })}
|
|
95
|
+
planName={checkoutLocalization.downgradeToFree.paidPlanName({ plan: activeSubscription.plan })}
|
|
96
|
+
priceText={checkoutLocalization.downgradeToFree.paidPlanPriceText({
|
|
97
|
+
plan: activeSubscription.plan,
|
|
98
|
+
billingPeriod: paidBillingPeriod,
|
|
99
|
+
})}
|
|
100
|
+
/>
|
|
101
|
+
|
|
102
|
+
<StyledArrowRightIcon
|
|
103
|
+
className="stigg-checkout-downgrade-to-free-arrow"
|
|
104
|
+
style={{ margin: 'auto 16px', minWidth: '16px' }}
|
|
105
|
+
/>
|
|
106
|
+
|
|
107
|
+
<DowngradeToFreeContent
|
|
108
|
+
headerText={checkoutLocalization.downgradeToFree.freePlanHeader({ plan: freePlan })}
|
|
109
|
+
planName={checkoutLocalization.downgradeToFree.freePlanName({ plan: freePlan })}
|
|
110
|
+
priceText={checkoutLocalization.downgradeToFree.freePlanPriceText({ plan: freePlan })}
|
|
111
|
+
/>
|
|
112
|
+
</DowngradeToFreePlansContainer>
|
|
113
|
+
</>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
@@ -2,7 +2,10 @@ import styled from '@emotion/styled/macro';
|
|
|
2
2
|
import { Grid } from '@mui/material';
|
|
3
3
|
import ReactSkeleton from 'react-loading-skeleton';
|
|
4
4
|
|
|
5
|
-
export const SkeletonsContainer = styled(Grid
|
|
5
|
+
export const SkeletonsContainer = styled(Grid, { shouldForwardProp: (prop) => !prop.startsWith('$') })<{
|
|
6
|
+
$gap: number;
|
|
7
|
+
$flexDirection?: 'row' | 'column';
|
|
8
|
+
}>`
|
|
6
9
|
display: flex;
|
|
7
10
|
flex-direction: ${({ $flexDirection }) => $flexDirection || 'row'};
|
|
8
11
|
gap: ${({ $gap }) => $gap}px;
|
|
@@ -3,6 +3,7 @@ import { useCheckoutContext } from '../CheckoutProvider';
|
|
|
3
3
|
export type WidgetState = {
|
|
4
4
|
readOnly?: boolean;
|
|
5
5
|
isLoadingCheckoutData?: boolean;
|
|
6
|
+
isValid?: boolean;
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
function useCheckoutState() {
|
|
@@ -19,14 +20,23 @@ function useSetWidgetReadonly() {
|
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
function useSetIsValid() {
|
|
24
|
+
const [, setState] = useCheckoutContext();
|
|
25
|
+
|
|
26
|
+
return (isValid: boolean) =>
|
|
27
|
+
setState((draft) => {
|
|
28
|
+
draft.widgetState.isValid = isValid;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
export function useCheckoutModel() {
|
|
23
33
|
const { checkoutState, widgetState, checkoutLocalization } = useCheckoutState();
|
|
24
|
-
const setWidgetReadOnly = useSetWidgetReadonly();
|
|
25
34
|
|
|
26
35
|
return {
|
|
27
36
|
checkoutState,
|
|
28
37
|
widgetState,
|
|
29
38
|
checkoutLocalization,
|
|
30
|
-
setWidgetReadOnly,
|
|
39
|
+
setWidgetReadOnly: useSetWidgetReadonly(),
|
|
40
|
+
setIsValid: useSetIsValid(),
|
|
31
41
|
};
|
|
32
42
|
}
|
|
@@ -1,18 +1,27 @@
|
|
|
1
|
-
import { Customer } from '@stigg/js-client-sdk';
|
|
1
|
+
import { BillingAddress, Customer } from '@stigg/js-client-sdk';
|
|
2
2
|
|
|
3
3
|
import { useCheckoutContext } from '../CheckoutProvider';
|
|
4
4
|
|
|
5
5
|
export type PaymentStepState = {
|
|
6
6
|
useNewPaymentMethod: boolean;
|
|
7
7
|
errorMessage?: string;
|
|
8
|
+
billingAddress?: BillingAddress;
|
|
9
|
+
taxPercentage?: number;
|
|
8
10
|
};
|
|
9
11
|
|
|
10
12
|
type GetPaymentStepInitialStateProps = {
|
|
11
13
|
customer?: Customer;
|
|
14
|
+
taxPercentage?: number;
|
|
12
15
|
};
|
|
13
16
|
|
|
14
|
-
export function getPaymentStepInitialState({
|
|
15
|
-
|
|
17
|
+
export function getPaymentStepInitialState({
|
|
18
|
+
customer,
|
|
19
|
+
taxPercentage,
|
|
20
|
+
}: GetPaymentStepInitialStateProps): PaymentStepState {
|
|
21
|
+
return {
|
|
22
|
+
useNewPaymentMethod: !customer?.paymentMethodDetails,
|
|
23
|
+
taxPercentage,
|
|
24
|
+
};
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
function useSetUseNewPaymentMethod() {
|
|
@@ -33,6 +42,15 @@ function useSetErrorMessage() {
|
|
|
33
42
|
});
|
|
34
43
|
}
|
|
35
44
|
|
|
45
|
+
function useSetBillingAddress() {
|
|
46
|
+
const [, setState] = useCheckoutContext();
|
|
47
|
+
|
|
48
|
+
return (billingAddress?: BillingAddress) =>
|
|
49
|
+
setState((draft) => {
|
|
50
|
+
draft.paymentStep.billingAddress = billingAddress;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
36
54
|
function usePaymentState() {
|
|
37
55
|
const [{ paymentStep }] = useCheckoutContext();
|
|
38
56
|
return paymentStep;
|
|
@@ -45,5 +63,6 @@ export function usePaymentStepModel() {
|
|
|
45
63
|
...state,
|
|
46
64
|
setUseNewPaymentMethod: useSetUseNewPaymentMethod(),
|
|
47
65
|
setErrorMessage: useSetErrorMessage(),
|
|
66
|
+
setBillingAddress: useSetBillingAddress(),
|
|
48
67
|
};
|
|
49
68
|
}
|