@edx/frontend-app-subscription-manage 1.7.0 → 1.9.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/Main.js +2 -2
- package/dist/Main.js.map +1 -1
- package/dist/components/ActiveSubscription/ActiveSubscription.js +6 -1
- package/dist/components/ActiveSubscription/ActiveSubscription.js.map +1 -1
- package/dist/components/HelpFooter/HelpFooter.js +3 -1
- package/dist/components/HelpFooter/HelpFooter.js.map +1 -1
- package/dist/components/SubscriptionTabs/SubscriptionTabs.js +7 -1
- package/dist/components/SubscriptionTabs/SubscriptionTabs.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/data/services/segment/index.d.ts +3 -0
- package/dist/data/services/segment/index.js +13 -0
- package/dist/data/services/segment/index.js.map +1 -0
- package/dist/data/services/subscription/getIsCurrentUserSubscriber.js +5 -1
- package/dist/data/services/subscription/getIsCurrentUserSubscriber.js.map +1 -1
- package/dist/routes.js +2 -0
- package/dist/routes.js.map +1 -1
- package/dist/tracking/index.d.ts +8 -0
- package/dist/tracking/index.js +13 -0
- package/dist/tracking/index.js.map +1 -0
- package/dist/tracking/trackingContext.d.ts +11 -0
- package/dist/tracking/trackingContext.js +18 -0
- package/dist/tracking/trackingContext.js.map +1 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/subscriptionView.js +19 -1
- package/dist/utils/subscriptionView.js.map +1 -1
- package/package.json +1 -1
package/dist/Main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { CurrentAppProvider, getSiteConfig, useIntl, } from '@openedx/frontend-base';
|
|
2
|
+
import { CurrentAppProvider, getSiteConfig, useIntl, PageWrap } from '@openedx/frontend-base';
|
|
3
3
|
import { Helmet } from 'react-helmet';
|
|
4
4
|
import { Outlet } from 'react-router-dom';
|
|
5
5
|
import { appId } from './constants';
|
|
@@ -9,7 +9,7 @@ const Main = () => {
|
|
|
9
9
|
const { formatMessage } = useIntl();
|
|
10
10
|
return (_jsxs(CurrentAppProvider, { appId: appId, children: [_jsx(Helmet, { children: _jsx("title", { children: formatMessage(messages['template.page.title'], {
|
|
11
11
|
siteName: getSiteConfig().siteName,
|
|
12
|
-
}) }) }), _jsx("main", { className: "d-flex flex-column flex-grow-1", children: _jsx(Outlet, {}) })] }));
|
|
12
|
+
}) }) }), _jsx("main", { className: "d-flex flex-column flex-grow-1", children: _jsx(PageWrap, { children: _jsx(Outlet, {}) }) })] }));
|
|
13
13
|
};
|
|
14
14
|
export default Main;
|
|
15
15
|
//# sourceMappingURL=Main.js.map
|
package/dist/Main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,OAAO,
|
|
1
|
+
{"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,OAAO,EACP,QAAQ,EACT,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,OAAO,cAAc,CAAC;AAEtB,MAAM,IAAI,GAAG,GAAG,EAAE;IAChB,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,OAAO,CACL,MAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,aAC9B,KAAC,MAAM,cACL,0BACG,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE;wBAC9C,QAAQ,EAAE,aAAa,EAAE,CAAC,QAAQ;qBACnC,CAAC,GACI,GACD,EACT,eAAM,SAAS,EAAC,gCAAgC,YAC9C,KAAC,QAAQ,cACP,KAAC,MAAM,KAAG,GACD,GACN,IACY,CACtB,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import {\n CurrentAppProvider,\n getSiteConfig,\n useIntl,\n PageWrap\n} from '@openedx/frontend-base';\nimport { Helmet } from 'react-helmet';\nimport { Outlet } from 'react-router-dom';\nimport { appId } from './constants';\nimport messages from './messages';\n\nimport './style.scss';\n\nconst Main = () => {\n const { formatMessage } = useIntl();\n return (\n <CurrentAppProvider appId={appId}>\n <Helmet>\n <title>\n {formatMessage(messages['template.page.title'], {\n siteName: getSiteConfig().siteName,\n })}\n </title>\n </Helmet>\n <main className=\"d-flex flex-column flex-grow-1\">\n <PageWrap>\n <Outlet />\n </PageWrap>\n </main>\n </CurrentAppProvider>\n );\n};\n\nexport default Main;\n"]}
|
|
@@ -9,6 +9,7 @@ import { resolvePlanLabel } from '../../utils/subscriptionView';
|
|
|
9
9
|
import { MANAGE_PAGE_PATH } from '../../constants';
|
|
10
10
|
import UpdatePaymentMethodModal from '../UpdatePaymentMethodModal/UpdatePaymentMethodModal';
|
|
11
11
|
import messages from '../messages';
|
|
12
|
+
import { trackManageSubscriptionUpdatePaymentButtonClick } from '../../tracking';
|
|
12
13
|
const ActiveSubscription = ({ subscriber }) => {
|
|
13
14
|
const { formatMessage } = useIntl();
|
|
14
15
|
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
|
|
@@ -16,9 +17,13 @@ const ActiveSubscription = ({ subscriber }) => {
|
|
|
16
17
|
const sinceDate = formatDisplayDate(subscriber === null || subscriber === void 0 ? void 0 : subscriber.subscriptionStartDate);
|
|
17
18
|
const nextPayment = formatDisplayDate(subscriber === null || subscriber === void 0 ? void 0 : subscriber.currentPeriodEnd);
|
|
18
19
|
const canUpdatePayment = Boolean(subscriber === null || subscriber === void 0 ? void 0 : subscriber.subscriptionBiId);
|
|
20
|
+
const handleUpdatePaymentClick = () => {
|
|
21
|
+
trackManageSubscriptionUpdatePaymentButtonClick({ buttonName: 'updatePayment' });
|
|
22
|
+
setIsPaymentModalOpen(true);
|
|
23
|
+
};
|
|
19
24
|
return (_jsxs("section", { className: "manage-section mt-4", children: [_jsx("h2", { className: "manage-section__title h3 font-weight-bold text-primary-500 mb-1", children: formatMessage(messages['manage.active.heading']) }), sinceDate && (_jsx("p", { className: "manage-section__subtitle text-gray-700 mb-3", children: formatMessage(messages['manage.active.since'], { date: sinceDate }) })), _jsxs("div", { className: "manage-card d-flex flex-column flex-md-row align-items-md-center justify-content-md-between bg-white border p-4 rounded", children: [_jsxs("div", { className: "manage-card__content", children: [_jsxs("div", { className: "manage-card__status-row d-flex align-items-center mb-1", children: [_jsx(Icon, { src: SpinnerIcon, className: "manage-card__status-badge manage-card__status-badge--sync flex-shrink-0", "aria-hidden": true }), _jsx("span", { className: "manage-card__status-label font-weight-bold text-primary-500", children: formatMessage(plan === 'annual'
|
|
20
25
|
? messages['manage.active.statusAnnual']
|
|
21
|
-
: messages['manage.active.statusMonthly']) })] }), nextPayment && (_jsx("p", { className: "manage-card__body text-gray-700 mb-0", children: formatMessage(messages['manage.active.nextPayment'], { date: nextPayment }) }))] }), _jsx("div", { className: "manage-card__actions manage-card__actions--row d-flex flex-wrap align-items-center flex-shrink-0 justify-content-end", children: _jsx(Button, { className: "manage-btn manage-btn--dark", variant: "primary", onClick:
|
|
26
|
+
: messages['manage.active.statusMonthly']) })] }), nextPayment && (_jsx("p", { className: "manage-card__body text-gray-700 mb-0", children: formatMessage(messages['manage.active.nextPayment'], { date: nextPayment }) }))] }), _jsx("div", { className: "manage-card__actions manage-card__actions--row d-flex flex-wrap align-items-center flex-shrink-0 justify-content-end", children: _jsx(Button, { className: "manage-btn manage-btn--dark", variant: "primary", onClick: handleUpdatePaymentClick, disabled: !canUpdatePayment, children: formatMessage(messages['manage.active.updatePayment']) }) })] }), _jsxs("p", { className: "manage-cancel-prompt mt-3 text-right text-gray-700 small", children: [formatMessage(messages['manage.active.cancelPrompt']), ' ', _jsx(Link, { className: "manage-cancel-prompt__link text-info-500 font-weight-bold text-decoration-none", to: `/${MANAGE_PAGE_PATH}/cancel`, children: formatMessage(messages['manage.active.cancelLink']) })] }), _jsx(UpdatePaymentMethodModal, { isOpen: isPaymentModalOpen, onClose: () => setIsPaymentModalOpen(false), subscriptionBiId: subscriber === null || subscriber === void 0 ? void 0 : subscriber.subscriptionBiId, nextBillingDate: nextPayment })] }));
|
|
22
27
|
};
|
|
23
28
|
export default ActiveSubscription;
|
|
24
29
|
//# sourceMappingURL=ActiveSubscription.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActiveSubscription.js","sourceRoot":"","sources":["../../../src/components/ActiveSubscription/ActiveSubscription.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,wBAAwB,MAAM,sDAAsD,CAAC;AAC5F,OAAO,QAAQ,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ActiveSubscription.js","sourceRoot":"","sources":["../../../src/components/ActiveSubscription/ActiveSubscription.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,wBAAwB,MAAM,sDAAsD,CAAC;AAC5F,OAAO,QAAQ,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,+CAA+C,EAAE,MAAM,eAAe,CAAC;AAMhF,MAAM,kBAAkB,GAAsC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE;IAC/E,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,qBAAqB,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,iBAAiB,CAAC,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,gBAAgB,CAAC,CAAC;IACpE,MAAM,gBAAgB,GAAG,OAAO,CAAC,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,gBAAgB,CAAC,CAAC;IAE/D,MAAM,wBAAwB,GAAG,GAAG,EAAE;QACpC,+CAA+C,CAAC,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC,CAAC;QACjF,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,OAAO,CACL,mBAAS,SAAS,EAAC,qBAAqB,aACtC,aAAI,SAAS,EAAC,iEAAiE,YAC5E,aAAa,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,GAC9C,EACJ,SAAS,IAAI,CACZ,YAAG,SAAS,EAAC,6CAA6C,YACvD,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,GAClE,CACL,EAED,eAAK,SAAS,EAAC,yHAAyH,aACtI,eAAK,SAAS,EAAC,sBAAsB,aACnC,eAAK,SAAS,EAAC,wDAAwD,aACrE,KAAC,IAAI,IACH,GAAG,EAAE,WAAW,EAChB,SAAS,EAAC,yEAAyE,wBAEnF,EACF,eAAM,SAAS,EAAC,6DAA6D,YAC1E,aAAa,CACZ,IAAI,KAAK,QAAQ;4CACf,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;4CACxC,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAC5C,GACI,IACH,EACL,WAAW,IAAI,CACd,YAAG,SAAS,EAAC,sCAAsC,YAChD,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,GAC1E,CACL,IACG,EACN,cAAK,SAAS,EAAC,sHAAsH,YACnI,KAAC,MAAM,IACL,SAAS,EAAC,6BAA6B,EACvC,OAAO,EAAC,SAAS,EACjB,OAAO,EAAE,wBAAwB,EACjC,QAAQ,EAAE,CAAC,gBAAgB,YAE1B,aAAa,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC,GAChD,GACL,IACF,EAEN,aAAG,SAAS,EAAC,0DAA0D,aACpE,aAAa,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC,EACrD,GAAG,EACJ,KAAC,IAAI,IAAC,SAAS,EAAC,gFAAgF,EAAC,EAAE,EAAE,IAAI,gBAAgB,SAAS,YAC/H,aAAa,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,GAC/C,IACL,EAEJ,KAAC,wBAAwB,IACvB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAC3C,gBAAgB,EAAE,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,gBAAgB,EAC9C,eAAe,EAAE,WAAW,GAC5B,IACM,CACX,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC","sourcesContent":["import React, { useState } from 'react';\nimport { Button, Icon } from '@openedx/paragon';\nimport { SpinnerIcon } from '@openedx/paragon/icons';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Link } from 'react-router-dom';\n\nimport type { CurrentUserSubscriberResult } from '../../types';\nimport { formatDisplayDate } from '../../utils/formatDate';\nimport { resolvePlanLabel } from '../../utils/subscriptionView';\nimport { MANAGE_PAGE_PATH } from '../../constants';\nimport UpdatePaymentMethodModal from '../UpdatePaymentMethodModal/UpdatePaymentMethodModal';\nimport messages from '../messages';\nimport { trackManageSubscriptionUpdatePaymentButtonClick } from '@src/tracking';\n\ninterface ActiveSubscriptionProps {\n subscriber: CurrentUserSubscriberResult | null,\n}\n\nconst ActiveSubscription: React.FC<ActiveSubscriptionProps> = ({ subscriber }) => {\n const { formatMessage } = useIntl();\n const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);\n const plan = resolvePlanLabel(subscriber);\n const sinceDate = formatDisplayDate(subscriber?.subscriptionStartDate);\n const nextPayment = formatDisplayDate(subscriber?.currentPeriodEnd);\n const canUpdatePayment = Boolean(subscriber?.subscriptionBiId);\n\n const handleUpdatePaymentClick = () => {\n trackManageSubscriptionUpdatePaymentButtonClick({ buttonName: 'updatePayment' });\n setIsPaymentModalOpen(true);\n };\n\n return (\n <section className=\"manage-section mt-4\">\n <h2 className=\"manage-section__title h3 font-weight-bold text-primary-500 mb-1\">\n {formatMessage(messages['manage.active.heading'])}\n </h2>\n {sinceDate && (\n <p className=\"manage-section__subtitle text-gray-700 mb-3\">\n {formatMessage(messages['manage.active.since'], { date: sinceDate })}\n </p>\n )}\n\n <div className=\"manage-card d-flex flex-column flex-md-row align-items-md-center justify-content-md-between bg-white border p-4 rounded\">\n <div className=\"manage-card__content\">\n <div className=\"manage-card__status-row d-flex align-items-center mb-1\">\n <Icon\n src={SpinnerIcon}\n className=\"manage-card__status-badge manage-card__status-badge--sync flex-shrink-0\"\n aria-hidden\n />\n <span className=\"manage-card__status-label font-weight-bold text-primary-500\">\n {formatMessage(\n plan === 'annual'\n ? messages['manage.active.statusAnnual']\n : messages['manage.active.statusMonthly'],\n )}\n </span>\n </div>\n {nextPayment && (\n <p className=\"manage-card__body text-gray-700 mb-0\">\n {formatMessage(messages['manage.active.nextPayment'], { date: nextPayment })}\n </p>\n )}\n </div>\n <div className=\"manage-card__actions manage-card__actions--row d-flex flex-wrap align-items-center flex-shrink-0 justify-content-end\">\n <Button\n className=\"manage-btn manage-btn--dark\"\n variant=\"primary\"\n onClick={handleUpdatePaymentClick}\n disabled={!canUpdatePayment}\n >\n {formatMessage(messages['manage.active.updatePayment'])}\n </Button>\n </div>\n </div>\n\n <p className=\"manage-cancel-prompt mt-3 text-right text-gray-700 small\">\n {formatMessage(messages['manage.active.cancelPrompt'])}\n {' '}\n <Link className=\"manage-cancel-prompt__link text-info-500 font-weight-bold text-decoration-none\" to={`/${MANAGE_PAGE_PATH}/cancel`}>\n {formatMessage(messages['manage.active.cancelLink'])}\n </Link>\n </p>\n\n <UpdatePaymentMethodModal\n isOpen={isPaymentModalOpen}\n onClose={() => setIsPaymentModalOpen(false)}\n subscriptionBiId={subscriber?.subscriptionBiId}\n nextBillingDate={nextPayment}\n />\n </section>\n );\n};\n\nexport default ActiveSubscription;\n"]}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
2
3
|
import { useIntl } from '@openedx/frontend-base';
|
|
3
4
|
import { ExternalLinkIcon } from '../../icons';
|
|
4
5
|
import { getLearnerHelpCenterUrl } from '../../utils/urls';
|
|
5
6
|
import messages from '../messages';
|
|
7
|
+
import { trackManageSubscriptionVisitHelpCenterButtonClick } from '../../tracking';
|
|
6
8
|
const HelpFooter = () => {
|
|
7
9
|
const { formatMessage } = useIntl();
|
|
8
10
|
const helpUrl = getLearnerHelpCenterUrl();
|
|
9
|
-
return (_jsx("div", { className: "manage-help mt-5 pt-4 border-top", children: _jsxs("p", { className: "manage-help__text text-gray-700 small mb-0", children: [formatMessage(messages['manage.help.prefix']), ' ', _jsxs(
|
|
11
|
+
return (_jsx("div", { className: "manage-help mt-5 pt-4 border-top", children: _jsxs("p", { className: "manage-help__text text-gray-700 small mb-0", children: [formatMessage(messages['manage.help.prefix']), ' ', _jsxs(Link, { to: helpUrl, className: "manage-help__link font-weight-bold text-primary-500 d-inline-flex align-items-center", target: "_blank", rel: "noopener noreferrer", onClick: () => trackManageSubscriptionVisitHelpCenterButtonClick({ linkPath: helpUrl }), children: [formatMessage(messages['manage.help.link']), _jsx(ExternalLinkIcon, { className: "manage-help__icon ml-2", size: 14 })] })] }) }));
|
|
10
12
|
};
|
|
11
13
|
export default HelpFooter;
|
|
12
14
|
//# sourceMappingURL=HelpFooter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HelpFooter.js","sourceRoot":"","sources":["../../../src/components/HelpFooter/HelpFooter.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,QAAQ,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"HelpFooter.js","sourceRoot":"","sources":["../../../src/components/HelpFooter/HelpFooter.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,QAAQ,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,iDAAiD,EAAE,MAAM,eAAe,CAAC;AAElF,MAAM,UAAU,GAAa,GAAG,EAAE;IAChC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,uBAAuB,EAAE,CAAC;IAE1C,OAAO,CACL,cAAK,SAAS,EAAC,kCAAkC,YAC/C,aAAG,SAAS,EAAC,4CAA4C,aACtD,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,EAC7C,GAAG,EACJ,MAAC,IAAI,IAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAC,sFAAsF,EAAC,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,iDAAiD,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,aAClP,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,EAC5C,KAAC,gBAAgB,IAAC,SAAS,EAAC,wBAAwB,EAAC,IAAI,EAAE,EAAE,GAAI,IAC5D,IACL,GACA,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import React from 'react';\nimport { Link } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\n\nimport { ExternalLinkIcon } from '../../icons';\nimport { getLearnerHelpCenterUrl } from '../../utils/urls';\nimport messages from '../messages';\nimport { trackManageSubscriptionVisitHelpCenterButtonClick } from '@src/tracking';\n\nconst HelpFooter: React.FC = () => {\n const { formatMessage } = useIntl();\n const helpUrl = getLearnerHelpCenterUrl();\n\n return (\n <div className=\"manage-help mt-5 pt-4 border-top\">\n <p className=\"manage-help__text text-gray-700 small mb-0\">\n {formatMessage(messages['manage.help.prefix'])}\n {' '}\n <Link to={helpUrl} className=\"manage-help__link font-weight-bold text-primary-500 d-inline-flex align-items-center\" target=\"_blank\" rel=\"noopener noreferrer\" onClick={() => trackManageSubscriptionVisitHelpCenterButtonClick({ linkPath: helpUrl })}>\n {formatMessage(messages['manage.help.link'])}\n <ExternalLinkIcon className=\"manage-help__icon ml-2\" size={14} />\n </Link>\n </p>\n </div>\n );\n};\n\nexport default HelpFooter;\n"]}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useIntl } from '@openedx/frontend-base';
|
|
3
|
+
import { trackManageSubscriptionTabClick } from '../../tracking';
|
|
3
4
|
import messages from '../messages';
|
|
4
5
|
const SubscriptionTabs = ({ activeTab, onChange }) => {
|
|
5
6
|
const { formatMessage } = useIntl();
|
|
6
|
-
|
|
7
|
+
const handleClick = (tab) => {
|
|
8
|
+
// Track tab click event here
|
|
9
|
+
trackManageSubscriptionTabClick({ tab });
|
|
10
|
+
onChange(tab);
|
|
11
|
+
};
|
|
12
|
+
return (_jsxs("div", { className: "manage-tabs d-flex border-bottom mt-4", role: "tablist", "aria-label": formatMessage(messages['manage.header.title']), children: [_jsx("button", { type: "button", role: "tab", id: "manage-tab-subscription", "aria-selected": activeTab === 'subscription', "aria-controls": "manage-tabpanel-subscription", className: `manage-tabs__tab${activeTab === 'subscription' ? ' manage-tabs__tab--active' : ''}`, onClick: () => handleClick('subscription'), children: formatMessage(messages['manage.tab.subscription']) }), _jsx("button", { type: "button", role: "tab", id: "manage-tab-payment-history", "aria-selected": activeTab === 'payment-history', "aria-controls": "manage-tabpanel-payment-history", className: `manage-tabs__tab${activeTab === 'payment-history' ? ' manage-tabs__tab--active' : ''}`, onClick: () => handleClick('payment-history'), children: formatMessage(messages['manage.tab.paymentHistory']) })] }));
|
|
7
13
|
};
|
|
8
14
|
export default SubscriptionTabs;
|
|
9
15
|
//# sourceMappingURL=SubscriptionTabs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionTabs.js","sourceRoot":"","sources":["../../../src/components/SubscriptionTabs/SubscriptionTabs.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"SubscriptionTabs.js","sourceRoot":"","sources":["../../../src/components/SubscriptionTabs/SubscriptionTabs.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAGhE,OAAO,QAAQ,MAAM,aAAa,CAAC;AAOnC,MAAM,gBAAgB,GAAoC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;IACpF,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,MAAM,WAAW,GAAG,CAAC,GAAc,EAAE,EAAE;QACrC,6BAA6B;QAC7B,+BAA+B,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACzC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO,CACL,eACE,SAAS,EAAC,uCAAuC,EACjD,IAAI,EAAC,SAAS,gBACF,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,aAE1D,iBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,EACV,EAAE,EAAC,yBAAyB,mBACb,SAAS,KAAK,cAAc,mBAC7B,8BAA8B,EAC5C,SAAS,EAAE,mBAAmB,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,EAAE,EAC/F,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,cAAc,CAAC,YAEzC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,GAC5C,EACT,iBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,EACV,EAAE,EAAC,4BAA4B,mBAChB,SAAS,KAAK,iBAAiB,mBAChC,iCAAiC,EAC/C,SAAS,EAAE,mBAAmB,SAAS,KAAK,iBAAiB,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,EAAE,EAClG,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,iBAAiB,CAAC,YAE5C,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,GAC9C,IACL,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import React from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { trackManageSubscriptionTabClick } from '@src/tracking';\n\nimport type { ManageTab } from '../../types';\nimport messages from '../messages';\n\ninterface SubscriptionTabsProps {\n activeTab: ManageTab,\n onChange: (tab: ManageTab) => void,\n}\n\nconst SubscriptionTabs: React.FC<SubscriptionTabsProps> = ({ activeTab, onChange }) => {\n const { formatMessage } = useIntl();\n\n const handleClick = (tab: ManageTab) => {\n // Track tab click event here\n trackManageSubscriptionTabClick({ tab });\n onChange(tab);\n };\n\n return (\n <div\n className=\"manage-tabs d-flex border-bottom mt-4\"\n role=\"tablist\"\n aria-label={formatMessage(messages['manage.header.title'])}\n >\n <button\n type=\"button\"\n role=\"tab\"\n id=\"manage-tab-subscription\"\n aria-selected={activeTab === 'subscription'}\n aria-controls=\"manage-tabpanel-subscription\"\n className={`manage-tabs__tab${activeTab === 'subscription' ? ' manage-tabs__tab--active' : ''}`}\n onClick={() => handleClick('subscription')}\n >\n {formatMessage(messages['manage.tab.subscription'])}\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n id=\"manage-tab-payment-history\"\n aria-selected={activeTab === 'payment-history'}\n aria-controls=\"manage-tabpanel-payment-history\"\n className={`manage-tabs__tab${activeTab === 'payment-history' ? ' manage-tabs__tab--active' : ''}`}\n onClick={() => handleClick('payment-history')}\n >\n {formatMessage(messages['manage.tab.paymentHistory'])}\n </button>\n </div>\n );\n};\n\nexport default SubscriptionTabs;\n"]}
|
package/dist/constants.d.ts
CHANGED
|
@@ -15,3 +15,4 @@ export declare const COUNTRIES_REQUIRING_EXTRA_CONFIRM: readonly string[];
|
|
|
15
15
|
export declare const ACTIVE_SUBSCRIPTION_STATUSES: Set<string>;
|
|
16
16
|
/** Canceled statuses that may still have access until period end. */
|
|
17
17
|
export declare const CANCELED_SUBSCRIPTION_STATUSES: Set<string>;
|
|
18
|
+
export declare const appName = "learner-home";
|
package/dist/constants.js
CHANGED
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,8CAA8C,CAAC;AACpE,MAAM,CAAC,MAAM,sBAAsB,GAAG,+CAA+C,CAAC;AAEtF,wDAAwD;AACxD,MAAM,CAAC,MAAM,wBAAwB,GAAG,iDAAiD,CAAC;AAE1F,sDAAsD;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,+CAA+C,CAAC;AAEtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAEtD,iEAAiE;AACjE,MAAM,CAAC,MAAM,+BAA+B,GAAG,kCAAkC,CAAC;AAElF,iEAAiE;AACjE,MAAM,CAAC,MAAM,mCAAmC,GAAG,sCAAsC,CAAC;AAE1F,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iCAAiC,GAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAEjF,oEAAoE;AACpE,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,GAAG,CAAC;IAClD,QAAQ;IACR,cAAc;IACd,UAAU;CACX,CAAC,CAAC;AAEH,qEAAqE;AACrE,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAC;IACpD,UAAU;IACV,WAAW;IACX,sBAAsB;IACtB,gBAAgB;CACjB,CAAC,CAAC","sourcesContent":["export const appId = 'org.openedx.frontend.app.subscription.manage';\nexport const subscriptionManageRole = 'org.openedx.frontend.role.subscription.manage';\n\n/** Sibling checkout MFE route role (externalRoutes). */\nexport const subscriptionCheckoutRole = 'org.openedx.frontend.role.subscription.checkout';\n\n/** Sibling search MFE route role (externalRoutes). */\nexport const subscriptionSearchRole = 'org.openedx.frontend.role.subscription.search';\n\nexport const MANAGE_PAGE_PATH = 'manage-subscription';\n\n/** Default help center URL when not overridden in app config. */\nexport const DEFAULT_LEARNER_HELP_CENTER_URL = 'https://support.edx.org/hc/en-us';\n\n/** Default marketing page for \"Learn about edX Subscription\". */\nexport const DEFAULT_SUBSCRIPTION_LEARN_MORE_URL = 'https://www.edx.org/edx-subscription';\n\n/** Countries that require the extra renew consent checkbox (ISO alpha-2). */\nexport const COUNTRIES_REQUIRING_EXTRA_CONFIRM: readonly string[] = ['GB', 'CA'];\n\n/** Active / trial statuses that map to the manage (active) view. */\nexport const ACTIVE_SUBSCRIPTION_STATUSES = new Set([\n 'ACTIVE',\n 'TRIAL_ACTIVE',\n 'TRIALING',\n]);\n\n/** Canceled statuses that may still have access until period end. */\nexport const CANCELED_SUBSCRIPTION_STATUSES = new Set([\n 'CANCELED',\n 'CANCELLED',\n 'CANCEL_AT_PERIOD_END',\n 'PENDING_CANCEL',\n]);\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,8CAA8C,CAAC;AACpE,MAAM,CAAC,MAAM,sBAAsB,GAAG,+CAA+C,CAAC;AAEtF,wDAAwD;AACxD,MAAM,CAAC,MAAM,wBAAwB,GAAG,iDAAiD,CAAC;AAE1F,sDAAsD;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,+CAA+C,CAAC;AAEtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAEtD,iEAAiE;AACjE,MAAM,CAAC,MAAM,+BAA+B,GAAG,kCAAkC,CAAC;AAElF,iEAAiE;AACjE,MAAM,CAAC,MAAM,mCAAmC,GAAG,sCAAsC,CAAC;AAE1F,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iCAAiC,GAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAEjF,oEAAoE;AACpE,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,GAAG,CAAC;IAClD,QAAQ;IACR,cAAc;IACd,UAAU;CACX,CAAC,CAAC;AAEH,qEAAqE;AACrE,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAC;IACpD,UAAU;IACV,WAAW;IACX,sBAAsB;IACtB,gBAAgB;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAC","sourcesContent":["export const appId = 'org.openedx.frontend.app.subscription.manage';\nexport const subscriptionManageRole = 'org.openedx.frontend.role.subscription.manage';\n\n/** Sibling checkout MFE route role (externalRoutes). */\nexport const subscriptionCheckoutRole = 'org.openedx.frontend.role.subscription.checkout';\n\n/** Sibling search MFE route role (externalRoutes). */\nexport const subscriptionSearchRole = 'org.openedx.frontend.role.subscription.search';\n\nexport const MANAGE_PAGE_PATH = 'manage-subscription';\n\n/** Default help center URL when not overridden in app config. */\nexport const DEFAULT_LEARNER_HELP_CENTER_URL = 'https://support.edx.org/hc/en-us';\n\n/** Default marketing page for \"Learn about edX Subscription\". */\nexport const DEFAULT_SUBSCRIPTION_LEARN_MORE_URL = 'https://www.edx.org/edx-subscription';\n\n/** Countries that require the extra renew consent checkbox (ISO alpha-2). */\nexport const COUNTRIES_REQUIRING_EXTRA_CONFIRM: readonly string[] = ['GB', 'CA'];\n\n/** Active / trial statuses that map to the manage (active) view. */\nexport const ACTIVE_SUBSCRIPTION_STATUSES = new Set([\n 'ACTIVE',\n 'TRIAL_ACTIVE',\n 'TRIALING',\n]);\n\n/** Canceled statuses that may still have access until period end. */\nexport const CANCELED_SUBSCRIPTION_STATUSES = new Set([\n 'CANCELED',\n 'CANCELLED',\n 'CANCEL_AT_PERIOD_END',\n 'PENDING_CANCEL',\n]);\n\nexport const appName = 'learner-home';\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { sendTrackEvent } from '@openedx/frontend-base';
|
|
2
|
+
import { appName } from '../../../constants';
|
|
3
|
+
import { getCommonTrackingProps } from '../../../tracking/trackingContext';
|
|
4
|
+
export const LINK_TIMEOUT = 300;
|
|
5
|
+
export const createEventTracker = (name, options = {}) => () => sendTrackEvent(name, Object.assign(Object.assign(Object.assign({}, options), { app_name: appName }), getCommonTrackingProps()));
|
|
6
|
+
export const createLinkTracker = (tracker, href) => (e) => {
|
|
7
|
+
e.preventDefault();
|
|
8
|
+
tracker();
|
|
9
|
+
return setTimeout(() => {
|
|
10
|
+
global.location.href = href;
|
|
11
|
+
}, LINK_TIMEOUT);
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/data/services/segment/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAE3E,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAEhC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,UAAmC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,cAAc,CAC7G,IAAI,gDACC,OAAO,KAAE,QAAQ,EAAE,OAAO,KAAK,sBAAsB,EAAE,EAC7D,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;IACxD,CAAC,CAAC,cAAc,EAAE,CAAC;IACnB,OAAO,EAAE,CAAC;IACV,OAAO,UAAU,CAAC,GAAG,EAAE;QACrB,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;IAC9B,CAAC,EAAE,YAAY,CAAC,CAAC;AACnB,CAAC,CAAC","sourcesContent":["import { sendTrackEvent } from '@openedx/frontend-base';\nimport { appName } from '../../../constants';\nimport { getCommonTrackingProps } from '../../../tracking/trackingContext';\n\nexport const LINK_TIMEOUT = 300;\n\nexport const createEventTracker = (name: string, options: Record<string, unknown> = {}) => () => sendTrackEvent(\n name,\n { ...options, app_name: appName, ...getCommonTrackingProps() },\n);\n\nexport const createLinkTracker = (tracker, href) => (e) => {\n e.preventDefault();\n tracker();\n return setTimeout(() => {\n global.location.href = href;\n }, LINK_TIMEOUT);\n};\n"]}
|
|
@@ -11,7 +11,7 @@ import { GET_IS_CURRENT_USER_SUBSCRIBER } from '../../../utils/queries';
|
|
|
11
11
|
/** Check whether the authenticated user has an active / recent subscription. */
|
|
12
12
|
export function getIsCurrentUserSubscriber(gql) {
|
|
13
13
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
14
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
15
15
|
const data = yield gql(GET_IS_CURRENT_USER_SUBSCRIBER);
|
|
16
16
|
const result = data === null || data === void 0 ? void 0 : data.tIsCurrentUserSubscriber;
|
|
17
17
|
if (!result || typeof result !== 'object') {
|
|
@@ -31,6 +31,10 @@ export function getIsCurrentUserSubscriber(gql) {
|
|
|
31
31
|
canceledAt: (_k = (_j = result.canceledAt) !== null && _j !== void 0 ? _j : result.cancelledAt) !== null && _k !== void 0 ? _k : null,
|
|
32
32
|
amount: (_m = (_l = result.amount) !== null && _l !== void 0 ? _l : result.price) !== null && _m !== void 0 ? _m : null,
|
|
33
33
|
currency: (_o = result.currency) !== null && _o !== void 0 ? _o : null,
|
|
34
|
+
billingPlanUid: (_p = result.billingPlanUid) !== null && _p !== void 0 ? _p : null,
|
|
35
|
+
interval: (_q = result.interval) !== null && _q !== void 0 ? _q : null,
|
|
36
|
+
billingInterval: (_r = result.billingInterval) !== null && _r !== void 0 ? _r : null,
|
|
37
|
+
bipOwnershipModel: (_s = result.bipOwnershipModel) !== null && _s !== void 0 ? _s : null,
|
|
34
38
|
};
|
|
35
39
|
});
|
|
36
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIsCurrentUserSubscriber.js","sourceRoot":"","sources":["../../../../src/data/services/subscription/getIsCurrentUserSubscriber.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAExE,gFAAgF;AAChF,MAAM,UAAgB,0BAA0B,CAC9C,GAAc;;;QAEd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,8BAA8B,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,wBAAwB,CAAC;QAC9C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO;YACL,YAAY,EAAE,MAAM,CAAC,YAAY,KAAK,IAAI;YAC1C,SAAS,EAAE,MAAM,CAAC,SAAS,KAAK,IAAI;YACpC,gBAAgB,EAAE,MAAA,MAAM,CAAC,gBAAgB,mCAAI,IAAI;YACjD,MAAM,EAAE,MAAA,MAAM,CAAC,MAAM,mCAAI,IAAI;YAC7B,gBAAgB,EAAE,MAAA,MAAM,CAAC,gBAAgB,mCAAI,IAAI;YACjD,qBAAqB,EAAE,MAAA,MAAM,CAAC,qBAAqB,mCAAI,IAAI;YAC3D,mBAAmB,EAAE,MAAA,MAAM,CAAC,mBAAmB,mCAAI,IAAI;YACvD,yEAAyE;YACzE,uDAAuD;YACvD,WAAW,EACT,MAAA,MAAA,MAAA,MAAM,CAAC,gBAAgB,mCAAI,MAAM,CAAC,WAAW,mCAAI,MAAM,CAAC,QAAQ,mCAAI,IAAI;YAC1E,UAAU,EAAE,MAAA,MAAA,MAAM,CAAC,UAAU,mCAAI,MAAM,CAAC,WAAW,mCAAI,IAAI;YAC3D,MAAM,EAAE,MAAA,MAAA,MAAM,CAAC,MAAM,mCAAI,MAAM,CAAC,KAAK,mCAAI,IAAI;YAC7C,QAAQ,EAAE,MAAA,MAAM,CAAC,QAAQ,mCAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"getIsCurrentUserSubscriber.js","sourceRoot":"","sources":["../../../../src/data/services/subscription/getIsCurrentUserSubscriber.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAExE,gFAAgF;AAChF,MAAM,UAAgB,0BAA0B,CAC9C,GAAc;;;QAEd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,8BAA8B,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,wBAAwB,CAAC;QAC9C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO;YACL,YAAY,EAAE,MAAM,CAAC,YAAY,KAAK,IAAI;YAC1C,SAAS,EAAE,MAAM,CAAC,SAAS,KAAK,IAAI;YACpC,gBAAgB,EAAE,MAAA,MAAM,CAAC,gBAAgB,mCAAI,IAAI;YACjD,MAAM,EAAE,MAAA,MAAM,CAAC,MAAM,mCAAI,IAAI;YAC7B,gBAAgB,EAAE,MAAA,MAAM,CAAC,gBAAgB,mCAAI,IAAI;YACjD,qBAAqB,EAAE,MAAA,MAAM,CAAC,qBAAqB,mCAAI,IAAI;YAC3D,mBAAmB,EAAE,MAAA,MAAM,CAAC,mBAAmB,mCAAI,IAAI;YACvD,yEAAyE;YACzE,uDAAuD;YACvD,WAAW,EACT,MAAA,MAAA,MAAA,MAAM,CAAC,gBAAgB,mCAAI,MAAM,CAAC,WAAW,mCAAI,MAAM,CAAC,QAAQ,mCAAI,IAAI;YAC1E,UAAU,EAAE,MAAA,MAAA,MAAM,CAAC,UAAU,mCAAI,MAAM,CAAC,WAAW,mCAAI,IAAI;YAC3D,MAAM,EAAE,MAAA,MAAA,MAAM,CAAC,MAAM,mCAAI,MAAM,CAAC,KAAK,mCAAI,IAAI;YAC7C,QAAQ,EAAE,MAAA,MAAM,CAAC,QAAQ,mCAAI,IAAI;YACjC,cAAc,EAAE,MAAA,MAAM,CAAC,cAAc,mCAAI,IAAI;YAC7C,QAAQ,EAAE,MAAA,MAAM,CAAC,QAAQ,mCAAI,IAAI;YACjC,eAAe,EAAE,MAAA,MAAM,CAAC,eAAe,mCAAI,IAAI;YAC/C,iBAAiB,EAAE,MAAA,MAAM,CAAC,iBAAiB,mCAAI,IAAI;SACpD,CAAC;IACJ,CAAC;CAAA","sourcesContent":["import type { GqlRunner, CurrentUserSubscriberResult } from '../../../types';\nimport { GET_IS_CURRENT_USER_SUBSCRIBER } from '../../../utils/queries';\n\n/** Check whether the authenticated user has an active / recent subscription. */\nexport async function getIsCurrentUserSubscriber(\n gql: GqlRunner,\n): Promise<CurrentUserSubscriberResult | null> {\n const data = await gql(GET_IS_CURRENT_USER_SUBSCRIBER);\n const result = data?.tIsCurrentUserSubscriber;\n if (!result || typeof result !== 'object') {\n return null;\n }\n\n return {\n isSubscriber: result.isSubscriber === true,\n canEnroll: result.canEnroll === true,\n subscriptionBiId: result.subscriptionBiId ?? null,\n status: result.status ?? null,\n currentPeriodEnd: result.currentPeriodEnd ?? null,\n subscriptionStartDate: result.subscriptionStartDate ?? null,\n subscriptionEndDate: result.subscriptionEndDate ?? null,\n // Prefer billingFrequency (e.g. ANNUAL / MONTHLY); planName is a display\n // label and usually does not encode the billing cycle.\n renewalType:\n result.billingFrequency ?? result.renewalType ?? result.planName ?? null,\n canceledAt: result.canceledAt ?? result.cancelledAt ?? null,\n amount: result.amount ?? result.price ?? null,\n currency: result.currency ?? null,\n billingPlanUid: result.billingPlanUid ?? null,\n interval: result.interval ?? null,\n billingInterval: result.billingInterval ?? null,\n bipOwnershipModel: result.bipOwnershipModel ?? null,\n };\n}\n"]}
|
package/dist/routes.js
CHANGED
|
@@ -11,6 +11,7 @@ import { authenticatedLoader, getAuthenticatedHttpClient, } from '@openedx/front
|
|
|
11
11
|
import { redirect } from 'react-router-dom';
|
|
12
12
|
import { getSubsInitApiUrl } from './data/services/subs/urls';
|
|
13
13
|
import { subscriptionManageRole } from './constants';
|
|
14
|
+
import { setCommonTrackingProps, mapSubsInitToTrackingProps } from './tracking/trackingContext';
|
|
14
15
|
// loader to check if the user has subscription access
|
|
15
16
|
const subscriptionAccessLoader = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
17
|
try {
|
|
@@ -18,6 +19,7 @@ const subscriptionAccessLoader = () => __awaiter(void 0, void 0, void 0, functio
|
|
|
18
19
|
if (!(data === null || data === void 0 ? void 0 : data.userSubscription) || !data.userSubscription.isSubscriber) {
|
|
19
20
|
throw redirect('/learner-dashboard'); // redirect to learner dashboard if user does not have subscription access
|
|
20
21
|
}
|
|
22
|
+
setCommonTrackingProps(mapSubsInitToTrackingProps(data));
|
|
21
23
|
return null;
|
|
22
24
|
}
|
|
23
25
|
catch (error) {
|
package/dist/routes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAEhG,sDAAsD;AACtD,MAAM,wBAAwB,GAAG,GAAS,EAAE;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GACV,MAAM,0BAA0B,EAAE,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAEhE,IAAI,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,gBAAgB,CAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,CAAC;YACnE,MAAM,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,0EAA0E;QAClH,CAAC;QAED,sBAAsB,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mCAAmC;QACnC,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,mDAAmD;IAC3F,CAAC;AACH,CAAC,CAAA,CAAC;AAEF,yEAAyE;AACzE,MAAM,eAAe,GAAG,CAAO,IAAI,EAAE,EAAE;IACrC,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,wBAAwB,EAAE,CAAC;IAEjC,OAAO,IAAI,CAAC;AACd,CAAC,CAAA,CAAC;AAEF,MAAM,MAAM,GAAG;IACb;QACE,EAAE,EAAE,qDAAqD;QACzD,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,eAAe;QACvB,MAAM,EAAE;YACN,KAAK,EAAE,CAAC,sBAAsB,CAAC;SAChC;QACK,IAAI;;gBACR,MAAM,MAAM,GAAG,MAAM,MAAM;gBACzB,kDAAkD,CAAC,QAAQ,CAC5D,CAAC;gBACF,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACvC,CAAC;SAAA;QACD,QAAQ,EAAE;YACR;gBACE,KAAK,EAAE,IAAI;gBACL,IAAI;;wBACR,MAAM,MAAM,GAAG,MAAM,MAAM;wBACzB,gDAAgD,CAAC,iDAAiD,CACnG,CAAC;wBACF,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;oBACvC,CAAC;iBAAA;aACF;YACD;gBACE,IAAI,EAAE,QAAQ;gBACR,IAAI;;wBACR,MAAM,MAAM,GAAG,MAAM,MAAM;wBACzB,gDAAgD,CAAC,iDAAiD,CACnG,CAAC;wBACF,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;oBACvC,CAAC;iBAAA;aACF;YACD;gBACE,IAAI,EAAE,gBAAgB;gBAChB,IAAI;;wBACR,MAAM,MAAM,GAAG,MAAM,MAAM;wBACzB,2CAA2C,CAAC,4CAA4C,CACzF,CAAC;wBACF,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;oBACvC,CAAC;iBAAA;aACF;SACF;KACF;CACF,CAAC;AAEF,eAAe,MAAM,CAAC","sourcesContent":["import {\n authenticatedLoader,\n getAuthenticatedHttpClient,\n} from '@openedx/frontend-base';\nimport { redirect } from 'react-router-dom';\n\nimport { getSubsInitApiUrl } from './data/services/subs/urls';\nimport { subscriptionManageRole } from './constants';\nimport { setCommonTrackingProps, mapSubsInitToTrackingProps } from './tracking/trackingContext';\n\n// loader to check if the user has subscription access\nconst subscriptionAccessLoader = async () => {\n try {\n const { data }\n = await getAuthenticatedHttpClient().get(getSubsInitApiUrl());\n\n if (!data?.userSubscription || !data.userSubscription.isSubscriber) {\n throw redirect('/learner-dashboard'); // redirect to learner dashboard if user does not have subscription access\n }\n\n setCommonTrackingProps(mapSubsInitToTrackingProps(data));\n return null;\n } catch (error) {\n // Let redirect responses bubble up\n if (error instanceof Response) {\n throw error;\n }\n\n throw redirect('/learner-dashboard'); // redirect to learner dashboard if an error occurs\n }\n};\n\n// composed loader that checks for authentication and subscription access\nconst protectedLoader = async (args) => {\n await authenticatedLoader(args);\n await subscriptionAccessLoader();\n\n return null;\n};\n\nconst routes = [\n {\n id: 'org.openedx.frontend.route.subscription.manage.main',\n path: 'manage-subscription',\n loader: protectedLoader,\n handle: {\n roles: [subscriptionManageRole],\n },\n async lazy() {\n const module = await import(\n /* webpackChunkName: \"subscription-manage-main\" */ './Main'\n );\n return { Component: module.default };\n },\n children: [\n {\n index: true,\n async lazy() {\n const module = await import(\n /* webpackChunkName: \"ManageSubscriptionPage\" */ './manageSubscriptionPage/ManageSubscriptionPage'\n );\n return { Component: module.default };\n },\n },\n {\n path: 'cancel',\n async lazy() {\n const module = await import(\n /* webpackChunkName: \"CancelSubscriptionPage\" */ './manageSubscriptionPage/CancelSubscriptionPage'\n );\n return { Component: module.default };\n },\n },\n {\n path: 'cancel/success',\n async lazy() {\n const module = await import(\n /* webpackChunkName: \"CancelSuccessPage\" */ './manageSubscriptionPage/CancelSuccessPage'\n );\n return { Component: module.default };\n },\n },\n ],\n },\n];\n\nexport default routes;\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const eventNames: {
|
|
2
|
+
manageSubscriptionTabClicked: string;
|
|
3
|
+
manageSubscriptionUpdatePaymentButtonClicked: string;
|
|
4
|
+
manageSubscriptionVisitHelpCenterButtonClicked: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const trackManageSubscriptionTabClick: (eventProperties: any) => void;
|
|
7
|
+
export declare const trackManageSubscriptionUpdatePaymentButtonClick: (eventProperties: any) => void;
|
|
8
|
+
export declare const trackManageSubscriptionVisitHelpCenterButtonClick: (eventProperties: any) => void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createEventTracker } from '../data/services/segment';
|
|
2
|
+
export const eventNames = {
|
|
3
|
+
manageSubscriptionTabClicked: 'edx.manage.subscription.tab.clicked',
|
|
4
|
+
manageSubscriptionUpdatePaymentButtonClicked: 'edx.manage.subscription.update.payment.button.clicked',
|
|
5
|
+
manageSubscriptionVisitHelpCenterButtonClicked: 'edx.manage.subscription.visit.help.center.button.clicked',
|
|
6
|
+
};
|
|
7
|
+
// Event tracker for manage subscription payment history tab click
|
|
8
|
+
export const trackManageSubscriptionTabClick = (eventProperties) => createEventTracker(eventNames.manageSubscriptionTabClicked, Object.assign({}, eventProperties))();
|
|
9
|
+
// Event tracker for manage subscription update payment button click
|
|
10
|
+
export const trackManageSubscriptionUpdatePaymentButtonClick = (eventProperties) => createEventTracker(eventNames.manageSubscriptionUpdatePaymentButtonClicked, Object.assign({}, eventProperties))();
|
|
11
|
+
// Event tracker for manage subscription visit help center button click
|
|
12
|
+
export const trackManageSubscriptionVisitHelpCenterButtonClick = (eventProperties) => createEventTracker(eventNames.manageSubscriptionVisitHelpCenterButtonClicked, Object.assign({}, eventProperties))();
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tracking/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,4BAA4B,EAAE,qCAAqC;IACnE,4CAA4C,EAAE,uDAAuD;IACrG,8CAA8C,EAAE,0DAA0D;CAC3G,CAAC;AAEF,kEAAkE;AAClE,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,kBAAkB,CACpF,UAAU,CAAC,4BAA4B,oBAClC,eAAe,EACrB,EAAE,CAAC;AAEJ,oEAAoE;AACpE,MAAM,CAAC,MAAM,+CAA+C,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,kBAAkB,CACpG,UAAU,CAAC,4CAA4C,oBAClD,eAAe,EACrB,EAAE,CAAC;AAEJ,uEAAuE;AACvE,MAAM,CAAC,MAAM,iDAAiD,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,kBAAkB,CACtG,UAAU,CAAC,8CAA8C,oBACpD,eAAe,EACrB,EAAE,CAAC","sourcesContent":["import { createEventTracker } from '@src/data/services/segment';\n\nexport const eventNames = {\n manageSubscriptionTabClicked: 'edx.manage.subscription.tab.clicked',\n manageSubscriptionUpdatePaymentButtonClicked: 'edx.manage.subscription.update.payment.button.clicked',\n manageSubscriptionVisitHelpCenterButtonClicked: 'edx.manage.subscription.visit.help.center.button.clicked',\n};\n\n// Event tracker for manage subscription payment history tab click\nexport const trackManageSubscriptionTabClick = (eventProperties) => createEventTracker(\n eventNames.manageSubscriptionTabClicked,\n { ...eventProperties },\n)();\n\n// Event tracker for manage subscription update payment button click\nexport const trackManageSubscriptionUpdatePaymentButtonClick = (eventProperties) => createEventTracker(\n eventNames.manageSubscriptionUpdatePaymentButtonClicked,\n { ...eventProperties },\n)();\n\n// Event tracker for manage subscription visit help center button click\nexport const trackManageSubscriptionVisitHelpCenterButtonClick = (eventProperties) => createEventTracker(\n eventNames.manageSubscriptionVisitHelpCenterButtonClicked,\n { ...eventProperties },\n)();\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface CommonTrackingProps {
|
|
2
|
+
free_trial_status?: string;
|
|
3
|
+
subscription_status?: string;
|
|
4
|
+
subscription_tier?: string;
|
|
5
|
+
session_id?: string | null;
|
|
6
|
+
experimentation?: string | null;
|
|
7
|
+
device_type?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export declare const setCommonTrackingProps: (props: CommonTrackingProps) => void;
|
|
10
|
+
export declare const getCommonTrackingProps: () => CommonTrackingProps;
|
|
11
|
+
export declare const mapSubsInitToTrackingProps: (data: any) => CommonTrackingProps;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
let commonProps = {};
|
|
2
|
+
export const setCommonTrackingProps = (props) => {
|
|
3
|
+
commonProps = Object.assign(Object.assign({}, commonProps), props);
|
|
4
|
+
};
|
|
5
|
+
export const getCommonTrackingProps = () => commonProps;
|
|
6
|
+
// Single place that maps the subs/init API response -> tracking props
|
|
7
|
+
export const mapSubsInitToTrackingProps = (data) => {
|
|
8
|
+
var _a, _b, _c;
|
|
9
|
+
return ({
|
|
10
|
+
free_trial_status: (_a = data === null || data === void 0 ? void 0 : data.userSubscription) === null || _a === void 0 ? void 0 : _a.trialActive,
|
|
11
|
+
subscription_status: (_b = data === null || data === void 0 ? void 0 : data.userSubscription) === null || _b === void 0 ? void 0 : _b.status,
|
|
12
|
+
subscription_tier: (_c = data === null || data === void 0 ? void 0 : data.userSubscription) === null || _c === void 0 ? void 0 : _c.billingFrequency,
|
|
13
|
+
session_id: '',
|
|
14
|
+
experimentation: '',
|
|
15
|
+
device_type: '',
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=trackingContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trackingContext.js","sourceRoot":"","sources":["../../src/tracking/trackingContext.ts"],"names":[],"mappings":"AASA,IAAI,WAAW,GAAwB,EAAE,CAAC;AAE1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAA0B,EAAE,EAAE;IACnE,WAAW,mCAAQ,WAAW,GAAK,KAAK,CAAE,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAwB,EAAE,CAAC,WAAW,CAAC;AAE7E,sEAAsE;AACtE,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,IAAS,EAAuB,EAAE;;IAAC,OAAA,CAAC;QAC7E,iBAAiB,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,gBAAgB,0CAAE,WAAW;QACtD,mBAAmB,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,gBAAgB,0CAAE,MAAM;QACnD,iBAAiB,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,gBAAgB,0CAAE,gBAAgB;QAC3D,UAAU,EAAE,EAAE;QACd,eAAe,EAAE,EAAE;QACnB,WAAW,EAAE,EAAE;KAChB,CAAC,CAAA;CAAA,CAAC","sourcesContent":["export interface CommonTrackingProps {\n free_trial_status?: string,\n subscription_status?: string,\n subscription_tier?: string,\n session_id?: string | null,\n experimentation?: string | null,\n device_type?: string | null,\n}\n\nlet commonProps: CommonTrackingProps = {};\n\nexport const setCommonTrackingProps = (props: CommonTrackingProps) => {\n commonProps = { ...commonProps, ...props };\n};\n\nexport const getCommonTrackingProps = (): CommonTrackingProps => commonProps;\n\n// Single place that maps the subs/init API response -> tracking props\nexport const mapSubsInitToTrackingProps = (data: any): CommonTrackingProps => ({\n free_trial_status: data?.userSubscription?.trialActive,\n subscription_status: data?.userSubscription?.status,\n subscription_tier: data?.userSubscription?.billingFrequency,\n session_id: '',\n experimentation: '',\n device_type: '',\n});\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -24,6 +24,17 @@ export interface CurrentUserSubscriberResult {
|
|
|
24
24
|
/** Optional price display amount when present. */
|
|
25
25
|
amount?: string | null;
|
|
26
26
|
currency?: string | null;
|
|
27
|
+
/**
|
|
28
|
+
* Billing-plan fallback fields used when `renewalType` is missing
|
|
29
|
+
* (e.g. PayPal payloads). See `resolvePlanLabel`.
|
|
30
|
+
*/
|
|
31
|
+
billingPlanUid?: string | null;
|
|
32
|
+
interval?: string | null;
|
|
33
|
+
billingInterval?: string | null;
|
|
34
|
+
bipOwnershipModel?: {
|
|
35
|
+
uid?: string;
|
|
36
|
+
omName?: string;
|
|
37
|
+
} | null;
|
|
27
38
|
}
|
|
28
39
|
/** Normalized enrollment for the cancel confirmation course list. */
|
|
29
40
|
export interface SubscriptionEnrollment {
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG","sourcesContent":["/**\n * Manage Subscription — domain types for Viax subscriber + enrollment data.\n */\n\n/** GraphQL runner used by VIAX fetchers. */\nexport type GqlRunner = (\n query: string,\n variables?: Record<string, unknown>,\n) => Promise<any>;\n\n/** Result of `tIsCurrentUserSubscriber` (JSON scalar). */\nexport interface CurrentUserSubscriberResult {\n /** Has/expects access — drive manage vs upsell messaging. */\n isSubscriber: boolean,\n /** Enrollable right now (ACTIVE / TRIAL_ACTIVE). */\n canEnroll: boolean,\n subscriptionBiId: string | null,\n status: string | null,\n currentPeriodEnd: string | null,\n subscriptionStartDate: string | null,\n subscriptionEndDate: string | null,\n /**\n * Billing cycle / plan label used by UI (from `billingFrequency`,\n * `renewalType`, or `planName` on the API payload).\n */\n renewalType?: string | null,\n /** Optional cancel timestamp when present. */\n canceledAt?: string | null,\n /** Optional price display amount when present. */\n amount?: string | null,\n currency?: string | null,\n}\n\n/** Normalized enrollment for the cancel confirmation course list. */\nexport interface SubscriptionEnrollment {\n biId: string,\n courseMaId: string | null,\n courseName: string | null,\n courseSlug: string | null,\n /** Course card / thumbnail image. */\n imageUrl: string | null,\n orgName: string | null,\n orgLogoUrl: string | null,\n courseRunKey: string | null,\n /** TwouEnrollment bpStatus.code (ACTIVE, COMPLETED, …). */\n status: string | null,\n /** True when the enrollment has a certificate id and/or URL. */\n hasCertificate: boolean,\n /** Absolute certificate link (`COURSES_BASE_URL` + `tCertificateUrl`). */\n certificateUrl: string | null,\n}\n\n/** Normalized invoice row for the Payment history tab. */\nexport interface PaymentHistoryItem {\n biId: string,\n /** Display order number, e.g. EDX-BI3X25N5SY30OSIK */\n orderNumber: string,\n stripeInvoiceId: string | null,\n status: string | null,\n billDate: string | null,\n periodStart: string | null,\n periodEnd: string | null,\n /** Charged amount in major currency units (e.g. 59.00). */\n amount: number,\n currency: string,\n isTrial: boolean,\n}\n\n/** UI view derived from subscriber status. */\nexport type SubscriptionView =\n | 'none'\n | 'active'\n | 'canceled_access'\n | 'canceled_expired';\n\nexport type ManageTab = 'subscription' | 'payment-history';\n\nexport type BillingCycle = 'monthly' | 'annual';\n\nexport interface BillingPlanOwnershipModel {\n uid: string,\n omName: string,\n}\n\n/** Normalized row from `filterCustomerBillingPlan`. */\nexport interface BillingPlan {\n uid: string,\n stripePriceId: string,\n /** Price amount e.g. \"39.99\" */\n amount: string,\n /** Currency code e.g. \"USD\" */\n currency: string,\n isTemplate: boolean,\n ownershipModel: BillingPlanOwnershipModel,\n}\n\nexport interface BillingPlansResult {\n plans: BillingPlan[],\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG","sourcesContent":["/**\n * Manage Subscription — domain types for Viax subscriber + enrollment data.\n */\n\n/** GraphQL runner used by VIAX fetchers. */\nexport type GqlRunner = (\n query: string,\n variables?: Record<string, unknown>,\n) => Promise<any>;\n\n/** Result of `tIsCurrentUserSubscriber` (JSON scalar). */\nexport interface CurrentUserSubscriberResult {\n /** Has/expects access — drive manage vs upsell messaging. */\n isSubscriber: boolean,\n /** Enrollable right now (ACTIVE / TRIAL_ACTIVE). */\n canEnroll: boolean,\n subscriptionBiId: string | null,\n status: string | null,\n currentPeriodEnd: string | null,\n subscriptionStartDate: string | null,\n subscriptionEndDate: string | null,\n /**\n * Billing cycle / plan label used by UI (from `billingFrequency`,\n * `renewalType`, or `planName` on the API payload).\n */\n renewalType?: string | null,\n /** Optional cancel timestamp when present. */\n canceledAt?: string | null,\n /** Optional price display amount when present. */\n amount?: string | null,\n currency?: string | null,\n /**\n * Billing-plan fallback fields used when `renewalType` is missing\n * (e.g. PayPal payloads). See `resolvePlanLabel`.\n */\n billingPlanUid?: string | null,\n interval?: string | null,\n billingInterval?: string | null,\n bipOwnershipModel?: { uid?: string, omName?: string } | null,\n}\n\n/** Normalized enrollment for the cancel confirmation course list. */\nexport interface SubscriptionEnrollment {\n biId: string,\n courseMaId: string | null,\n courseName: string | null,\n courseSlug: string | null,\n /** Course card / thumbnail image. */\n imageUrl: string | null,\n orgName: string | null,\n orgLogoUrl: string | null,\n courseRunKey: string | null,\n /** TwouEnrollment bpStatus.code (ACTIVE, COMPLETED, …). */\n status: string | null,\n /** True when the enrollment has a certificate id and/or URL. */\n hasCertificate: boolean,\n /** Absolute certificate link (`COURSES_BASE_URL` + `tCertificateUrl`). */\n certificateUrl: string | null,\n}\n\n/** Normalized invoice row for the Payment history tab. */\nexport interface PaymentHistoryItem {\n biId: string,\n /** Display order number, e.g. EDX-BI3X25N5SY30OSIK */\n orderNumber: string,\n stripeInvoiceId: string | null,\n status: string | null,\n billDate: string | null,\n periodStart: string | null,\n periodEnd: string | null,\n /** Charged amount in major currency units (e.g. 59.00). */\n amount: number,\n currency: string,\n isTrial: boolean,\n}\n\n/** UI view derived from subscriber status. */\nexport type SubscriptionView =\n | 'none'\n | 'active'\n | 'canceled_access'\n | 'canceled_expired';\n\nexport type ManageTab = 'subscription' | 'payment-history';\n\nexport type BillingCycle = 'monthly' | 'annual';\n\nexport interface BillingPlanOwnershipModel {\n uid: string,\n omName: string,\n}\n\n/** Normalized row from `filterCustomerBillingPlan`. */\nexport interface BillingPlan {\n uid: string,\n stripePriceId: string,\n /** Price amount e.g. \"39.99\" */\n amount: string,\n /** Currency code e.g. \"USD\" */\n currency: string,\n isTemplate: boolean,\n ownershipModel: BillingPlanOwnershipModel,\n}\n\nexport interface BillingPlansResult {\n plans: BillingPlan[],\n}\n"]}
|
|
@@ -40,11 +40,29 @@ export function resolveSubscriptionView(subscriber) {
|
|
|
40
40
|
}
|
|
41
41
|
/** Human-readable plan label from renewal type / status. */
|
|
42
42
|
export function resolvePlanLabel(subscriber) {
|
|
43
|
-
var _a;
|
|
43
|
+
var _a, _b, _c, _d;
|
|
44
44
|
const raw = ((_a = subscriber === null || subscriber === void 0 ? void 0 : subscriber.renewalType) !== null && _a !== void 0 ? _a : '').toLowerCase();
|
|
45
45
|
if (raw.includes('annual') || raw.includes('year')) {
|
|
46
46
|
return 'annual';
|
|
47
47
|
}
|
|
48
|
+
if (raw) {
|
|
49
|
+
return 'monthly';
|
|
50
|
+
}
|
|
51
|
+
// renewalType/tStripePriceId unavailable (e.g. PayPal) — fall back to billing-plan fields.
|
|
52
|
+
const omName = (_b = subscriber === null || subscriber === void 0 ? void 0 : subscriber.bipOwnershipModel) === null || _b === void 0 ? void 0 : _b.omName;
|
|
53
|
+
if (omName === 'Annual Subscription') {
|
|
54
|
+
return 'annual';
|
|
55
|
+
}
|
|
56
|
+
if (omName === 'Monthly Subscription') {
|
|
57
|
+
return 'monthly';
|
|
58
|
+
}
|
|
59
|
+
const cycle = ((_d = (_c = subscriber === null || subscriber === void 0 ? void 0 : subscriber.interval) !== null && _c !== void 0 ? _c : subscriber === null || subscriber === void 0 ? void 0 : subscriber.billingInterval) !== null && _d !== void 0 ? _d : '').toLowerCase();
|
|
60
|
+
if (cycle.includes('annual') || cycle.includes('year')) {
|
|
61
|
+
return 'annual';
|
|
62
|
+
}
|
|
63
|
+
if (cycle.includes('month')) {
|
|
64
|
+
return 'monthly';
|
|
65
|
+
}
|
|
48
66
|
return 'monthly';
|
|
49
67
|
}
|
|
50
68
|
//# sourceMappingURL=subscriptionView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscriptionView.js","sourceRoot":"","sources":["../../src/utils/subscriptionView.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAA0D;;IAE1D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAA,UAAU,CAAC,MAAM,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACvD,MAAM,gBAAgB,GAAG,CACvB,8BAA8B,CAAC,GAAG,CAAC,MAAM,CAAC;WACvC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC7B,CAAC;IAEF,IACE,CAAC,gBAAgB;WACd,CACD,UAAU,CAAC,SAAS;eACjB,UAAU,CAAC,YAAY;eACvB,4BAA4B,CAAC,GAAG,CAAC,MAAM,CAAC,CAC5C,EACD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,eAAe,GAAG,YAAY,CAAC,UAAU,CAAC,gBAAgB,CAAC;WAC5D,YAAY,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;IAElD,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,UAAU,CAAC,YAAY,IAAI,eAAe,EAAE,CAAC;YAC/C,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QACD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,IAAI,UAAU,CAAC,gBAAgB,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAC9B,UAA0D;;IAE1D,MAAM,GAAG,GAAG,CAAC,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,WAAW,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1D,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["/**\n * Derive which manage-subscription UI to show from subscriber API data.\n */\n\nimport {\n ACTIVE_SUBSCRIPTION_STATUSES,\n CANCELED_SUBSCRIPTION_STATUSES,\n} from '../constants';\nimport type { CurrentUserSubscriberResult, SubscriptionView } from '../types';\nimport { isFutureDate } from './formatDate';\n\n/**\n * Map subscriber payload → UI view.\n *\n * - active: can enroll / ACTIVE / TRIAL / isSubscriber without cancel status\n * - canceled_access: canceled but period end still in the future (or isSubscriber)\n * - canceled_expired: previously subscribed, no current access\n * - none: never subscribed / no useful subscription context\n */\nexport function resolveSubscriptionView(\n subscriber: CurrentUserSubscriberResult | null | undefined,\n): SubscriptionView {\n if (!subscriber) {\n return 'none';\n }\n\n const status = (subscriber.status ?? '').toUpperCase();\n const isCanceledStatus = (\n CANCELED_SUBSCRIPTION_STATUSES.has(status)\n || status.includes('CANCEL')\n );\n\n if (\n !isCanceledStatus\n && (\n subscriber.canEnroll\n || subscriber.isSubscriber\n || ACTIVE_SUBSCRIPTION_STATUSES.has(status)\n )\n ) {\n return 'active';\n }\n\n const periodStillOpen = isFutureDate(subscriber.currentPeriodEnd)\n || isFutureDate(subscriber.subscriptionEndDate);\n\n if (isCanceledStatus) {\n if (subscriber.isSubscriber || periodStillOpen) {\n return 'canceled_access';\n }\n return 'canceled_expired';\n }\n\n if (subscriber.subscriptionBiId || subscriber.canceledAt) {\n return 'canceled_expired';\n }\n\n return 'none';\n}\n\n/** Human-readable plan label from renewal type / status. */\nexport function resolvePlanLabel(\n subscriber: CurrentUserSubscriberResult | null | undefined,\n): 'monthly' | 'annual' {\n const raw = (subscriber?.renewalType ?? '').toLowerCase();\n if (raw.includes('annual') || raw.includes('year')) {\n return 'annual';\n }\n return 'monthly';\n}\n"]}
|
|
1
|
+
{"version":3,"file":"subscriptionView.js","sourceRoot":"","sources":["../../src/utils/subscriptionView.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAA0D;;IAE1D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAA,UAAU,CAAC,MAAM,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACvD,MAAM,gBAAgB,GAAG,CACvB,8BAA8B,CAAC,GAAG,CAAC,MAAM,CAAC;WACvC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC7B,CAAC;IAEF,IACE,CAAC,gBAAgB;WACd,CACD,UAAU,CAAC,SAAS;eACjB,UAAU,CAAC,YAAY;eACvB,4BAA4B,CAAC,GAAG,CAAC,MAAM,CAAC,CAC5C,EACD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,eAAe,GAAG,YAAY,CAAC,UAAU,CAAC,gBAAgB,CAAC;WAC5D,YAAY,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;IAElD,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,UAAU,CAAC,YAAY,IAAI,eAAe,EAAE,CAAC;YAC/C,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QACD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,IAAI,UAAU,CAAC,gBAAgB,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAC9B,UAA0D;;IAE1D,MAAM,GAAG,GAAG,CAAC,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,WAAW,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1D,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,2FAA2F;IAC3F,MAAM,MAAM,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,iBAAiB,0CAAE,MAAM,CAAC;IACrD,IAAI,MAAM,KAAK,qBAAqB,EAAE,CAAC;QACrC,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,MAAM,KAAK,sBAAsB,EAAE,CAAC;QACtC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,MAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ,mCAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,eAAe,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACxF,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["/**\n * Derive which manage-subscription UI to show from subscriber API data.\n */\n\nimport {\n ACTIVE_SUBSCRIPTION_STATUSES,\n CANCELED_SUBSCRIPTION_STATUSES,\n} from '../constants';\nimport type { CurrentUserSubscriberResult, SubscriptionView } from '../types';\nimport { isFutureDate } from './formatDate';\n\n/**\n * Map subscriber payload → UI view.\n *\n * - active: can enroll / ACTIVE / TRIAL / isSubscriber without cancel status\n * - canceled_access: canceled but period end still in the future (or isSubscriber)\n * - canceled_expired: previously subscribed, no current access\n * - none: never subscribed / no useful subscription context\n */\nexport function resolveSubscriptionView(\n subscriber: CurrentUserSubscriberResult | null | undefined,\n): SubscriptionView {\n if (!subscriber) {\n return 'none';\n }\n\n const status = (subscriber.status ?? '').toUpperCase();\n const isCanceledStatus = (\n CANCELED_SUBSCRIPTION_STATUSES.has(status)\n || status.includes('CANCEL')\n );\n\n if (\n !isCanceledStatus\n && (\n subscriber.canEnroll\n || subscriber.isSubscriber\n || ACTIVE_SUBSCRIPTION_STATUSES.has(status)\n )\n ) {\n return 'active';\n }\n\n const periodStillOpen = isFutureDate(subscriber.currentPeriodEnd)\n || isFutureDate(subscriber.subscriptionEndDate);\n\n if (isCanceledStatus) {\n if (subscriber.isSubscriber || periodStillOpen) {\n return 'canceled_access';\n }\n return 'canceled_expired';\n }\n\n if (subscriber.subscriptionBiId || subscriber.canceledAt) {\n return 'canceled_expired';\n }\n\n return 'none';\n}\n\n/** Human-readable plan label from renewal type / status. */\nexport function resolvePlanLabel(\n subscriber: CurrentUserSubscriberResult | null | undefined,\n): 'monthly' | 'annual' {\n const raw = (subscriber?.renewalType ?? '').toLowerCase();\n if (raw.includes('annual') || raw.includes('year')) {\n return 'annual';\n }\n if (raw) {\n return 'monthly';\n }\n\n // renewalType/tStripePriceId unavailable (e.g. PayPal) — fall back to billing-plan fields.\n const omName = subscriber?.bipOwnershipModel?.omName;\n if (omName === 'Annual Subscription') {\n return 'annual';\n }\n if (omName === 'Monthly Subscription') {\n return 'monthly';\n }\n\n const cycle = (subscriber?.interval ?? subscriber?.billingInterval ?? '').toLowerCase();\n if (cycle.includes('annual') || cycle.includes('year')) {\n return 'annual';\n }\n if (cycle.includes('month')) {\n return 'monthly';\n }\n\n return 'monthly';\n}\n"]}
|