@stigg/react-sdk 5.23.1 → 5.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/common/mediaQuery.d.ts +12 -0
- package/dist/components/hooks/useIsScreenWiderThan.d.ts +2 -0
- package/dist/react-sdk.cjs.development.js +155 -102
- 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 +163 -122
- package/dist/react-sdk.esm.js.map +1 -1
- package/package.json +6 -4
- package/src/components/checkout/CheckoutContainer.style.ts +18 -3
- package/src/components/checkout/progressBar/CheckoutProgressBar.tsx +24 -5
- package/src/components/checkout/steps/addons/CheckoutAddonsStep.style.tsx +11 -3
- package/src/components/checkout/steps/addons/CheckoutAddonsStep.tsx +4 -2
- package/src/components/checkout/steps/plan/CheckoutChargeList.tsx +13 -6
- package/src/components/checkout/summary/CheckoutSuccess.tsx +8 -2
- package/src/components/checkout/summary/CheckoutSummary.tsx +6 -1
- package/src/components/checkout/summary/components/LineItems.tsx +15 -4
- package/src/components/common/mediaQuery.ts +19 -0
- package/src/components/customerPortal/billing/InformationGrid.tsx +1 -0
- package/src/components/customerPortal/billing/PaymentDetailsSection.tsx +15 -3
- package/src/components/customerPortal/common/SectionContainer.tsx +12 -1
- package/src/components/customerPortal/subscriptionOverview/SubscriptionOverviewLoader.tsx +4 -1
- package/src/components/customerPortal/subscriptionOverview/SubscriptionsOverview.tsx +3 -1
- package/src/components/customerPortal/usage/CustomerUsageData.style.tsx +4 -2
- package/src/components/customerPortal/usage/CustomerUsageData.tsx +6 -3
- package/src/components/hooks/useIsScreenWiderThan.ts +6 -0
- package/src/stories/Checkout.stories.tsx +2 -1
- package/src/stories/CustomerPortal.stories.tsx +2 -1
- package/src/stories/baseArgs.ts +4 -4
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "5.
|
|
2
|
+
"version": "5.24.0",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"typings": "dist/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"prepare": "husky install",
|
|
26
26
|
"docs": "typedoc",
|
|
27
27
|
"link-sdk": "yarn link && cd node_modules/react && yarn link && cd ../../node_modules/react-dom && yarn link && cd ../../",
|
|
28
|
-
"publish-storybook": "export NODE_OPTIONS=--openssl-legacy-provider && yarn build-storybook && npx chromatic --project-token=cbd1660d8132"
|
|
28
|
+
"publish-storybook": "export NODE_OPTIONS=--openssl-legacy-provider && yarn build-storybook && npx chromatic --project-token=cbd1660d8132 --exit-once-uploaded"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"react": ">=16"
|
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
]
|
|
43
43
|
},
|
|
44
44
|
"name": "@stigg/react-sdk",
|
|
45
|
-
"author":
|
|
45
|
+
"author": {
|
|
46
|
+
"name": "Stigg"
|
|
47
|
+
},
|
|
46
48
|
"module": "dist/react-sdk.esm.js",
|
|
47
49
|
"size-limit": [
|
|
48
50
|
{
|
|
@@ -132,5 +134,5 @@
|
|
|
132
134
|
"styled-typography": "^1.0.3"
|
|
133
135
|
},
|
|
134
136
|
"readme": "ERROR: No README data found!",
|
|
135
|
-
"_id": "@stigg/react-sdk@
|
|
137
|
+
"_id": "@stigg/react-sdk@5.23.0"
|
|
136
138
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import styled from '@emotion/styled/macro';
|
|
2
2
|
import Box from '@mui/material/Box';
|
|
3
|
+
import { mq } from '../common/mediaQuery';
|
|
3
4
|
|
|
4
5
|
export const CheckoutLayout = styled.div`
|
|
5
6
|
margin: auto;
|
|
6
|
-
width: 100%;
|
|
7
7
|
min-height: 760px;
|
|
8
8
|
max-width: 920px;
|
|
9
9
|
display: flex;
|
|
@@ -11,14 +11,19 @@ export const CheckoutLayout = styled.div`
|
|
|
11
11
|
flex-direction: column;
|
|
12
12
|
align-items: center;
|
|
13
13
|
|
|
14
|
-
padding: 16px 32px;
|
|
15
|
-
border-radius: 10px;
|
|
16
14
|
background-color: ${({ theme }) => theme.stigg.palette.backgroundPaper};
|
|
17
15
|
border: ${({ theme }) => `1px solid ${theme.stigg.palette.outlinedBorder}`};
|
|
18
16
|
|
|
19
17
|
& * {
|
|
20
18
|
box-sizing: border-box;
|
|
21
19
|
}
|
|
20
|
+
|
|
21
|
+
padding: 16px 16px;
|
|
22
|
+
${mq.md} {
|
|
23
|
+
padding: 32px;
|
|
24
|
+
width: calc(100% - 64px);
|
|
25
|
+
border-radius: 10px;
|
|
26
|
+
}
|
|
22
27
|
`;
|
|
23
28
|
export const CheckoutContent = styled(Box)`
|
|
24
29
|
display: flex;
|
|
@@ -26,6 +31,11 @@ export const CheckoutContent = styled(Box)`
|
|
|
26
31
|
gap: 32px;
|
|
27
32
|
flex-wrap: wrap;
|
|
28
33
|
width: 100%;
|
|
34
|
+
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
${mq.md} {
|
|
37
|
+
flex-direction: row;
|
|
38
|
+
}
|
|
29
39
|
`;
|
|
30
40
|
|
|
31
41
|
export const CheckoutPanel = styled(Box)`
|
|
@@ -33,4 +43,9 @@ export const CheckoutPanel = styled(Box)`
|
|
|
33
43
|
flex-direction: column;
|
|
34
44
|
gap: 0;
|
|
35
45
|
flex: 2;
|
|
46
|
+
|
|
47
|
+
width: 100%;
|
|
48
|
+
${mq.md} {
|
|
49
|
+
width: auto;
|
|
50
|
+
}
|
|
36
51
|
`;
|
|
@@ -1,26 +1,39 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import Grid from '@mui/material/Grid';
|
|
3
3
|
import Box from '@mui/material/Box';
|
|
4
4
|
import StepIcon from '@mui/material/StepIcon';
|
|
5
5
|
import { useCheckoutModel, useProgressBarModel } from '../hooks';
|
|
6
6
|
import { Typography } from '../../common/Typography';
|
|
7
|
-
import { StyledProgress, StyledStepButton
|
|
7
|
+
import { StyledIcon, StyledProgress, StyledStepButton } from './CheckoutProgressBar.style';
|
|
8
8
|
import { Icons } from '../../common/Icon';
|
|
9
9
|
import { Skeleton } from '../components/Skeletons.style';
|
|
10
|
+
import { useIsScreenWiderThan } from '../../hooks/useIsScreenWiderThan';
|
|
10
11
|
|
|
11
12
|
export const CheckoutProgressBar = () => {
|
|
12
|
-
const { progressBarState, setActiveStep } = useProgressBarModel();
|
|
13
|
+
const { progressBarState, setActiveStep, currentStep } = useProgressBarModel();
|
|
13
14
|
const { widgetState } = useCheckoutModel();
|
|
15
|
+
const isScreenWiderThanMd = useIsScreenWiderThan('md');
|
|
16
|
+
const containerRef = useRef<HTMLElement>();
|
|
14
17
|
const { readOnly, isLoadingCheckoutData } = widgetState;
|
|
15
18
|
const { activeStep, completedSteps, steps } = progressBarState || {};
|
|
16
19
|
const progress = ((activeStep + 1) * 100) / steps.length;
|
|
17
20
|
|
|
21
|
+
const [previousStep, setPreviousStep] = React.useState(currentStep);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!isScreenWiderThanMd) {
|
|
24
|
+
if (containerRef.current && currentStep !== previousStep) {
|
|
25
|
+
containerRef.current.scrollIntoView({ behavior: 'smooth' });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
setPreviousStep(currentStep);
|
|
29
|
+
}, [currentStep, isScreenWiderThanMd, previousStep, setPreviousStep]);
|
|
30
|
+
|
|
18
31
|
if (progressBarState.steps.length === 1) {
|
|
19
32
|
return null;
|
|
20
33
|
}
|
|
21
34
|
|
|
22
35
|
return (
|
|
23
|
-
<Box className="stigg-checkout-progress-container" sx={{ width: '100%', mb: 3 }}>
|
|
36
|
+
<Box className="stigg-checkout-progress-container" sx={{ width: '100%', mb: 3 }} ref={containerRef}>
|
|
24
37
|
<StyledProgress variant="determinate" value={progress} $disabled={readOnly} />
|
|
25
38
|
<Grid container display="flex">
|
|
26
39
|
{steps.map(({ key, label }, index) => {
|
|
@@ -32,7 +45,13 @@ export const CheckoutProgressBar = () => {
|
|
|
32
45
|
const checkedIcon: Icons = isDisabled ? 'OutlinedCheckedCircleDisabled' : 'OutlinedCheckedCircle';
|
|
33
46
|
|
|
34
47
|
return (
|
|
35
|
-
<Grid
|
|
48
|
+
<Grid
|
|
49
|
+
key={key}
|
|
50
|
+
item
|
|
51
|
+
display="flex"
|
|
52
|
+
flexDirection="row"
|
|
53
|
+
flex={isScreenWiderThanMd ? 1 : 'auto'}
|
|
54
|
+
justifyContent="flex-start">
|
|
36
55
|
{isLoadingCheckoutData ? (
|
|
37
56
|
<Skeleton width={120} height={20} style={{ marginTop: 8 }} />
|
|
38
57
|
) : (
|
|
@@ -2,6 +2,7 @@ import styled from '@emotion/styled/macro';
|
|
|
2
2
|
import Grid from '@mui/material/Grid';
|
|
3
3
|
|
|
4
4
|
import { Button } from '../../components';
|
|
5
|
+
import { mq } from '../../../common/mediaQuery';
|
|
5
6
|
|
|
6
7
|
export const CheckoutAddonsContainer = styled(Grid)`
|
|
7
8
|
width: 100%;
|
|
@@ -10,9 +11,16 @@ export const CheckoutAddonsContainer = styled(Grid)`
|
|
|
10
11
|
|
|
11
12
|
export const AddonListItemContainer = styled(Grid)`
|
|
12
13
|
display: flex;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
gap: 16px;
|
|
16
|
+
|
|
17
|
+
${mq.md} {
|
|
18
|
+
gap: 0;
|
|
19
|
+
flex-direction: row;
|
|
20
|
+
justify-content: space-between;
|
|
21
|
+
height: 80px;
|
|
22
|
+
align-items: center;
|
|
23
|
+
}
|
|
16
24
|
`;
|
|
17
25
|
|
|
18
26
|
export const TrashButton = styled(Button)`
|
|
@@ -13,6 +13,7 @@ import { AddonListItemContainer, CheckoutAddonsContainer, TrashButton } from './
|
|
|
13
13
|
import { CheckoutLocalization } from '../../configurations/textOverrides';
|
|
14
14
|
import { useCheckoutModel, useProgressBarModel } from '../../hooks';
|
|
15
15
|
import { ON_WHEEL_BLUR } from '../../../utils/onWheelBlur';
|
|
16
|
+
import { useIsScreenWiderThan } from '../../../hooks/useIsScreenWiderThan';
|
|
16
17
|
|
|
17
18
|
type UseAddonsStepModel = ReturnType<typeof useAddonsStepModel>;
|
|
18
19
|
|
|
@@ -39,6 +40,7 @@ function AddonListItem({
|
|
|
39
40
|
onAddonsValidationChange,
|
|
40
41
|
isValid,
|
|
41
42
|
}: AddonListItemProps) {
|
|
43
|
+
const isScreenWiderThanLg = useIsScreenWiderThan('lg');
|
|
42
44
|
const addonPrice = addon.pricePoints.find((pricePoint) => pricePoint.billingPeriod === billingPeriod);
|
|
43
45
|
const isAdded = !!addonState;
|
|
44
46
|
const hasChanges =
|
|
@@ -84,7 +86,7 @@ function AddonListItem({
|
|
|
84
86
|
</Typography>
|
|
85
87
|
)}
|
|
86
88
|
</Grid>
|
|
87
|
-
<Grid item>
|
|
89
|
+
<Grid item sx={{ gap: '16px' }} container={!isScreenWiderThanLg}>
|
|
88
90
|
{hasChanges && (
|
|
89
91
|
<Button variant="text" size="small" sx={{ padding: '8px', minWidth: 'unset' }} onClick={handleUndo}>
|
|
90
92
|
<Typography color="primary.main" variant="body1">
|
|
@@ -98,7 +100,7 @@ function AddonListItem({
|
|
|
98
100
|
id={`${addon.id}-input`}
|
|
99
101
|
type="number"
|
|
100
102
|
onWheel={ON_WHEEL_BLUR}
|
|
101
|
-
sx={{ width: 120
|
|
103
|
+
sx={isScreenWiderThanLg ? { marginX: 2, width: 120 } : { flex: 1 }}
|
|
102
104
|
value={addonState?.quantity ?? ''}
|
|
103
105
|
error={!isValid}
|
|
104
106
|
helperText={!isValid ? 'Minimum 1' : undefined}
|
|
@@ -15,6 +15,8 @@ import { TiersSelectContainer } from '../../../common/TiersSelectContainer';
|
|
|
15
15
|
import { getValidPriceQuantity } from '../../../utils/priceUtils';
|
|
16
16
|
import { getFeatureDisplayNameText } from '../../../utils/getFeatureName';
|
|
17
17
|
import { ON_WHEEL_BLUR } from '../../../utils/onWheelBlur';
|
|
18
|
+
import { mq } from '../../../common/mediaQuery';
|
|
19
|
+
import { useIsScreenWiderThan } from '../../../hooks/useIsScreenWiderThan';
|
|
18
20
|
|
|
19
21
|
export type UsePlanStepModel = ReturnType<typeof usePlanStepModel>;
|
|
20
22
|
|
|
@@ -25,11 +27,15 @@ type CheckoutChargeListProps = {
|
|
|
25
27
|
|
|
26
28
|
const StyledPlanCharge = styled.div`
|
|
27
29
|
display: flex;
|
|
28
|
-
flex-direction: row;
|
|
29
|
-
justify-content: space-between;
|
|
30
|
-
align-items: center;
|
|
31
30
|
min-height: 60px;
|
|
32
31
|
margin-top: 16px;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
|
|
34
|
+
${mq.md} {
|
|
35
|
+
flex-direction: row;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: space-between;
|
|
38
|
+
}
|
|
33
39
|
`;
|
|
34
40
|
|
|
35
41
|
const getValidationText = (charge: Price, quantity?: number) => {
|
|
@@ -58,6 +64,7 @@ export function PlanCharge({
|
|
|
58
64
|
setBillableFeature: UsePlanStepModel['setBillableFeature'];
|
|
59
65
|
onValidationChange: ({ featureId, isValid }: { featureId: string; isValid: boolean }) => void;
|
|
60
66
|
}) {
|
|
67
|
+
const isScreenWiderThanMd = useIsScreenWiderThan('md');
|
|
61
68
|
const featureId = charge.feature?.featureId;
|
|
62
69
|
const isBaseCharge = !featureId;
|
|
63
70
|
const isPayAsYouGo = charge.pricingModel === BillingModel.UsageBased;
|
|
@@ -120,7 +127,7 @@ export function PlanCharge({
|
|
|
120
127
|
} else {
|
|
121
128
|
chargeRow = (
|
|
122
129
|
<InputField
|
|
123
|
-
sx={{ width: 120 }}
|
|
130
|
+
sx={{ width: isScreenWiderThanMd ? 120 : '100%' }}
|
|
124
131
|
id={`${featureId}-input`}
|
|
125
132
|
type="number"
|
|
126
133
|
onWheel={ON_WHEEL_BLUR}
|
|
@@ -172,7 +179,7 @@ export function CheckoutChargeList({ plan, billingPeriod }: CheckoutChargeListPr
|
|
|
172
179
|
}, [chargesValidation, setIsDisabled, setIsValid]);
|
|
173
180
|
|
|
174
181
|
return (
|
|
175
|
-
|
|
182
|
+
<>
|
|
176
183
|
{planCharges?.map((charge) => {
|
|
177
184
|
const billableFeature = billableFeatures.find((x) => x.featureId === charge.feature?.featureId);
|
|
178
185
|
return (
|
|
@@ -188,6 +195,6 @@ export function CheckoutChargeList({ plan, billingPeriod }: CheckoutChargeListPr
|
|
|
188
195
|
/>
|
|
189
196
|
);
|
|
190
197
|
})}
|
|
191
|
-
|
|
198
|
+
</>
|
|
192
199
|
);
|
|
193
200
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styled from '@emotion/styled/macro';
|
|
2
2
|
import Box from '@mui/material/Box';
|
|
3
3
|
import Color from 'color';
|
|
4
|
-
import React from 'react';
|
|
4
|
+
import React, { useEffect, useRef } from 'react';
|
|
5
5
|
import Lottie from 'lottie-react';
|
|
6
6
|
import animationData from '../../../assets/lottie/checkout-success.json';
|
|
7
7
|
import { Typography } from '../../common/Typography';
|
|
@@ -70,8 +70,14 @@ const StyledLottie = styled(Lottie)`
|
|
|
70
70
|
`;
|
|
71
71
|
|
|
72
72
|
export function CheckoutSuccess({ checkoutLocalization }: { checkoutLocalization: CheckoutLocalization }) {
|
|
73
|
+
const containerRef = useRef<HTMLDivElement>();
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (containerRef.current) {
|
|
76
|
+
containerRef.current.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
|
|
77
|
+
}
|
|
78
|
+
}, []);
|
|
73
79
|
return (
|
|
74
|
-
<CheckoutSuccessContainer className="stigg-checkout-success-container">
|
|
80
|
+
<CheckoutSuccessContainer className="stigg-checkout-success-container" ref={containerRef}>
|
|
75
81
|
<StyledLottie animationData={animationData} loop={false} autoplay />
|
|
76
82
|
<CheckoutSuccessText variant="h1" color="primary.main">
|
|
77
83
|
{checkoutLocalization.summary.checkoutSuccessText}
|
|
@@ -37,16 +37,21 @@ import { Icon } from '../../common/Icon';
|
|
|
37
37
|
import { CheckoutLocalization } from '../configurations/textOverrides';
|
|
38
38
|
import { CheckoutSuccess } from './CheckoutSuccess';
|
|
39
39
|
import { getFeatureDisplayNameText } from '../../utils/getFeatureName';
|
|
40
|
+
import { mq } from '../../common/mediaQuery';
|
|
40
41
|
|
|
41
42
|
export const SummaryContainer = styled(Box)`
|
|
43
|
+
width: 100%;
|
|
42
44
|
max-width: 470px;
|
|
43
45
|
flex: 1.5;
|
|
44
46
|
`;
|
|
45
47
|
|
|
46
48
|
export const SummaryCard = styled(Paper)`
|
|
47
|
-
border-radius: 10px;
|
|
48
49
|
background: ${({ theme }) => theme.stigg.palette.backgroundHighlight};
|
|
49
50
|
padding: 16px;
|
|
51
|
+
|
|
52
|
+
${mq.md} {
|
|
53
|
+
border-radius: 10px;
|
|
54
|
+
}
|
|
50
55
|
`;
|
|
51
56
|
|
|
52
57
|
SummaryCard.defaultProps = {
|
|
@@ -24,6 +24,8 @@ import { getPriceBreakdownString } from './getPriceBreakdownString';
|
|
|
24
24
|
import { GraduatedPriceBreakdown } from './GraduatedPriceBreakdown';
|
|
25
25
|
import { CollapsableSectionIcon } from '../../../common/CollapsableSectionIcon';
|
|
26
26
|
import { calculateTierPrice } from '../../../utils/priceTierUtils';
|
|
27
|
+
import { useIsScreenWiderThan } from '../../../hooks/useIsScreenWiderThan';
|
|
28
|
+
import { mq } from '../../../common/mediaQuery';
|
|
27
29
|
|
|
28
30
|
export const LineItemContainer = styled.div`
|
|
29
31
|
& + & {
|
|
@@ -38,9 +40,14 @@ export const NestedBreakdownContainer = styled.div`
|
|
|
38
40
|
|
|
39
41
|
export const LineItemRow = styled.div`
|
|
40
42
|
display: flex;
|
|
41
|
-
|
|
42
|
-
justify-content: space-between;
|
|
43
|
+
flex-direction: column;
|
|
43
44
|
gap: 16px;
|
|
45
|
+
|
|
46
|
+
${mq.lg} {
|
|
47
|
+
flex-direction: row;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: space-between;
|
|
50
|
+
}
|
|
44
51
|
`;
|
|
45
52
|
|
|
46
53
|
const PayAsYouGoPriceTooltip = ({ checkoutLocalization }: { checkoutLocalization: CheckoutLocalization }) => {
|
|
@@ -63,6 +70,7 @@ export const BilledPriceLineItem = ({
|
|
|
63
70
|
quantity: number;
|
|
64
71
|
price: Price;
|
|
65
72
|
}) => {
|
|
73
|
+
const isScreenWiderThanLg = useIsScreenWiderThan('lg');
|
|
66
74
|
const [isNestedBreakdownOpen, setIsNestedBreakdownOpen] = useState(false);
|
|
67
75
|
const toggleNestedBreakdown = () => setIsNestedBreakdownOpen((prev) => !prev);
|
|
68
76
|
|
|
@@ -100,7 +108,7 @@ export const BilledPriceLineItem = ({
|
|
|
100
108
|
return (
|
|
101
109
|
<LineItemContainer className="stigg-checkout-summary-base-charges-container">
|
|
102
110
|
<LineItemRow style={{ alignItems: 'flex-start' }}>
|
|
103
|
-
<Grid item display="flex" gap={0.5} style={{ whiteSpace: 'nowrap' }}>
|
|
111
|
+
<Grid item display="flex" gap={0.5} style={{ whiteSpace: isScreenWiderThanLg ? 'nowrap' : 'break-spaces' }}>
|
|
104
112
|
{title}
|
|
105
113
|
{nestedBreakdown && (
|
|
106
114
|
<IconButton onClick={toggleNestedBreakdown} sx={{ padding: 0 }}>
|
|
@@ -110,7 +118,10 @@ export const BilledPriceLineItem = ({
|
|
|
110
118
|
</Grid>
|
|
111
119
|
<Grid item display="flex" gap={1} alignItems="center">
|
|
112
120
|
{isPayAsYouGo && <PayAsYouGoPriceTooltip checkoutLocalization={checkoutLocalization} />}
|
|
113
|
-
<Typography
|
|
121
|
+
<Typography
|
|
122
|
+
variant="body1"
|
|
123
|
+
color="secondary"
|
|
124
|
+
style={{ whiteSpace: isScreenWiderThanLg ? 'nowrap' : 'break-spaces' }}>
|
|
114
125
|
{getPriceBreakdownString({
|
|
115
126
|
totalAmount,
|
|
116
127
|
quantity,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const breakpoints = {
|
|
2
|
+
xs: 320,
|
|
3
|
+
sm: 640,
|
|
4
|
+
md: 768,
|
|
5
|
+
lg: 1024,
|
|
6
|
+
xl: 1280,
|
|
7
|
+
xxl: 1536,
|
|
8
|
+
} as const;
|
|
9
|
+
|
|
10
|
+
export type Breakpoints = typeof breakpoints;
|
|
11
|
+
|
|
12
|
+
export type Breakpoint = keyof Breakpoints;
|
|
13
|
+
|
|
14
|
+
export const mqMinWidth = (breakpoint: Breakpoint) => `(min-width: ${breakpoints[breakpoint]}px)`;
|
|
15
|
+
|
|
16
|
+
export const mq = Object.keys(breakpoints).reduce(
|
|
17
|
+
(obj, breakpoint) => ({ ...obj, [breakpoint]: `@media ${mqMinWidth(breakpoint as Breakpoint)}` }),
|
|
18
|
+
{} as Record<Breakpoint, string>,
|
|
19
|
+
);
|
|
@@ -9,11 +9,13 @@ import { ExternalLinkButton } from '../common/ExternalLinkButton';
|
|
|
9
9
|
import { InformationGrid, InformationGridContainer } from './InformationGrid';
|
|
10
10
|
import { SectionHeader } from '../common/SectionHeader';
|
|
11
11
|
import { SkeletonButton } from '../common/SkeletonButton';
|
|
12
|
+
import { useIsScreenWiderThan } from '../../hooks/useIsScreenWiderThan';
|
|
12
13
|
|
|
13
14
|
export const EMPTY_CHAR = '-';
|
|
14
15
|
|
|
15
16
|
export function PaymentDetailsSection() {
|
|
16
17
|
const { customerPortal, isLoading, textOverrides, theme } = useCustomerPortalContext();
|
|
18
|
+
const isScreenWiderThanMd = useIsScreenWiderThan('md');
|
|
17
19
|
const { billingInformation } = customerPortal || {};
|
|
18
20
|
const isLoadingData = !billingInformation || isLoading;
|
|
19
21
|
|
|
@@ -27,7 +29,11 @@ export function PaymentDetailsSection() {
|
|
|
27
29
|
<Skeleton width={220} height={12} />
|
|
28
30
|
<Skeleton width={220} height={12} />
|
|
29
31
|
</InformationGridContainer>,
|
|
30
|
-
<Divider
|
|
32
|
+
<Divider
|
|
33
|
+
key="information-loading-data-divider"
|
|
34
|
+
orientation="vertical"
|
|
35
|
+
style={{ minHeight: 93, display: isScreenWiderThanMd ? 'block' : 'none' }}
|
|
36
|
+
/>,
|
|
31
37
|
<InformationGridContainer key="information-loading-data-bottom">
|
|
32
38
|
<Skeleton width={220} height={12} />
|
|
33
39
|
<Skeleton width={220} height={12} />
|
|
@@ -64,7 +70,11 @@ export function PaymentDetailsSection() {
|
|
|
64
70
|
billingInformation.defaultPaymentExpirationYear
|
|
65
71
|
) {
|
|
66
72
|
items.unshift(
|
|
67
|
-
<Divider
|
|
73
|
+
<Divider
|
|
74
|
+
key="information-billing-data-divider"
|
|
75
|
+
orientation="vertical"
|
|
76
|
+
style={{ minHeight: 93, display: isScreenWiderThanMd ? 'block' : 'none' }}
|
|
77
|
+
/>,
|
|
68
78
|
);
|
|
69
79
|
items.unshift(
|
|
70
80
|
<InformationGrid
|
|
@@ -122,7 +132,9 @@ export function PaymentDetailsSection() {
|
|
|
122
132
|
{editButton}
|
|
123
133
|
</SectionHeader>
|
|
124
134
|
|
|
125
|
-
<div style={{ display: 'flex', alignItems: 'stretch', gap: 64 }}>
|
|
135
|
+
<div style={{ display: 'flex', alignItems: 'stretch', gap: isScreenWiderThanMd ? 64 : 32, flexWrap: 'wrap' }}>
|
|
136
|
+
{items}
|
|
137
|
+
</div>
|
|
126
138
|
</SectionContainer>
|
|
127
139
|
);
|
|
128
140
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import styled from '@emotion/styled/macro';
|
|
2
|
+
import { mq } from '../../common/mediaQuery';
|
|
2
3
|
|
|
3
4
|
export const SectionContainer = styled.div<{ $backgroundColor: string; $borderColor: string }>`
|
|
4
5
|
width: 100%;
|
|
@@ -7,5 +8,15 @@ export const SectionContainer = styled.div<{ $backgroundColor: string; $borderCo
|
|
|
7
8
|
border-radius: 10px;
|
|
8
9
|
background-color: ${({ $backgroundColor }) => $backgroundColor};
|
|
9
10
|
border: ${({ $borderColor }) => `1px solid ${$borderColor}`};
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
padding: 16px;
|
|
13
|
+
${mq.sm} {
|
|
14
|
+
padding: 32px;
|
|
15
|
+
}
|
|
16
|
+
${mq.md} {
|
|
17
|
+
padding: 48px;
|
|
18
|
+
}
|
|
19
|
+
${mq.lg} {
|
|
20
|
+
padding: 64px;
|
|
21
|
+
}
|
|
11
22
|
`;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import styled from '@emotion/styled/macro';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import Skeleton from 'react-loading-skeleton';
|
|
4
|
+
import { useIsScreenWiderThan } from '../../hooks/useIsScreenWiderThan';
|
|
4
5
|
|
|
5
6
|
const SkeletonLayout = styled.div`
|
|
6
7
|
display: flex;
|
|
7
8
|
justify-content: space-between;
|
|
9
|
+
flex-wrap: wrap;
|
|
8
10
|
`;
|
|
9
11
|
|
|
10
12
|
const SkeletonLayoutLeft = styled.div`
|
|
@@ -14,13 +16,14 @@ const SkeletonLayoutLeft = styled.div`
|
|
|
14
16
|
`;
|
|
15
17
|
|
|
16
18
|
export function SubscriptionOverviewLoader() {
|
|
19
|
+
const isScreenWiderThanMd = useIsScreenWiderThan('md');
|
|
17
20
|
return (
|
|
18
21
|
<SkeletonLayout className="stigg-subscription-overview-skeleton-layout">
|
|
19
22
|
<SkeletonLayoutLeft>
|
|
20
23
|
<Skeleton width={120} />
|
|
21
24
|
<Skeleton width={120} />
|
|
22
25
|
</SkeletonLayoutLeft>
|
|
23
|
-
<Skeleton width={295} height={193} />
|
|
26
|
+
<Skeleton width={isScreenWiderThanMd ? 295 : 260} height={193} />
|
|
24
27
|
</SkeletonLayout>
|
|
25
28
|
);
|
|
26
29
|
}
|
|
@@ -56,7 +56,9 @@ export function SubscriptionsOverview({
|
|
|
56
56
|
{isLoadingData || !mainSubscription ? (
|
|
57
57
|
<SubscriptionOverviewLoader />
|
|
58
58
|
) : (
|
|
59
|
-
<div
|
|
59
|
+
<div
|
|
60
|
+
className="stigg-overview-layout"
|
|
61
|
+
style={{ display: 'flex', alignItems: 'flex-start', gap: 64, flexWrap: 'wrap' }}>
|
|
60
62
|
<div style={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
|
|
61
63
|
<SubscriptionsOverviewHeader
|
|
62
64
|
onManageSubscription={onManageSubscription}
|
|
@@ -3,16 +3,18 @@ import Grid from '@mui/material/Grid';
|
|
|
3
3
|
import { range } from 'lodash';
|
|
4
4
|
import Skeleton from 'react-loading-skeleton';
|
|
5
5
|
import React from 'react';
|
|
6
|
+
import { useIsScreenWiderThan } from '../../hooks/useIsScreenWiderThan';
|
|
6
7
|
|
|
7
8
|
export const Footer = styled.div`
|
|
8
9
|
margin-top: 32px;
|
|
9
10
|
`;
|
|
10
11
|
|
|
11
12
|
export function CustomerUsageLoader() {
|
|
13
|
+
const isMdScreen = useIsScreenWiderThan('md');
|
|
12
14
|
return (
|
|
13
|
-
<Grid container spacing={4} className="stigg-subscription-usage-skeleton-layout">
|
|
15
|
+
<Grid container spacing={4} className="stigg-subscription-usage-skeleton-layout" sx={{ flexWrap: 'wrap' }}>
|
|
14
16
|
{range(6).map((item) => (
|
|
15
|
-
<Grid key={item} item xs={4}>
|
|
17
|
+
<Grid key={item} item xs={isMdScreen ? 4 : 12}>
|
|
16
18
|
<Skeleton width={280} height={120} />
|
|
17
19
|
</Grid>
|
|
18
20
|
))}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MeterType, PricingType, SubscriptionStatus } from '@stigg/js-client-sdk';
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
3
|
import { compact, keyBy } from 'lodash';
|
|
4
4
|
import { Minus, Plus } from 'react-feather';
|
|
5
5
|
import Grid from '@mui/material/Grid';
|
|
@@ -12,6 +12,7 @@ import { SectionTitle } from '../common/SectionTitle';
|
|
|
12
12
|
import { StyledButton } from '../common/StyledButton';
|
|
13
13
|
import { FilterEntitlementsFn, OnBuyMoreCallbackFn } from '../types';
|
|
14
14
|
import { OnManageClick } from '../CustomerPortalContainer';
|
|
15
|
+
import { useIsScreenWiderThan } from '../../hooks/useIsScreenWiderThan';
|
|
15
16
|
|
|
16
17
|
const MAX_BOXES = 6;
|
|
17
18
|
|
|
@@ -22,7 +23,9 @@ export type CustomerUsageDataProps = {
|
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
export function CustomerUsageData({ onManageSubscription, onBuyMore, filterEntitlements }: CustomerUsageDataProps) {
|
|
25
|
-
const [showAll, setShowAll] =
|
|
26
|
+
const [showAll, setShowAll] = useState(false);
|
|
27
|
+
const isMdScreen = useIsScreenWiderThan('md');
|
|
28
|
+
|
|
26
29
|
const { customerPortal, isLoading, textOverrides, theme } = useCustomerPortalContext();
|
|
27
30
|
const isLoadingData = isLoading || !customerPortal;
|
|
28
31
|
const { entitlements, subscriptions } = customerPortal || {};
|
|
@@ -52,7 +55,7 @@ export function CustomerUsageData({ onManageSubscription, onBuyMore, filterEntit
|
|
|
52
55
|
const filteredEntitlements = filterEntitlements ? filterEntitlements(sortedEntitlements) : sortedEntitlements;
|
|
53
56
|
|
|
54
57
|
// 4 -> 3 per row, 6 -> 2 per row
|
|
55
|
-
const xs = filteredEntitlements.length > 2 ? 4 : 6;
|
|
58
|
+
const xs = isMdScreen ? (filteredEntitlements.length > 2 ? 4 : 6) : 12;
|
|
56
59
|
|
|
57
60
|
const entitlementsToShow = showAll ? filteredEntitlements : filteredEntitlements.slice(0, MAX_BOXES);
|
|
58
61
|
|
package/src/stories/baseArgs.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export const defaultArgs = {
|
|
2
|
-
apiKey: process.env.
|
|
3
|
-
baseUri: process.env.
|
|
4
|
-
disableEdge: Boolean(process.env.
|
|
2
|
+
apiKey: process.env.STORYBOOK_API_KEY || 'place your api key here',
|
|
3
|
+
baseUri: process.env.STORYBOOK_BASE_URI || 'https://api.stigg.io',
|
|
4
|
+
disableEdge: Boolean(process.env.STORYBOOK_DISABLE_EDGE),
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
export const defaultArgsWithCustomer = {
|
|
8
8
|
...defaultArgs,
|
|
9
|
-
customerId: process.env.
|
|
9
|
+
customerId: process.env.STORYBOOK_CUSTOMER_ID || 'customer-demo-01',
|
|
10
10
|
};
|