@edx/frontend-app-subscription-learner-dashboard 1.29.1 → 1.30.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.
|
@@ -3,61 +3,58 @@ import { useEffect, useMemo, useState } from 'react';
|
|
|
3
3
|
import { Alert, Button, Icon } from '@openedx/paragon';
|
|
4
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
5
5
|
import { utilHooks } from '../../../hooks';
|
|
6
|
+
import { useInitializeSubsDashboard } from '../../../data/hooks';
|
|
6
7
|
import messages from '../messages';
|
|
7
8
|
import { manageSubscriptionURL } from '../../../data/constants/app';
|
|
8
9
|
import '../index.scss';
|
|
9
10
|
import { Cached, WarningFilled, Cancel } from '@openedx/paragon/icons';
|
|
10
11
|
import { subscriptionRenewalURL } from '../../../data/constants/app';
|
|
11
|
-
// TODO: We can replace the below hardcoded subscriptionInformationData with the actual data from the API once we have the API ready.
|
|
12
|
-
// For now, we can use this hardcoded data to test the SubscriptionInformation component.
|
|
13
|
-
const subscriptionInformationData = {
|
|
14
|
-
isSubscribed: true,
|
|
15
|
-
status: 'Active', // can be 'active', 'cancelled', 'renewalFailed'
|
|
16
|
-
subscriptionStartDate: '05/22/25',
|
|
17
|
-
subscriptionEndDate: '05/22/26',
|
|
18
|
-
subscriptionRenewalDate: '05/22/26',
|
|
19
|
-
subscriptionRenewalPrice: '$36',
|
|
20
|
-
numberOfCoursesEnrolled: 5,
|
|
21
|
-
totalSavings: '$120',
|
|
22
|
-
planName: 'Monthly plan',
|
|
23
|
-
};
|
|
24
12
|
export const SubscriptionInformation = () => {
|
|
25
|
-
var _a;
|
|
13
|
+
var _a, _b, _c, _d, _e;
|
|
14
|
+
const { data: subsData } = useInitializeSubsDashboard();
|
|
26
15
|
const { formatMessage } = useIntl();
|
|
27
16
|
const formatDate = utilHooks.useFormatDate();
|
|
28
17
|
const [infoBody, setInfoBody] = useState('');
|
|
29
18
|
const [infoTitle, setInfoTitle] = useState('');
|
|
19
|
+
const status = (_a = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _a === void 0 ? void 0 : _a.status;
|
|
30
20
|
useEffect(() => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
var _a, _b, _c, _d, _e;
|
|
22
|
+
if (!status) {
|
|
23
|
+
setInfoTitle('');
|
|
24
|
+
setInfoBody('');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
switch (status) {
|
|
28
|
+
case 'ACTIVE':
|
|
29
|
+
case 'TRIAL_ACTIVE':
|
|
30
|
+
case 'RENEWAL_PENDING':
|
|
34
31
|
setInfoTitle(formatMessage(messages.activeSubscriptionTitle, {
|
|
35
|
-
subscriptionStatus:
|
|
36
|
-
planName:
|
|
32
|
+
subscriptionStatus: status.split('_').map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join(' '),
|
|
33
|
+
planName: (_a = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _a === void 0 ? void 0 : _a.planName,
|
|
37
34
|
}));
|
|
38
35
|
setInfoBody(formatMessage(messages.renewalMessage, {
|
|
39
|
-
subscriptionRenewalDate: formatDate(
|
|
36
|
+
subscriptionRenewalDate: formatDate((_b = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _b === void 0 ? void 0 : _b.currentPeriodEnd),
|
|
40
37
|
}));
|
|
41
38
|
break;
|
|
42
|
-
case '
|
|
39
|
+
case 'CANCELLED':
|
|
43
40
|
setInfoTitle(formatMessage(messages.cancelledSubscriptionTitle, {
|
|
44
|
-
subscriptionStatus:
|
|
45
|
-
planName:
|
|
41
|
+
subscriptionStatus: status.charAt(0).toUpperCase() + status.slice(1).toLowerCase(),
|
|
42
|
+
planName: (_c = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _c === void 0 ? void 0 : _c.planName,
|
|
46
43
|
}));
|
|
47
44
|
setInfoBody(formatMessage(messages.cancelledSubscriptionBody, {
|
|
48
|
-
subscriptionEndDate: formatDate(
|
|
45
|
+
subscriptionEndDate: formatDate((_d = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _d === void 0 ? void 0 : _d.subscriptionEndDate),
|
|
49
46
|
}));
|
|
50
47
|
break;
|
|
51
|
-
case '
|
|
48
|
+
case 'RENEWAL_FAILED': // also known as 'Payment Error' in figma designs
|
|
52
49
|
setInfoTitle(formatMessage(messages.renewalFailedTitle));
|
|
53
50
|
setInfoBody(formatMessage(messages.renewalFailedBody, {
|
|
54
|
-
subscriptionRenewalDate: formatDate(
|
|
51
|
+
subscriptionRenewalDate: formatDate((_e = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _e === void 0 ? void 0 : _e.currentPeriodEnd),
|
|
55
52
|
}));
|
|
56
53
|
break;
|
|
57
54
|
}
|
|
58
|
-
}, [formatDate, formatMessage]);
|
|
55
|
+
}, [formatDate, formatMessage, status, (_b = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _b === void 0 ? void 0 : _b.planName, (_c = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _c === void 0 ? void 0 : _c.currentPeriodEnd, (_d = subsData === null || subsData === void 0 ? void 0 : subsData.userSubscription) === null || _d === void 0 ? void 0 : _d.subscriptionEndDate]);
|
|
59
56
|
const getSubscriptionAction = useMemo(() => {
|
|
60
|
-
if (
|
|
57
|
+
if (status === 'CANCELLED') {
|
|
61
58
|
return ([
|
|
62
59
|
_jsx(Button, { "data-testid": "renew-button", className: "renew-button", variant: "tertiary", href: subscriptionRenewalURL, target: "_blank", rel: "noopener noreferrer", role: "link", children: formatMessage(messages.renewSubscriptionButton) }, "renew-subscription"),
|
|
63
60
|
]);
|
|
@@ -66,14 +63,15 @@ export const SubscriptionInformation = () => {
|
|
|
66
63
|
return ([
|
|
67
64
|
_jsx(Button, { variant: "tertiary", "data-testid": "manage-button", href: manageSubscriptionURL, target: "_blank", rel: "noopener noreferrer", role: "link", children: formatMessage(messages.manageSubscriptionMessage) }, "manage-subscription"),
|
|
68
65
|
]);
|
|
69
|
-
}, [formatMessage]);
|
|
66
|
+
}, [formatMessage, status]);
|
|
70
67
|
const subscriptionStatusIcons = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
ACTIVE: Cached,
|
|
69
|
+
TRIAL_ACTIVE: Cached,
|
|
70
|
+
CANCELLED: Cancel,
|
|
71
|
+
RENEWAL_FAILED: WarningFilled,
|
|
72
|
+
RENEWAL_PENDING: Cached,
|
|
75
73
|
};
|
|
76
|
-
const bannerIcon = (
|
|
74
|
+
const bannerIcon = (_e = subscriptionStatusIcons[status]) !== null && _e !== void 0 ? _e : undefined;
|
|
77
75
|
return (_jsxs("div", { className: "container subscription-information py-5 px-4", children: [_jsx("h2", { className: "mb-4 my-subscription-heading", children: formatMessage(messages.mySubscriptionHeading) }), _jsxs(Alert, { dismissible: false, show: true, actions: getSubscriptionAction, className: "subscription-status-alert bg-white", children: [_jsxs(Alert.Heading, { as: "h6", children: [_jsx(Icon, { src: bannerIcon, className: `icon mr-1 ${bannerIcon === WarningFilled ? 'warning-icon text-warning-500' : ''}`, "data-testid": "subscription-status-icon" }), infoTitle] }), _jsx("p", { children: infoBody })] })] }));
|
|
78
76
|
};
|
|
79
77
|
//# sourceMappingURL=SubscriptionInformation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionInformation.js","sourceRoot":"","sources":["../../../../src/containers/SubscriptionInformation/components/SubscriptionInformation.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAM,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,QAAQ,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAQ,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,
|
|
1
|
+
{"version":3,"file":"SubscriptionInformation.js","sourceRoot":"","sources":["../../../../src/containers/SubscriptionInformation/components/SubscriptionInformation.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FC, useEffect, useMemo, useState } from 'react';\nimport { Alert, Button, Icon } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { utilHooks } from '@src/hooks';\nimport { useInitializeSubsDashboard } from '@src/data/hooks';\nimport messages from '../messages';\nimport { manageSubscriptionURL } from '@src/data/constants/app';\nimport '../index.scss';\nimport { Cached, WarningFilled, Cancel, Info } from '@openedx/paragon/icons';\nimport { subscriptionRenewalURL } from '@src/data/constants/app';\n\nexport const SubscriptionInformation: FC = () => {\n const { data: subsData } = useInitializeSubsDashboard();\n const { formatMessage } = useIntl();\n const formatDate = utilHooks.useFormatDate();\n const [infoBody, setInfoBody] = useState('');\n const [infoTitle, setInfoTitle] = useState('');\n const status = subsData?.userSubscription?.status;\n\n useEffect(() => {\n if (!status) {\n setInfoTitle('');\n setInfoBody('');\n return;\n }\n\n switch (status) {\n case 'ACTIVE':\n case 'TRIAL_ACTIVE':\n case 'RENEWAL_PENDING':\n setInfoTitle(formatMessage(messages.activeSubscriptionTitle, {\n subscriptionStatus: status.split('_').map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join(' '),\n planName: subsData?.userSubscription?.planName,\n }));\n setInfoBody(formatMessage(messages.renewalMessage, {\n subscriptionRenewalDate: formatDate(subsData?.userSubscription?.currentPeriodEnd),\n }));\n break;\n case 'CANCELLED':\n setInfoTitle(formatMessage(messages.cancelledSubscriptionTitle, {\n subscriptionStatus: status.charAt(0).toUpperCase() + status.slice(1).toLowerCase(),\n planName: subsData?.userSubscription?.planName,\n }));\n setInfoBody(formatMessage(messages.cancelledSubscriptionBody, {\n subscriptionEndDate: formatDate(subsData?.userSubscription?.subscriptionEndDate),\n }));\n break;\n case 'RENEWAL_FAILED': // also known as 'Payment Error' in figma designs\n setInfoTitle(formatMessage(messages.renewalFailedTitle));\n setInfoBody(formatMessage(messages.renewalFailedBody, {\n subscriptionRenewalDate: formatDate(subsData?.userSubscription?.currentPeriodEnd),\n }));\n break;\n }\n }, [formatDate, formatMessage, status, subsData?.userSubscription?.planName, subsData?.userSubscription?.currentPeriodEnd, subsData?.userSubscription?.subscriptionEndDate]);\n\n const getSubscriptionAction = useMemo(() => {\n if (status === 'CANCELLED') {\n return (\n [\n <Button\n key=\"renew-subscription\"\n data-testid=\"renew-button\"\n className=\"renew-button\"\n variant=\"tertiary\"\n href={subscriptionRenewalURL}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n role=\"link\"\n >\n {formatMessage(messages.renewSubscriptionButton)}\n </Button>,\n ]\n );\n } else\n return (\n [\n <Button\n key=\"manage-subscription\"\n variant=\"tertiary\"\n data-testid=\"manage-button\"\n href={manageSubscriptionURL}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n role=\"link\"\n >\n {formatMessage(messages.manageSubscriptionMessage)}\n </Button>,\n ]\n );\n }, [formatMessage, status]);\n\n const subscriptionStatusIcons: Record<string, typeof Info | undefined> = {\n ACTIVE: Cached,\n TRIAL_ACTIVE: Cached,\n CANCELLED: Cancel,\n RENEWAL_FAILED: WarningFilled,\n RENEWAL_PENDING: Cached,\n };\n\n const bannerIcon = subscriptionStatusIcons[status] ?? undefined;\n\n return (\n <div className=\"container subscription-information py-5 px-4\">\n <h2 className=\"mb-4 my-subscription-heading\">{formatMessage(messages.mySubscriptionHeading)}</h2>\n <Alert\n dismissible={false}\n show={true}\n actions={getSubscriptionAction}\n className=\"subscription-status-alert bg-white\"\n >\n <Alert.Heading as=\"h6\">\n <Icon src={bannerIcon} className={`icon mr-1 ${bannerIcon === WarningFilled ? 'warning-icon text-warning-500' : ''}`} data-testid=\"subscription-status-icon\" />\n {infoTitle}\n </Alert.Heading>\n <p>\n {infoBody}\n </p>\n </Alert>\n </div>\n );\n};\n"]}
|