@edx/frontend-app-subscription-manage 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/Main.js +1 -1
  2. package/dist/Main.js.map +1 -1
  3. package/dist/app.js +3 -0
  4. package/dist/app.js.map +1 -1
  5. package/dist/checkoutPage/CheckoutPage.d.ts +3 -0
  6. package/dist/checkoutPage/CheckoutPage.js +24 -0
  7. package/dist/checkoutPage/CheckoutPage.js.map +1 -0
  8. package/dist/components/BrandMarks/BrandMarks.d.ts +3 -0
  9. package/dist/components/BrandMarks/BrandMarks.js +9 -0
  10. package/dist/components/BrandMarks/BrandMarks.js.map +1 -0
  11. package/dist/components/CartSummary/CartSummary.d.ts +21 -0
  12. package/dist/components/CartSummary/CartSummary.js +30 -0
  13. package/dist/components/CartSummary/CartSummary.js.map +1 -0
  14. package/dist/components/CartSummary/Messages.d.ts +73 -0
  15. package/dist/components/CartSummary/Messages.js +76 -0
  16. package/dist/components/CartSummary/Messages.js.map +1 -0
  17. package/dist/components/Checkout/Checkout.d.ts +4 -0
  18. package/dist/components/Checkout/Checkout.js +37 -0
  19. package/dist/components/Checkout/Checkout.js.map +1 -0
  20. package/dist/components/CheckoutGate/CheckoutGate.d.ts +9 -0
  21. package/dist/components/CheckoutGate/CheckoutGate.js +34 -0
  22. package/dist/components/CheckoutGate/CheckoutGate.js.map +1 -0
  23. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.d.ts +9 -0
  24. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.js +28 -0
  25. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.js.map +1 -0
  26. package/dist/components/CourseEnrollmentCard/Messages.d.ts +33 -0
  27. package/dist/components/CourseEnrollmentCard/Messages.js +35 -0
  28. package/dist/components/CourseEnrollmentCard/Messages.js.map +1 -0
  29. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.d.ts +13 -0
  30. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.js +11 -0
  31. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.js.map +1 -0
  32. package/dist/components/EnrollmentSummary/EnrollmentSummary.d.ts +15 -0
  33. package/dist/components/EnrollmentSummary/EnrollmentSummary.js +21 -0
  34. package/dist/components/EnrollmentSummary/EnrollmentSummary.js.map +1 -0
  35. package/dist/components/EnrollmentSummary/Messages.d.ts +33 -0
  36. package/dist/components/EnrollmentSummary/Messages.js +35 -0
  37. package/dist/components/EnrollmentSummary/Messages.js.map +1 -0
  38. package/dist/components/PaymentFields/PaymentFields.d.ts +9 -0
  39. package/dist/components/PaymentFields/PaymentFields.js +7 -0
  40. package/dist/components/PaymentFields/PaymentFields.js.map +1 -0
  41. package/dist/components/PaymentForm/Messages.d.ts +88 -0
  42. package/dist/components/PaymentForm/Messages.js +95 -0
  43. package/dist/components/PaymentForm/Messages.js.map +1 -0
  44. package/dist/components/PaymentForm/PaymentForm.d.ts +21 -0
  45. package/dist/components/PaymentForm/PaymentForm.js +69 -0
  46. package/dist/components/PaymentForm/PaymentForm.js.map +1 -0
  47. package/dist/components/StatusScreens/Messages.d.ts +103 -0
  48. package/dist/components/StatusScreens/Messages.js +108 -0
  49. package/dist/components/StatusScreens/Messages.js.map +1 -0
  50. package/dist/components/StatusScreens/StatusScreens.d.ts +23 -0
  51. package/dist/components/StatusScreens/StatusScreens.js +25 -0
  52. package/dist/components/StatusScreens/StatusScreens.js.map +1 -0
  53. package/dist/constants.d.ts +59 -0
  54. package/dist/constants.js +275 -0
  55. package/dist/constants.js.map +1 -1
  56. package/dist/data/hooks/keys.d.ts +14 -0
  57. package/dist/data/hooks/keys.js +15 -0
  58. package/dist/data/hooks/keys.js.map +1 -0
  59. package/dist/data/hooks/useCheckout.d.ts +57 -0
  60. package/dist/data/hooks/useCheckout.js +249 -0
  61. package/dist/data/hooks/useCheckout.js.map +1 -0
  62. package/dist/data/hooks/useCheckoutGate.d.ts +15 -0
  63. package/dist/data/hooks/useCheckoutGate.js +54 -0
  64. package/dist/data/hooks/useCheckoutGate.js.map +1 -0
  65. package/dist/data/hooks/useCheckoutMutations.d.ts +16 -0
  66. package/dist/data/hooks/useCheckoutMutations.js +131 -0
  67. package/dist/data/hooks/useCheckoutMutations.js.map +1 -0
  68. package/dist/data/hooks/useCheckoutQueries.d.ts +35 -0
  69. package/dist/data/hooks/useCheckoutQueries.js +110 -0
  70. package/dist/data/hooks/useCheckoutQueries.js.map +1 -0
  71. package/dist/data/services/subs/urls.d.ts +2 -0
  72. package/dist/data/services/subs/urls.js +4 -0
  73. package/dist/data/services/subs/urls.js.map +1 -0
  74. package/dist/routes.d.ts +2 -1
  75. package/dist/routes.js +33 -4
  76. package/dist/routes.js.map +1 -1
  77. package/dist/style.scss +13 -0
  78. package/dist/styles/components/brandMarks.scss +54 -0
  79. package/dist/styles/components/cartSummary.scss +18 -0
  80. package/dist/styles/components/checkout.scss +29 -0
  81. package/dist/styles/components/checkoutStepper.scss +9 -0
  82. package/dist/styles/components/courseEnrollmentCard.scss +38 -0
  83. package/dist/styles/components/edxUnlimitedBanner.scss +138 -0
  84. package/dist/styles/components/enrollmentSummary.scss +13 -0
  85. package/dist/styles/components/paymentFields.scss +15 -0
  86. package/dist/styles/components/paymentForm.scss +105 -0
  87. package/dist/styles/components/statusScreens.scss +29 -0
  88. package/dist/styles/components/successScreen.scss +0 -0
  89. package/dist/types.d.ts +222 -0
  90. package/dist/types.js +2 -0
  91. package/dist/types.js.map +1 -0
  92. package/dist/utils/auth.d.ts +7 -0
  93. package/dist/utils/auth.js +28 -0
  94. package/dist/utils/auth.js.map +1 -0
  95. package/dist/utils/billingDetails.d.ts +30 -0
  96. package/dist/utils/billingDetails.js +47 -0
  97. package/dist/utils/billingDetails.js.map +1 -0
  98. package/dist/utils/bootstrapApi.d.ts +20 -0
  99. package/dist/utils/bootstrapApi.js +142 -0
  100. package/dist/utils/bootstrapApi.js.map +1 -0
  101. package/dist/utils/cartApi.d.ts +16 -0
  102. package/dist/utils/cartApi.js +118 -0
  103. package/dist/utils/cartApi.js.map +1 -0
  104. package/dist/utils/checkout.d.ts +6 -0
  105. package/dist/utils/checkout.js +28 -0
  106. package/dist/utils/checkout.js.map +1 -0
  107. package/dist/utils/fetchActiveSubscriptions.d.ts +4 -0
  108. package/dist/utils/fetchActiveSubscriptions.js +36 -0
  109. package/dist/utils/fetchActiveSubscriptions.js.map +1 -0
  110. package/dist/utils/fetchBillingPlans.d.ts +2 -0
  111. package/dist/utils/fetchBillingPlans.js +48 -0
  112. package/dist/utils/fetchBillingPlans.js.map +1 -0
  113. package/dist/utils/graphqlClient.d.ts +16 -0
  114. package/dist/utils/graphqlClient.js +39 -0
  115. package/dist/utils/graphqlClient.js.map +1 -0
  116. package/dist/utils/index.d.ts +3 -0
  117. package/dist/utils/index.js +17 -0
  118. package/dist/utils/index.js.map +1 -0
  119. package/dist/utils/provision.d.ts +25 -0
  120. package/dist/utils/provision.js +107 -0
  121. package/dist/utils/provision.js.map +1 -0
  122. package/dist/utils/queries.d.ts +35 -0
  123. package/dist/utils/queries.js +168 -0
  124. package/dist/utils/queries.js.map +1 -0
  125. package/dist/utils/stripe.d.ts +7 -0
  126. package/dist/utils/stripe.js +43 -0
  127. package/dist/utils/stripe.js.map +1 -0
  128. package/package.json +2 -2
  129. package/dist/example/ExamplePage.d.ts +0 -2
  130. package/dist/example/ExamplePage.js +0 -6
  131. package/dist/example/ExamplePage.js.map +0 -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, } 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';
package/dist/Main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACpF,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,MAAM,KAAG,GACL,IACY,CACtB,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import { CurrentAppProvider, getSiteConfig, useIntl } 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 <Outlet />\n </main>\n </CurrentAppProvider>\n );\n};\n\nexport default Main;\n"]}
1
+ {"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,OAAO,GACR,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,MAAM,KAAG,GACL,IACY,CACtB,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import {\n CurrentAppProvider,\n getSiteConfig,\n useIntl,\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 <Outlet />\n </main>\n </CurrentAppProvider>\n );\n};\n\nexport default Main;\n"]}
package/dist/app.js CHANGED
@@ -5,6 +5,9 @@ const app = {
5
5
  appId,
6
6
  routes,
7
7
  slots,
8
+ // Environment-specific values (STRIPE_PUBLIC_KEY, VIAX_API_URL) are supplied
9
+ // by site.config.{dev,stage,prod}.tsx at site build time.
10
+ config: {},
8
11
  };
9
12
  export default app;
10
13
  //# sourceMappingURL=app.js.map
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,GAAG,GAAQ;IACf,KAAK;IACL,MAAM;IACN,KAAK;CACN,CAAC;AAEF,eAAe,GAAG,CAAC","sourcesContent":["import { App } from '@openedx/frontend-base';\nimport { appId } from '@src/constants';\nimport routes from '@src/routes';\nimport slots from '@src/slots';\n\nconst app: App = {\n appId,\n routes,\n slots,\n};\n\nexport default app;\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,GAAG,GAAQ;IACf,KAAK;IACL,MAAM;IACN,KAAK;IACL,6EAA6E;IAC7E,0DAA0D;IAC1D,MAAM,EAAE,EAAE;CACX,CAAC;AAEF,eAAe,GAAG,CAAC","sourcesContent":["import { App } from '@openedx/frontend-base';\nimport { appId } from '@src/constants';\nimport routes from '@src/routes';\nimport slots from '@src/slots';\n\nconst app: App = {\n appId,\n routes,\n slots,\n // Environment-specific values (STRIPE_PUBLIC_KEY, VIAX_API_URL) are supplied\n // by site.config.{dev,stage,prod}.tsx at site build time.\n config: {},\n};\n\nexport default app;\n"]}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const CheckoutPage: React.FC;
3
+ export default CheckoutPage;
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Alert, Container } from '@openedx/paragon';
3
+ import { getAppConfig, getSiteConfig } from '@openedx/frontend-base';
4
+ import { appId } from '../constants';
5
+ import CheckoutGate from '../components/CheckoutGate/CheckoutGate';
6
+ const PageWrapper = ({ children }) => (_jsx(Container, { children: children }));
7
+ const CheckoutPage = () => {
8
+ const config = getAppConfig(appId);
9
+ const siteConfig = getSiteConfig();
10
+ const LMS_BASE_URL = siteConfig.lmsBaseUrl.replace(/\/$/, '');
11
+ const stripePublishableKey = config.STRIPE_PUBLIC_KEY;
12
+ const apiUrl = config.VIAX_API_URL;
13
+ const edxSessionUrl = `${LMS_BASE_URL}/api/edx-session`;
14
+ if (!stripePublishableKey || !apiUrl || !edxSessionUrl) {
15
+ return (_jsx(PageWrapper, { children: _jsxs(Alert, { variant: "danger", children: ["We're having trouble loading the checkout. Please refresh the page or try again in a few moments. If the problem persists,", ' ', _jsx("a", { href: "https://courses.edx.org/support/contact_us", children: "contact support" }), "."] }) }));
16
+ }
17
+ return (_jsx(PageWrapper, { children: _jsx(CheckoutGate, { stripePublishableKey: stripePublishableKey, apiUrl: apiUrl, edxSessionUrl: edxSessionUrl, subscribedRedirectUrl: `${LMS_BASE_URL}/dashboard`, learnerDashboardUrl: `${LMS_BASE_URL}/dashboard`, onComplete: (_subscriptionBiId) => {
18
+ console.log(_subscriptionBiId);
19
+ // window.location.href = `/checkout/confirmation?sub=${_subscriptionBiId ?? ''}`;
20
+ // Success screen.
21
+ } }) }));
22
+ };
23
+ export default CheckoutPage;
24
+ //# sourceMappingURL=CheckoutPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckoutPage.js","sourceRoot":"","sources":["../../src/checkoutPage/CheckoutPage.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,YAAY,MAAM,yCAAyC,CAAC;AAEnE,MAAM,WAAW,GAA4C,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAC7E,KAAC,SAAS,cAAE,QAAQ,GAAa,CAClC,CAAC;AAEF,MAAM,YAAY,GAAa,GAAG,EAAE;IAClC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,oBAAoB,GAAG,MAAM,CAAC,iBAA2B,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,YAAsB,CAAC;IAC7C,MAAM,aAAa,GAAG,GAAG,YAAY,kBAAkB,CAAC;IAExD,IAAI,CAAC,oBAAoB,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QACvD,OAAO,CACL,KAAC,WAAW,cACV,MAAC,KAAK,IAAC,OAAO,EAAC,QAAQ,2IAEwC,GAAG,EAChE,YAAG,IAAI,EAAC,4CAA4C,gCAEhD,SAEE,GACI,CACf,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,WAAW,cACV,KAAC,YAAY,IACX,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,aAAa,EAC5B,qBAAqB,EAAE,GAAG,YAAY,YAAY,EAClD,mBAAmB,EAAE,GAAG,YAAY,YAAY,EAChD,UAAU,EAAE,CAAC,iBAAiB,EAAE,EAAE;gBAChC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;gBAC/B,kFAAkF;gBAClF,kBAAkB;YACpB,CAAC,GACD,GACU,CACf,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import React from 'react';\nimport { Alert, Container } from '@openedx/paragon';\nimport { getAppConfig, getSiteConfig } from '@openedx/frontend-base';\nimport { appId } from '@src/constants';\nimport CheckoutGate from '../components/CheckoutGate/CheckoutGate';\n\nconst PageWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <Container>{children}</Container>\n);\n\nconst CheckoutPage: React.FC = () => {\n const config = getAppConfig(appId);\n const siteConfig = getSiteConfig();\n const LMS_BASE_URL = siteConfig.lmsBaseUrl.replace(/\\/$/, '');\n const stripePublishableKey = config.STRIPE_PUBLIC_KEY as string;\n const apiUrl = config.VIAX_API_URL as string;\n const edxSessionUrl = `${LMS_BASE_URL}/api/edx-session`;\n\n if (!stripePublishableKey || !apiUrl || !edxSessionUrl) {\n return (\n <PageWrapper>\n <Alert variant=\"danger\">\n We&apos;re having trouble loading the checkout. Please refresh the\n page or try again in a few moments. If the problem persists,{' '}\n <a href=\"https://courses.edx.org/support/contact_us\">\n contact support\n </a>\n .\n </Alert>\n </PageWrapper>\n );\n }\n\n return (\n <PageWrapper>\n <CheckoutGate\n stripePublishableKey={stripePublishableKey}\n apiUrl={apiUrl}\n edxSessionUrl={edxSessionUrl}\n subscribedRedirectUrl={`${LMS_BASE_URL}/dashboard`}\n learnerDashboardUrl={`${LMS_BASE_URL}/dashboard`}\n onComplete={(_subscriptionBiId) => {\n console.log(_subscriptionBiId);\n // window.location.href = `/checkout/confirmation?sub=${_subscriptionBiId ?? ''}`;\n // Success screen.\n }}\n />\n </PageWrapper>\n );\n};\n\nexport default CheckoutPage;\n"]}
@@ -0,0 +1,3 @@
1
+ export declare const CardBrands: () => import("react/jsx-runtime").JSX.Element;
2
+ export declare const PayPalWordmark: () => import("react/jsx-runtime").JSX.Element;
3
+ export declare const EdxUnlimitedLogo: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ const Visa = () => (_jsxs("svg", { width: "34", height: "22", viewBox: "0 0 34 22", role: "img", "aria-label": "Visa", children: [_jsx("rect", { width: "34", height: "22", rx: "3", fill: "#1A1F71" }), _jsx("text", { x: "17", y: "15", textAnchor: "middle", fontFamily: "Arial, sans-serif", fontWeight: "700", fontStyle: "italic", fontSize: "10", fill: "#fff", children: "VISA" })] }));
3
+ const Mastercard = () => (_jsxs("svg", { width: "34", height: "22", viewBox: "0 0 34 22", role: "img", "aria-label": "Mastercard", children: [_jsx("rect", { width: "34", height: "22", rx: "3", fill: "#fff", stroke: "#E6E6E6" }), _jsx("circle", { cx: "14", cy: "11", r: "6", fill: "#EB001B" }), _jsx("circle", { cx: "20", cy: "11", r: "6", fill: "#F79E1B", fillOpacity: "0.9" })] }));
4
+ const Amex = () => (_jsxs("svg", { width: "34", height: "22", viewBox: "0 0 34 22", role: "img", "aria-label": "American Express", children: [_jsx("rect", { width: "34", height: "22", rx: "3", fill: "#1F72CD" }), _jsx("text", { x: "17", y: "14", textAnchor: "middle", fontFamily: "Arial, sans-serif", fontWeight: "700", fontSize: "6.5", fill: "#fff", children: "AMEX" })] }));
5
+ const Discover = () => (_jsxs("svg", { width: "34", height: "22", viewBox: "0 0 34 22", role: "img", "aria-label": "Discover", children: [_jsx("rect", { width: "34", height: "22", rx: "3", fill: "#fff", stroke: "#E6E6E6" }), _jsx("circle", { cx: "25", cy: "11", r: "4", fill: "#F47216" }), _jsx("text", { x: "13", y: "14", textAnchor: "middle", fontFamily: "Arial, sans-serif", fontWeight: "700", fontSize: "5", fill: "#231F20", children: "DISCVR" })] }));
6
+ export const CardBrands = () => (_jsxs("div", { className: "brand-marks__card-brands", children: [_jsx(Visa, {}), _jsx(Mastercard, {}), _jsx(Amex, {}), _jsx(Discover, {})] }));
7
+ export const PayPalWordmark = () => (_jsxs("span", { className: "brand-marks__paypal", children: [_jsx("span", { className: "brand-marks__paypal-pay", children: "Pay" }), _jsx("span", { className: "brand-marks__paypal-pal", children: "Pal" })] }));
8
+ export const EdxUnlimitedLogo = () => (_jsx("div", { className: "brand-marks__edx-logo", "aria-label": "edX unlimited", children: _jsxs("div", { className: "brand-marks__edx-logo-text", children: [_jsx("div", { className: "brand-marks__edx-logo-edx", children: "edX" }), _jsx("div", { className: "brand-marks__edx-logo-unlimited", children: "unlimited" })] }) }));
9
+ //# sourceMappingURL=BrandMarks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrandMarks.js","sourceRoot":"","sources":["../../../src/components/BrandMarks/BrandMarks.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nconst Visa = () => (\n <svg width=\"34\" height=\"22\" viewBox=\"0 0 34 22\" role=\"img\" aria-label=\"Visa\">\n <rect width=\"34\" height=\"22\" rx=\"3\" fill=\"#1A1F71\" />\n <text\n x=\"17\"\n y=\"15\"\n textAnchor=\"middle\"\n fontFamily=\"Arial, sans-serif\"\n fontWeight=\"700\"\n fontStyle=\"italic\"\n fontSize=\"10\"\n fill=\"#fff\"\n >\n VISA\n </text>\n </svg>\n);\n\nconst Mastercard = () => (\n <svg\n width=\"34\"\n height=\"22\"\n viewBox=\"0 0 34 22\"\n role=\"img\"\n aria-label=\"Mastercard\"\n >\n <rect width=\"34\" height=\"22\" rx=\"3\" fill=\"#fff\" stroke=\"#E6E6E6\" />\n <circle cx=\"14\" cy=\"11\" r=\"6\" fill=\"#EB001B\" />\n <circle cx=\"20\" cy=\"11\" r=\"6\" fill=\"#F79E1B\" fillOpacity=\"0.9\" />\n </svg>\n);\n\nconst Amex = () => (\n <svg\n width=\"34\"\n height=\"22\"\n viewBox=\"0 0 34 22\"\n role=\"img\"\n aria-label=\"American Express\"\n >\n <rect width=\"34\" height=\"22\" rx=\"3\" fill=\"#1F72CD\" />\n <text\n x=\"17\"\n y=\"14\"\n textAnchor=\"middle\"\n fontFamily=\"Arial, sans-serif\"\n fontWeight=\"700\"\n fontSize=\"6.5\"\n fill=\"#fff\"\n >\n AMEX\n </text>\n </svg>\n);\n\nconst Discover = () => (\n <svg\n width=\"34\"\n height=\"22\"\n viewBox=\"0 0 34 22\"\n role=\"img\"\n aria-label=\"Discover\"\n >\n <rect width=\"34\" height=\"22\" rx=\"3\" fill=\"#fff\" stroke=\"#E6E6E6\" />\n <circle cx=\"25\" cy=\"11\" r=\"4\" fill=\"#F47216\" />\n <text\n x=\"13\"\n y=\"14\"\n textAnchor=\"middle\"\n fontFamily=\"Arial, sans-serif\"\n fontWeight=\"700\"\n fontSize=\"5\"\n fill=\"#231F20\"\n >\n DISCVR\n </text>\n </svg>\n);\n\nexport const CardBrands = () => (\n <div className=\"brand-marks__card-brands\">\n <Visa />\n <Mastercard />\n <Amex />\n <Discover />\n </div>\n);\n\nexport const PayPalWordmark = () => (\n <span className=\"brand-marks__paypal\">\n <span className=\"brand-marks__paypal-pay\">Pay</span>\n <span className=\"brand-marks__paypal-pal\">Pal</span>\n </span>\n);\n\nexport const EdxUnlimitedLogo = () => (\n <div className=\"brand-marks__edx-logo\" aria-label=\"edX unlimited\">\n <div className=\"brand-marks__edx-logo-text\">\n <div className=\"brand-marks__edx-logo-edx\">edX</div>\n <div className=\"brand-marks__edx-logo-unlimited\">unlimited</div>\n </div>\n </div>\n);\n"]}
@@ -0,0 +1,21 @@
1
+ import type { CourseDetail } from '../../types';
2
+ export type BillingCycle = 'monthly' | 'annual';
3
+ export interface CartSummaryProps {
4
+ productTitle?: string;
5
+ productBlurb?: string;
6
+ /** Monthly price amount e.g. "39" */
7
+ monthlyAmount?: string;
8
+ /** Annual price amount e.g. "299" */
9
+ annualAmount?: string;
10
+ currency?: string;
11
+ activeSubscriberCount?: number | null;
12
+ defaultCycle?: BillingCycle;
13
+ monthlyRenewalLabel?: string;
14
+ annualRenewalLabel?: string;
15
+ onCycleChange?: (cycle: BillingCycle) => void;
16
+ learnerCount?: number;
17
+ /** When set, shows the course enrollment preview card below the summary card. */
18
+ course?: CourseDetail | null;
19
+ }
20
+ declare const CartSummary: ({ productTitle, productBlurb, monthlyAmount, annualAmount, currency, activeSubscriberCount, defaultCycle, onCycleChange, learnerCount: learnerCountProp, course, }: CartSummaryProps) => import("react/jsx-runtime").JSX.Element;
21
+ export default CartSummary;
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Badge, Card, Icon } from '@openedx/paragon';
4
+ import { Group, People, Institution } from '@openedx/paragon/icons';
5
+ import { useIntl } from '@openedx/frontend-base';
6
+ import { EdxUnlimitedLogo } from '../BrandMarks/BrandMarks';
7
+ import CourseEnrollmentCard from '../CourseEnrollmentCard/CourseEnrollmentCard';
8
+ import messages from './Messages';
9
+ const CartSummary = ({ productTitle = 'edX Subscription', productBlurb = 'Subscribe and get access to hundreds of courses and programs.', monthlyAmount = '39', annualAmount = '299', currency = 'USD', activeSubscriberCount, defaultCycle = 'monthly', onCycleChange, learnerCount: learnerCountProp = 2203, course = null, }) => {
10
+ const { formatMessage } = useIntl();
11
+ const [cycle, setCycle] = useState(defaultCycle);
12
+ const isMonthly = cycle === 'monthly';
13
+ const handleToggle = () => {
14
+ const next = isMonthly ? 'annual' : 'monthly';
15
+ setCycle(next);
16
+ onCycleChange === null || onCycleChange === void 0 ? void 0 : onCycleChange(next);
17
+ };
18
+ const frequency = isMonthly ? 'month' : 'year';
19
+ const amount = isMonthly ? monthlyAmount : annualAmount;
20
+ const learnerCount = (activeSubscriberCount != null ? activeSubscriberCount : learnerCountProp).toLocaleString();
21
+ return (_jsxs("div", { className: "cart-summary ", children: [_jsxs(Card, { className: "cart-summary__card p-3", children: [_jsxs(Card.Section, { className: "d-flex justify-content-between align-items-center p-0 pb-3", children: [_jsx("span", { className: "font-weight-bold text-gray-900", children: formatMessage(messages.summaryHeading) }), _jsxs(Badge, { variant: "light", className: "d-flex align-items-center px-2 py-1", children: [_jsx(Icon, { src: Group, className: "mr-1", style: { width: '1rem', height: '1rem' } }), formatMessage(messages.learnersSubscribed, {
22
+ count: learnerCount,
23
+ })] })] }), _jsx(Card.Divider, {}), _jsx(Card.Section, { className: "p-0 py-3", children: _jsxs("div", { className: "d-flex align-items-start", children: [_jsx(EdxUnlimitedLogo, {}), _jsxs("div", { children: [_jsx("p", { className: "font-weight-bold mb-0 text-primary-500", children: productTitle }), _jsx("p", { className: "small mb-0 text-gray-900", children: productBlurb })] })] }) }), _jsx(Card.Divider, {}), _jsxs(Card.Section, { className: "p-0 py-3", children: [_jsxs("div", { className: "d-flex justify-content-between align-items-center mb-1", children: [_jsx("span", { className: "small text-gray-900", children: isMonthly
24
+ ? formatMessage(messages.monthlySubscription)
25
+ : formatMessage(messages.annualSubscription) }), _jsx("span", { className: "text-success font-weight-bold small", children: formatMessage(messages.trialLabel) })] }), _jsxs("div", { className: "d-flex justify-content-between align-items-center", children: [_jsx("button", { type: "button", className: "btn btn-link p-0 small", onClick: handleToggle, children: isMonthly
26
+ ? formatMessage(messages.switchToAnnual)
27
+ : formatMessage(messages.switchToMonthly) }), _jsxs("span", { className: "small text-gray-900 font-weight-bold", children: ["$", amount, "/", frequency, " ", currency] })] })] }), _jsxs(Card.Section, { className: "d-flex justify-content-between align-items-center px-0", children: [_jsx("span", { className: "font-weight-bold text-gray-900", children: formatMessage(messages.todaysTotal) }), _jsx("span", { className: "font-weight-bold mb-0 text-gray-900", children: formatMessage(messages.todaysTotalValue) })] })] }), course && (_jsx(CourseEnrollmentCard, { course: course, variant: "checkout" })), _jsxs("div", { className: "cart-summary__stats d-none d-lg-flex mt-3", children: [_jsxs("div", { className: "cart-summary__stat d-flex align-items-center mr-4", children: [_jsx(Icon, { src: People, className: "mr-2 text-muted", style: { width: '1.5rem', height: '1.5rem' } }), _jsxs("div", { children: [_jsx("p", { className: "font-weight-bold mb-0", children: formatMessage(messages.learnersCount) }), _jsx("p", { className: "text-muted small mb-0", children: formatMessage(messages.learnersLabel) })] })] }), _jsxs("div", { className: "cart-summary__stat d-flex align-items-center", children: [_jsx(Icon, { src: Institution, className: "mr-2 text-muted", style: { width: '1.5rem', height: '1.5rem' } }), _jsxs("div", { children: [_jsx("p", { className: "font-weight-bold mb-0", children: formatMessage(messages.institutionsCount) }), _jsx("p", { className: "text-muted small mb-0", children: formatMessage(messages.institutionsLabel) })] })] })] })] }));
28
+ };
29
+ export default CartSummary;
30
+ //# sourceMappingURL=CartSummary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CartSummary.js","sourceRoot":"","sources":["../../../src/components/CartSummary/CartSummary.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState } from 'react';\nimport { Badge, Card, Icon } from '@openedx/paragon';\nimport { Group, People, Institution } from '@openedx/paragon/icons';\nimport { useIntl } from '@openedx/frontend-base';\nimport { EdxUnlimitedLogo } from '../BrandMarks/BrandMarks';\nimport CourseEnrollmentCard from '../CourseEnrollmentCard/CourseEnrollmentCard';\nimport type { CourseDetail } from '../../types';\nimport messages from './Messages';\n\nexport type BillingCycle = 'monthly' | 'annual';\n\nexport interface CartSummaryProps {\n productTitle?: string,\n productBlurb?: string,\n /** Monthly price amount e.g. \"39\" */\n monthlyAmount?: string,\n /** Annual price amount e.g. \"299\" */\n annualAmount?: string,\n currency?: string,\n activeSubscriberCount?: number | null,\n defaultCycle?: BillingCycle,\n monthlyRenewalLabel?: string,\n annualRenewalLabel?: string,\n onCycleChange?: (cycle: BillingCycle) => void,\n learnerCount?: number,\n /** When set, shows the course enrollment preview card below the summary card. */\n course?: CourseDetail | null,\n}\n\nconst CartSummary = ({\n productTitle = 'edX Subscription',\n productBlurb = 'Subscribe and get access to hundreds of courses and programs.',\n monthlyAmount = '39',\n annualAmount = '299',\n currency = 'USD',\n activeSubscriberCount,\n defaultCycle = 'monthly',\n onCycleChange,\n learnerCount: learnerCountProp = 2203,\n course = null,\n}: CartSummaryProps) => {\n const { formatMessage } = useIntl();\n const [cycle, setCycle] = useState<BillingCycle>(defaultCycle);\n\n const isMonthly = cycle === 'monthly';\n\n const handleToggle = () => {\n const next: BillingCycle = isMonthly ? 'annual' : 'monthly';\n setCycle(next);\n onCycleChange?.(next);\n };\n\n const frequency = isMonthly ? 'month' : 'year';\n const amount = isMonthly ? monthlyAmount : annualAmount;\n\n const learnerCount = (\n activeSubscriberCount != null ? activeSubscriberCount : learnerCountProp\n ).toLocaleString();\n\n return (\n <div className=\"cart-summary \">\n <Card className=\"cart-summary__card p-3\">\n <Card.Section className=\"d-flex justify-content-between align-items-center p-0 pb-3\">\n <span className=\"font-weight-bold text-gray-900\">\n {formatMessage(messages.summaryHeading)}\n </span>\n <Badge\n variant=\"light\"\n className=\"d-flex align-items-center px-2 py-1\"\n >\n <Icon\n src={Group}\n className=\"mr-1\"\n style={{ width: '1rem', height: '1rem' }}\n />\n {formatMessage(messages.learnersSubscribed, {\n count: learnerCount,\n })}\n </Badge>\n </Card.Section>\n\n <Card.Divider />\n\n <Card.Section className=\"p-0 py-3\">\n <div className=\"d-flex align-items-start\">\n <EdxUnlimitedLogo />\n <div>\n <p className=\"font-weight-bold mb-0 text-primary-500\">\n {productTitle}\n </p>\n <p className=\"small mb-0 text-gray-900\">{productBlurb}</p>\n </div>\n </div>\n </Card.Section>\n\n <Card.Divider />\n\n <Card.Section className=\"p-0 py-3\">\n <div className=\"d-flex justify-content-between align-items-center mb-1\">\n <span className=\"small text-gray-900\">\n {isMonthly\n ? formatMessage(messages.monthlySubscription)\n : formatMessage(messages.annualSubscription)}\n </span>\n <span className=\"text-success font-weight-bold small\">\n {formatMessage(messages.trialLabel)}\n </span>\n </div>\n <div className=\"d-flex justify-content-between align-items-center\">\n <button\n type=\"button\"\n className=\"btn btn-link p-0 small\"\n onClick={handleToggle}\n >\n {isMonthly\n ? formatMessage(messages.switchToAnnual)\n : formatMessage(messages.switchToMonthly)}\n </button>\n <span className=\"small text-gray-900 font-weight-bold\">\n ${amount}/{frequency} {currency}\n </span>\n </div>\n </Card.Section>\n\n <Card.Section className=\"d-flex justify-content-between align-items-center px-0\">\n <span className=\"font-weight-bold text-gray-900\">\n {formatMessage(messages.todaysTotal)}\n </span>\n <span className=\"font-weight-bold mb-0 text-gray-900\">\n {formatMessage(messages.todaysTotalValue)}\n </span>\n </Card.Section>\n </Card>\n\n {course && (\n <CourseEnrollmentCard course={course} variant=\"checkout\" />\n )}\n\n {/* Stats row */}\n <div className=\"cart-summary__stats d-none d-lg-flex mt-3\">\n <div className=\"cart-summary__stat d-flex align-items-center mr-4\">\n <Icon\n src={People}\n className=\"mr-2 text-muted\"\n style={{ width: '1.5rem', height: '1.5rem' }}\n />\n <div>\n <p className=\"font-weight-bold mb-0\">\n {formatMessage(messages.learnersCount)}\n </p>\n <p className=\"text-muted small mb-0\">\n {formatMessage(messages.learnersLabel)}\n </p>\n </div>\n </div>\n <div className=\"cart-summary__stat d-flex align-items-center\">\n <Icon\n src={Institution}\n className=\"mr-2 text-muted\"\n style={{ width: '1.5rem', height: '1.5rem' }}\n />\n <div>\n <p className=\"font-weight-bold mb-0\">\n {formatMessage(messages.institutionsCount)}\n </p>\n <p className=\"text-muted small mb-0\">\n {formatMessage(messages.institutionsLabel)}\n </p>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default CartSummary;\n"]}
@@ -0,0 +1,73 @@
1
+ declare const messages: {
2
+ summaryHeading: {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ learnersSubscribed: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ description: string;
11
+ };
12
+ monthlySubscription: {
13
+ id: string;
14
+ defaultMessage: string;
15
+ description: string;
16
+ };
17
+ annualSubscription: {
18
+ id: string;
19
+ defaultMessage: string;
20
+ description: string;
21
+ };
22
+ trialLabel: {
23
+ id: string;
24
+ defaultMessage: string;
25
+ description: string;
26
+ };
27
+ priceDisplay: {
28
+ id: string;
29
+ defaultMessage: string;
30
+ description: string;
31
+ };
32
+ todaysTotal: {
33
+ id: string;
34
+ defaultMessage: string;
35
+ description: string;
36
+ };
37
+ todaysTotalValue: {
38
+ id: string;
39
+ defaultMessage: string;
40
+ description: string;
41
+ };
42
+ switchToAnnual: {
43
+ id: string;
44
+ defaultMessage: string;
45
+ description: string;
46
+ };
47
+ switchToMonthly: {
48
+ id: string;
49
+ defaultMessage: string;
50
+ description: string;
51
+ };
52
+ learnersCount: {
53
+ id: string;
54
+ defaultMessage: string;
55
+ description: string;
56
+ };
57
+ learnersLabel: {
58
+ id: string;
59
+ defaultMessage: string;
60
+ description: string;
61
+ };
62
+ institutionsCount: {
63
+ id: string;
64
+ defaultMessage: string;
65
+ description: string;
66
+ };
67
+ institutionsLabel: {
68
+ id: string;
69
+ defaultMessage: string;
70
+ description: string;
71
+ };
72
+ };
73
+ export default messages;
@@ -0,0 +1,76 @@
1
+ import { defineMessages } from '@openedx/frontend-base';
2
+ const messages = defineMessages({
3
+ // CartSummary
4
+ summaryHeading: {
5
+ id: 'checkout.cartSummary.summaryHeading',
6
+ defaultMessage: 'Summary',
7
+ description: 'Heading for the order summary card',
8
+ },
9
+ learnersSubscribed: {
10
+ id: 'checkout.cartSummary.learnersSubscribed',
11
+ defaultMessage: '{count} learners subscribed',
12
+ description: 'Badge showing number of active learners',
13
+ },
14
+ monthlySubscription: {
15
+ id: 'checkout.cartSummary.monthlySubscription',
16
+ defaultMessage: 'Monthly subscription',
17
+ description: 'Label for monthly billing cycle',
18
+ },
19
+ annualSubscription: {
20
+ id: 'checkout.cartSummary.annualSubscription',
21
+ defaultMessage: 'Annual subscription',
22
+ description: 'Label for annual billing cycle',
23
+ },
24
+ trialLabel: {
25
+ id: 'checkout.cartSummary.trialLabel',
26
+ defaultMessage: '7-day free trial',
27
+ description: 'Free trial badge label',
28
+ },
29
+ priceDisplay: {
30
+ id: 'checkout.cartSummary.priceDisplay',
31
+ defaultMessage: '${amount}/{frequency} USD',
32
+ description: 'Price display e.g. $39/month USD',
33
+ },
34
+ todaysTotal: {
35
+ id: 'checkout.cartSummary.todaysTotal',
36
+ defaultMessage: "Today's total",
37
+ description: "Label for today's total price row",
38
+ },
39
+ todaysTotalValue: {
40
+ id: 'checkout.cartSummary.todaysTotalValue',
41
+ defaultMessage: '$0',
42
+ description: "Today's total amount during trial",
43
+ },
44
+ switchToAnnual: {
45
+ id: 'checkout.cartSummary.switchToAnnual',
46
+ defaultMessage: 'Switch to annual',
47
+ description: 'Toggle button label to switch to annual billing',
48
+ },
49
+ switchToMonthly: {
50
+ id: 'checkout.cartSummary.switchToMonthly',
51
+ defaultMessage: 'Switch to monthly',
52
+ description: 'Toggle button label to switch to monthly billing',
53
+ },
54
+ learnersCount: {
55
+ id: 'checkout.cartSummary.learnersCount',
56
+ defaultMessage: '100M',
57
+ description: 'Total learners stat',
58
+ },
59
+ learnersLabel: {
60
+ id: 'checkout.cartSummary.learnersLabel',
61
+ defaultMessage: 'Learners',
62
+ description: 'Label under the learners count stat',
63
+ },
64
+ institutionsCount: {
65
+ id: 'checkout.cartSummary.institutionsCount',
66
+ defaultMessage: '250+',
67
+ description: 'Expert institutions count stat',
68
+ },
69
+ institutionsLabel: {
70
+ id: 'checkout.cartSummary.institutionsLabel',
71
+ defaultMessage: 'Expert institutions',
72
+ description: 'Label under the institutions count stat',
73
+ },
74
+ });
75
+ export default messages;
76
+ //# sourceMappingURL=Messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../src/components/CartSummary/Messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,cAAc;IACd,cAAc,EAAE;QACd,EAAE,EAAE,qCAAqC;QACzC,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,oCAAoC;KAClD;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,6BAA6B;QAC7C,WAAW,EAAE,yCAAyC;KACvD;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,0CAA0C;QAC9C,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,iCAAiC;KAC/C;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,gCAAgC;KAC9C;IACD,UAAU,EAAE;QACV,EAAE,EAAE,iCAAiC;QACrC,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,wBAAwB;KACtC;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,2BAA2B;QAC3C,WAAW,EAAE,kCAAkC;KAChD;IACD,WAAW,EAAE;QACX,EAAE,EAAE,kCAAkC;QACtC,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,mCAAmC;KACjD;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,uCAAuC;QAC3C,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,mCAAmC;KACjD;IACD,cAAc,EAAE;QACd,EAAE,EAAE,qCAAqC;QACzC,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,iDAAiD;KAC/D;IACD,eAAe,EAAE;QACf,EAAE,EAAE,sCAAsC;QAC1C,cAAc,EAAE,mBAAmB;QACnC,WAAW,EAAE,kDAAkD;KAChE;IACD,aAAa,EAAE;QACb,EAAE,EAAE,oCAAoC;QACxC,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,qBAAqB;KACnC;IACD,aAAa,EAAE;QACb,EAAE,EAAE,oCAAoC;QACxC,cAAc,EAAE,UAAU;QAC1B,WAAW,EAAE,qCAAqC;KACnD;IACD,iBAAiB,EAAE;QACjB,EAAE,EAAE,wCAAwC;QAC5C,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,gCAAgC;KAC9C;IACD,iBAAiB,EAAE;QACjB,EAAE,EAAE,wCAAwC;QAC5C,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,yCAAyC;KACvD;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n // CartSummary\n summaryHeading: {\n id: 'checkout.cartSummary.summaryHeading',\n defaultMessage: 'Summary',\n description: 'Heading for the order summary card',\n },\n learnersSubscribed: {\n id: 'checkout.cartSummary.learnersSubscribed',\n defaultMessage: '{count} learners subscribed',\n description: 'Badge showing number of active learners',\n },\n monthlySubscription: {\n id: 'checkout.cartSummary.monthlySubscription',\n defaultMessage: 'Monthly subscription',\n description: 'Label for monthly billing cycle',\n },\n annualSubscription: {\n id: 'checkout.cartSummary.annualSubscription',\n defaultMessage: 'Annual subscription',\n description: 'Label for annual billing cycle',\n },\n trialLabel: {\n id: 'checkout.cartSummary.trialLabel',\n defaultMessage: '7-day free trial',\n description: 'Free trial badge label',\n },\n priceDisplay: {\n id: 'checkout.cartSummary.priceDisplay',\n defaultMessage: '${amount}/{frequency} USD',\n description: 'Price display e.g. $39/month USD',\n },\n todaysTotal: {\n id: 'checkout.cartSummary.todaysTotal',\n defaultMessage: \"Today's total\",\n description: \"Label for today's total price row\",\n },\n todaysTotalValue: {\n id: 'checkout.cartSummary.todaysTotalValue',\n defaultMessage: '$0',\n description: \"Today's total amount during trial\",\n },\n switchToAnnual: {\n id: 'checkout.cartSummary.switchToAnnual',\n defaultMessage: 'Switch to annual',\n description: 'Toggle button label to switch to annual billing',\n },\n switchToMonthly: {\n id: 'checkout.cartSummary.switchToMonthly',\n defaultMessage: 'Switch to monthly',\n description: 'Toggle button label to switch to monthly billing',\n },\n learnersCount: {\n id: 'checkout.cartSummary.learnersCount',\n defaultMessage: '100M',\n description: 'Total learners stat',\n },\n learnersLabel: {\n id: 'checkout.cartSummary.learnersLabel',\n defaultMessage: 'Learners',\n description: 'Label under the learners count stat',\n },\n institutionsCount: {\n id: 'checkout.cartSummary.institutionsCount',\n defaultMessage: '250+',\n description: 'Expert institutions count stat',\n },\n institutionsLabel: {\n id: 'checkout.cartSummary.institutionsLabel',\n defaultMessage: 'Expert institutions',\n description: 'Label under the institutions count stat',\n },\n});\n\nexport default messages;\n"]}
@@ -0,0 +1,4 @@
1
+ import type { UseCheckoutOptions } from '../../data/hooks/useCheckout';
2
+ export type CheckoutProps = UseCheckoutOptions;
3
+ declare const Checkout: (props: CheckoutProps) => import("react/jsx-runtime").JSX.Element;
4
+ export default Checkout;
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Alert, Col, Row } from '@openedx/paragon';
3
+ import { Error as ErrorIcon } from '@openedx/paragon/icons';
4
+ import useCheckout from '../../data/hooks/useCheckout';
5
+ import CartSummary from '../CartSummary/CartSummary';
6
+ import EnrollmentSummary from '../EnrollmentSummary/EnrollmentSummary';
7
+ import PaymentForm from '../PaymentForm/PaymentForm';
8
+ import { getPlanPrice, getRenewalLabel } from '../../utils/billingDetails';
9
+ import { getTrialDateRange } from '../../utils';
10
+ import { SuccessScreen, BlockedScreen } from '../StatusScreens/StatusScreens';
11
+ const Checkout = (props) => {
12
+ var _a, _b;
13
+ const c = useCheckout(props);
14
+ const showForm = c.phase === 'init'
15
+ || c.phase === 'ready'
16
+ || c.phase === 'failed'
17
+ || c.phase === 'processing';
18
+ const monthlyPrice = getPlanPrice(c.billingPlans, 'monthly');
19
+ const annualPrice = getPlanPrice(c.billingPlans, 'annual');
20
+ const isSubmitting = c.processingSubscription;
21
+ const { displayStart, displayEnd } = getTrialDateRange();
22
+ const handleStartCourse = () => {
23
+ var _a;
24
+ if ((_a = c.course) === null || _a === void 0 ? void 0 : _a.tUrlCourse) {
25
+ window.location.href = c.course.tUrlCourse;
26
+ }
27
+ };
28
+ const courseLabel = c.course
29
+ ? [c.course.tBrandText, c.course.maName].filter(Boolean).join(': ')
30
+ : null;
31
+ return (_jsxs(Row, { className: "checkout__container bg-light-200", children: [_jsx(Col, { xs: 12, className: "d-lg-none", children: _jsx("h1", { className: "font-weight-bold text-primary-900", children: "Checkout" }) }), _jsx(Col, { xs: 12, children: _jsxs(Row, { className: "flex-column-reverse gap-5 flex-lg-row", children: [_jsx(Col, { xs: 12, lg: 7, xxl: 9, className: "payment__options", children: _jsxs("div", { children: [_jsx("h1", { className: "font-weight-bold text-primary-900 d-none d-lg-block", children: "Checkout" }), c.error && (_jsx(Alert, { variant: "danger", icon: ErrorIcon, dismissible: true, onClose: c.clearError, children: c.error })), showForm && (_jsxs(_Fragment, { children: [c.phase === 'failed' && (_jsx(Alert, { variant: "danger", icon: ErrorIcon, className: "mb-3", children: c.lastComment
32
+ || 'Your payment could not be processed. Please check your card details and try again.' })), _jsx(PaymentForm, { billing: c.billing, setField: c.setField, numberMountRef: c.numberMountRef, expiryMountRef: c.expiryMountRef, cvcMountRef: c.cvcMountRef, cardError: c.cardError, stripeReady: c.stripeReady, sessionReady: c.sessionReady, submitting: isSubmitting, onPlaceOrder: c.placeOrder, trialEnd: displayEnd, priceToShow: c.selectedCycle === 'monthly' ? monthlyPrice : annualPrice, cycleToShow: c.selectedCycle === 'monthly' ? 'monthly' : 'annual', userCountry: c.userCountry })] })), c.phase === 'success' && (_jsx(SuccessScreen, { subscriptionBiId: ((_a = c.subscriptionDetails) === null || _a === void 0 ? void 0 : _a.biId) || '', cardLast4: ((_b = c.subscriptionDetails) === null || _b === void 0 ? void 0 : _b.cardLast4) || '', trialStart: displayStart, trialEnd: displayEnd, priceToShow: c.selectedCycle === 'monthly'
33
+ ? monthlyPrice === null || monthlyPrice === void 0 ? void 0 : monthlyPrice.label
34
+ : annualPrice === null || annualPrice === void 0 ? void 0 : annualPrice.label, cycleToShow: c.selectedCycle === 'monthly' ? 'monthly' : 'annual', courseLabel: courseLabel, onFindCourse: c.course ? handleStartCourse : undefined })), c.phase === 'blocked' && (_jsx(BlockedScreen, { detail: c.lastComment }))] }) }), _jsx(Col, { xs: 12, lg: 5, xxl: 3, className: "payment__summary", children: c.phase === 'success' ? (_jsx(EnrollmentSummary, { course: c.course, onStartCourse: handleStartCourse })) : (_jsx(CartSummary, { monthlyRenewalLabel: getRenewalLabel(c.billingPlans, 'monthly'), annualRenewalLabel: getRenewalLabel(c.billingPlans, 'annual'), activeSubscriberCount: c.activeSubscriberCount, defaultCycle: c.selectedCycle, onCycleChange: c.setCycle, course: c.course })) })] }) })] }));
35
+ };
36
+ export default Checkout;
37
+ //# sourceMappingURL=Checkout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkout.js","sourceRoot":"","sources":["../../../src/components/Checkout/Checkout.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Alert, Col, Row } from '@openedx/paragon';\nimport { Error as ErrorIcon } from '@openedx/paragon/icons';\nimport useCheckout from '../../data/hooks/useCheckout';\nimport type { UseCheckoutOptions } from '../../data/hooks/useCheckout';\nimport CartSummary from '../CartSummary/CartSummary';\nimport EnrollmentSummary from '../EnrollmentSummary/EnrollmentSummary';\nimport PaymentForm from '../PaymentForm/PaymentForm';\nimport { getPlanPrice, getRenewalLabel } from '../../utils/billingDetails';\nimport { getTrialDateRange } from '@src/utils';\nimport { SuccessScreen, BlockedScreen } from '../StatusScreens/StatusScreens';\n\nexport type CheckoutProps = UseCheckoutOptions;\n\nconst Checkout = (props: CheckoutProps) => {\n const c = useCheckout(props);\n\n const showForm\n = c.phase === 'init'\n || c.phase === 'ready'\n || c.phase === 'failed'\n || c.phase === 'processing';\n const monthlyPrice = getPlanPrice(c.billingPlans, 'monthly');\n const annualPrice = getPlanPrice(c.billingPlans, 'annual');\n const isSubmitting = c.processingSubscription;\n\n const { displayStart, displayEnd } = getTrialDateRange();\n\n const handleStartCourse = () => {\n if (c.course?.tUrlCourse) {\n window.location.href = c.course.tUrlCourse;\n }\n };\n\n const courseLabel = c.course\n ? [c.course.tBrandText, c.course.maName].filter(Boolean).join(': ')\n : null;\n\n return (\n <Row className=\"checkout__container bg-light-200\">\n <Col xs={12} className=\"d-lg-none\">\n <h1 className=\"font-weight-bold text-primary-900\">Checkout</h1>\n </Col>\n <Col xs={12}>\n <Row className=\"flex-column-reverse gap-5 flex-lg-row\">\n {/* ── LEFT ── */}\n <Col xs={12} lg={7} xxl={9} className=\"payment__options\">\n <div>\n <h1 className=\"font-weight-bold text-primary-900 d-none d-lg-block\">\n Checkout\n </h1>\n {c.error && (\n <Alert\n variant=\"danger\"\n icon={ErrorIcon}\n dismissible\n onClose={c.clearError}\n >\n {c.error}\n </Alert>\n )}\n\n {showForm && (\n <>\n {c.phase === 'failed' && (\n <Alert variant=\"danger\" icon={ErrorIcon} className=\"mb-3\">\n {c.lastComment\n || 'Your payment could not be processed. Please check your card details and try again.'}\n </Alert>\n )}\n <PaymentForm\n billing={c.billing}\n setField={c.setField}\n numberMountRef={c.numberMountRef}\n expiryMountRef={c.expiryMountRef}\n cvcMountRef={c.cvcMountRef}\n cardError={c.cardError}\n stripeReady={c.stripeReady}\n sessionReady={c.sessionReady}\n submitting={isSubmitting}\n onPlaceOrder={c.placeOrder}\n trialEnd={displayEnd}\n priceToShow={\n c.selectedCycle === 'monthly' ? monthlyPrice : annualPrice\n }\n cycleToShow={\n c.selectedCycle === 'monthly' ? 'monthly' : 'annual'\n }\n userCountry={c.userCountry}\n />\n </>\n )}\n\n {c.phase === 'success' && (\n <SuccessScreen\n subscriptionBiId={c.subscriptionDetails?.biId || ''}\n cardLast4={c.subscriptionDetails?.cardLast4 || ''}\n trialStart={displayStart}\n trialEnd={displayEnd}\n priceToShow={\n c.selectedCycle === 'monthly'\n ? monthlyPrice?.label\n : annualPrice?.label\n }\n cycleToShow={\n c.selectedCycle === 'monthly' ? 'monthly' : 'annual'\n }\n courseLabel={courseLabel}\n onFindCourse={c.course ? handleStartCourse : undefined}\n />\n )}\n\n {c.phase === 'blocked' && (\n <BlockedScreen detail={c.lastComment} />\n )}\n </div>\n </Col>\n\n {/* ── RIGHT — swaps to EnrollmentSummary on success ── */}\n <Col xs={12} lg={5} xxl={3} className=\"payment__summary\">\n {c.phase === 'success' ? (\n <EnrollmentSummary\n course={c.course}\n onStartCourse={handleStartCourse}\n />\n ) : (\n <CartSummary\n monthlyRenewalLabel={getRenewalLabel(c.billingPlans, 'monthly')}\n annualRenewalLabel={getRenewalLabel(c.billingPlans, 'annual')}\n activeSubscriberCount={c.activeSubscriberCount}\n defaultCycle={c.selectedCycle}\n onCycleChange={c.setCycle}\n course={c.course}\n />\n )}\n </Col>\n </Row>\n </Col>\n </Row>\n );\n};\n\nexport default Checkout;\n"]}
@@ -0,0 +1,9 @@
1
+ import type { CheckoutProps } from '../Checkout/Checkout';
2
+ export interface CheckoutGateProps extends CheckoutProps {
3
+ /** URL to redirect already-subscribed users to. */
4
+ subscribedRedirectUrl?: string;
5
+ /** URL linked in the "not available in your country" message. */
6
+ learnerDashboardUrl?: string;
7
+ }
8
+ declare const CheckoutGate: ({ subscribedRedirectUrl, learnerDashboardUrl, ...checkoutProps }: CheckoutGateProps) => import("react/jsx-runtime").JSX.Element;
9
+ export default CheckoutGate;
@@ -0,0 +1,34 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import { Alert, Spinner } from '@openedx/paragon';
14
+ import { Error as ErrorIcon } from '@openedx/paragon/icons';
15
+ import { useCheckoutGate } from '../../data/hooks/useCheckoutGate';
16
+ import Checkout from '../Checkout/Checkout';
17
+ const CheckoutGate = (_a) => {
18
+ var { subscribedRedirectUrl, learnerDashboardUrl } = _a, checkoutProps = __rest(_a, ["subscribedRedirectUrl", "learnerDashboardUrl"]);
19
+ const { gateStatus, userCountry } = useCheckoutGate({
20
+ apiUrl: checkoutProps.apiUrl,
21
+ edxSessionUrl: checkoutProps.edxSessionUrl,
22
+ subscribedRedirectUrl,
23
+ learnerDashboardUrl,
24
+ });
25
+ if (gateStatus === 'loading') {
26
+ return (_jsx("div", { className: "d-flex justify-content-center align-items-center", style: { minHeight: '100vh' }, children: _jsx(Spinner, { animation: "border", screenReaderText: "Checking your account\u2026" }) }));
27
+ }
28
+ if (gateStatus === 'blocked') {
29
+ return (_jsxs(Alert, { variant: "danger", icon: ErrorIcon, children: ["Subscription is not available in your country.", ' ', learnerDashboardUrl && (_jsx("a", { href: learnerDashboardUrl, className: "alert-link", children: "Go to your learner dashboard" }))] }));
30
+ }
31
+ return _jsx(Checkout, Object.assign({}, checkoutProps, { userCountry: userCountry }));
32
+ };
33
+ export default CheckoutGate;
34
+ //# sourceMappingURL=CheckoutGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckoutGate.js","sourceRoot":"","sources":["../../../src/components/CheckoutGate/CheckoutGate.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,QAAQ,MAAM,sBAAsB,CAAC;AAU5C,MAAM,YAAY,GAAG,CAAC,EAIF,EAAE,EAAE;QAJF,EACpB,qBAAqB,EACrB,mBAAmB,OAED,EADf,aAAa,cAHI,gDAIrB,CADiB;IAEhB,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,eAAe,CAAC;QAClD,MAAM,EAAE,aAAa,CAAC,MAAM;QAC5B,aAAa,EAAE,aAAa,CAAC,aAAa;QAC1C,qBAAqB;QACrB,mBAAmB;KACpB,CAAC,CAAC;IAEH,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CACL,cACE,SAAS,EAAC,kDAAkD,EAC5D,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,YAE7B,KAAC,OAAO,IAAC,SAAS,EAAC,QAAQ,EAAC,gBAAgB,EAAC,6BAAwB,GAAG,GACpE,CACP,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CACL,MAAC,KAAK,IAAC,OAAO,EAAC,QAAQ,EAAC,IAAI,EAAE,SAAS,+DACU,GAAG,EACjD,mBAAmB,IAAI,CACtB,YAAG,IAAI,EAAE,mBAAmB,EAAE,SAAS,EAAC,YAAY,6CAEhD,CACL,IACK,CACT,CAAC;IACJ,CAAC;IAED,OAAO,KAAC,QAAQ,oBAAK,aAAa,IAAE,WAAW,EAAE,WAAW,IAAI,CAAC;AACnE,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import { Alert, Spinner } from '@openedx/paragon';\nimport { Error as ErrorIcon } from '@openedx/paragon/icons';\nimport { useCheckoutGate } from '../../data/hooks/useCheckoutGate';\nimport Checkout from '../Checkout/Checkout';\nimport type { CheckoutProps } from '../Checkout/Checkout';\n\nexport interface CheckoutGateProps extends CheckoutProps {\n /** URL to redirect already-subscribed users to. */\n subscribedRedirectUrl?: string,\n /** URL linked in the \"not available in your country\" message. */\n learnerDashboardUrl?: string,\n}\n\nconst CheckoutGate = ({\n subscribedRedirectUrl,\n learnerDashboardUrl,\n ...checkoutProps\n}: CheckoutGateProps) => {\n const { gateStatus, userCountry } = useCheckoutGate({\n apiUrl: checkoutProps.apiUrl,\n edxSessionUrl: checkoutProps.edxSessionUrl,\n subscribedRedirectUrl,\n learnerDashboardUrl,\n });\n\n if (gateStatus === 'loading') {\n return (\n <div\n className=\"d-flex justify-content-center align-items-center\"\n style={{ minHeight: '100vh' }}\n >\n <Spinner animation=\"border\" screenReaderText=\"Checking your account…\" />\n </div>\n );\n }\n\n if (gateStatus === 'blocked') {\n return (\n <Alert variant=\"danger\" icon={ErrorIcon}>\n Subscription is not available in your country.{' '}\n {learnerDashboardUrl && (\n <a href={learnerDashboardUrl} className=\"alert-link\">\n Go to your learner dashboard\n </a>\n )}\n </Alert>\n );\n }\n\n return <Checkout {...checkoutProps} userCountry={userCountry} />;\n};\n\nexport default CheckoutGate;\n"]}
@@ -0,0 +1,9 @@
1
+ import type { CourseDetail } from '../../types';
2
+ export type CourseEnrollmentCardVariant = 'checkout' | 'success';
3
+ export interface CourseEnrollmentCardProps {
4
+ course: CourseDetail;
5
+ variant?: CourseEnrollmentCardVariant;
6
+ onStartCourse?: () => void;
7
+ }
8
+ declare const CourseEnrollmentCard: ({ course, variant, onStartCourse, }: CourseEnrollmentCardProps) => import("react/jsx-runtime").JSX.Element;
9
+ export default CourseEnrollmentCard;
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from '@openedx/paragon';
3
+ import { useIntl } from '@openedx/frontend-base';
4
+ import messages from './Messages';
5
+ const CourseEnrollmentCard = ({ course, variant = 'checkout', onStartCourse, }) => {
6
+ var _a, _b;
7
+ const { formatMessage } = useIntl();
8
+ const brand = (_b = (_a = course.tBrandText) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
9
+ const courseName = course.maName;
10
+ const handleStartCourse = () => {
11
+ if (onStartCourse) {
12
+ onStartCourse();
13
+ return;
14
+ }
15
+ if (course.tUrlCourse) {
16
+ window.location.href = course.tUrlCourse;
17
+ }
18
+ };
19
+ const checkoutCopy = brand
20
+ ? formatMessage(messages.checkoutEnrollCopy, { brand, courseName })
21
+ : formatMessage(messages.checkoutEnrollCopyNoBrand, { courseName });
22
+ const successLabel = brand
23
+ ? formatMessage(messages.successCourseLabel, { brand, courseName })
24
+ : formatMessage(messages.successCourseLabelNoBrand, { courseName });
25
+ return (_jsx("div", { className: `course-enrollment-card course-enrollment-card--${variant}`, children: _jsxs("div", { className: "course-enrollment-card__body d-flex align-items-start", children: [_jsx("div", { className: "course-enrollment-card__image-wrap flex-shrink-0 mr-3", children: course.imageUrl ? (_jsx("img", { src: course.imageUrl, alt: formatMessage(messages.courseImageAlt, { courseName }), className: "course-enrollment-card__image" })) : (_jsx("div", { className: "course-enrollment-card__image course-enrollment-card__image--placeholder", "aria-hidden": "true" })) }), _jsx("div", { className: "course-enrollment-card__content flex-grow-1", children: variant === 'checkout' ? (_jsx("p", { className: "course-enrollment-card__copy mb-0 small", children: checkoutCopy })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "course-enrollment-card__copy font-weight-bold mb-2 small", children: successLabel }), _jsx(Button, { variant: "brand", size: "sm", className: "course-enrollment-card__cta", onClick: handleStartCourse, disabled: !course.tUrlCourse && !onStartCourse, children: formatMessage(messages.startCourse) })] })) })] }) }));
26
+ };
27
+ export default CourseEnrollmentCard;
28
+ //# sourceMappingURL=CourseEnrollmentCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CourseEnrollmentCard.js","sourceRoot":"","sources":["../../../src/components/CourseEnrollmentCard/CourseEnrollmentCard.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAUlC,MAAM,oBAAoB,GAAG,CAAC,EAC5B,MAAM,EACN,OAAO,GAAG,UAAU,EACpB,aAAa,GACa,EAAE,EAAE;;IAC9B,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,MAAA,MAAA,MAAM,CAAC,UAAU,0CAAE,IAAI,EAAE,mCAAI,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IAEjC,MAAM,iBAAiB,GAAG,GAAG,EAAE;QAC7B,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;QAC3C,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK;QACxB,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QACnE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAEtE,MAAM,YAAY,GAAG,KAAK;QACxB,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QACnE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAEtE,OAAO,CACL,cAAK,SAAS,EAAE,kDAAkD,OAAO,EAAE,YACzE,eAAK,SAAS,EAAC,uDAAuD,aACpE,cAAK,SAAS,EAAC,uDAAuD,YACnE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CACjB,cACE,GAAG,EAAE,MAAM,CAAC,QAAQ,EACpB,GAAG,EAAE,aAAa,CAAC,QAAQ,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,CAAC,EAC3D,SAAS,EAAC,+BAA+B,GACzC,CACH,CAAC,CAAC,CAAC,CACF,cACE,SAAS,EAAC,0EAA0E,iBACxE,MAAM,GAClB,CACH,GACG,EAEN,cAAK,SAAS,EAAC,6CAA6C,YACzD,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,CACxB,YAAG,SAAS,EAAC,yCAAyC,YACnD,YAAY,GACX,CACL,CAAC,CAAC,CAAC,CACF,8BACE,YAAG,SAAS,EAAC,0DAA0D,YACpE,YAAY,GACX,EACJ,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,6BAA6B,EACvC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,aAAa,YAE7C,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAC7B,IACR,CACJ,GACG,IACF,GACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,oBAAoB,CAAC","sourcesContent":["import React from 'react';\nimport { Button } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport type { CourseDetail } from '../../types';\nimport messages from './Messages';\n\nexport type CourseEnrollmentCardVariant = 'checkout' | 'success';\n\nexport interface CourseEnrollmentCardProps {\n course: CourseDetail,\n variant?: CourseEnrollmentCardVariant,\n onStartCourse?: () => void,\n}\n\nconst CourseEnrollmentCard = ({\n course,\n variant = 'checkout',\n onStartCourse,\n}: CourseEnrollmentCardProps) => {\n const { formatMessage } = useIntl();\n const brand = course.tBrandText?.trim() ?? '';\n const courseName = course.maName;\n\n const handleStartCourse = () => {\n if (onStartCourse) {\n onStartCourse();\n return;\n }\n if (course.tUrlCourse) {\n window.location.href = course.tUrlCourse;\n }\n };\n\n const checkoutCopy = brand\n ? formatMessage(messages.checkoutEnrollCopy, { brand, courseName })\n : formatMessage(messages.checkoutEnrollCopyNoBrand, { courseName });\n\n const successLabel = brand\n ? formatMessage(messages.successCourseLabel, { brand, courseName })\n : formatMessage(messages.successCourseLabelNoBrand, { courseName });\n\n return (\n <div className={`course-enrollment-card course-enrollment-card--${variant}`}>\n <div className=\"course-enrollment-card__body d-flex align-items-start\">\n <div className=\"course-enrollment-card__image-wrap flex-shrink-0 mr-3\">\n {course.imageUrl ? (\n <img\n src={course.imageUrl}\n alt={formatMessage(messages.courseImageAlt, { courseName })}\n className=\"course-enrollment-card__image\"\n />\n ) : (\n <div\n className=\"course-enrollment-card__image course-enrollment-card__image--placeholder\"\n aria-hidden=\"true\"\n />\n )}\n </div>\n\n <div className=\"course-enrollment-card__content flex-grow-1\">\n {variant === 'checkout' ? (\n <p className=\"course-enrollment-card__copy mb-0 small\">\n {checkoutCopy}\n </p>\n ) : (\n <>\n <p className=\"course-enrollment-card__copy font-weight-bold mb-2 small\">\n {successLabel}\n </p>\n <Button\n variant=\"brand\"\n size=\"sm\"\n className=\"course-enrollment-card__cta\"\n onClick={handleStartCourse}\n disabled={!course.tUrlCourse && !onStartCourse}\n >\n {formatMessage(messages.startCourse)}\n </Button>\n </>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default CourseEnrollmentCard;\n"]}
@@ -0,0 +1,33 @@
1
+ declare const messages: {
2
+ checkoutEnrollCopy: {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ checkoutEnrollCopyNoBrand: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ description: string;
11
+ };
12
+ successCourseLabel: {
13
+ id: string;
14
+ defaultMessage: string;
15
+ description: string;
16
+ };
17
+ successCourseLabelNoBrand: {
18
+ id: string;
19
+ defaultMessage: string;
20
+ description: string;
21
+ };
22
+ startCourse: {
23
+ id: string;
24
+ defaultMessage: string;
25
+ description: string;
26
+ };
27
+ courseImageAlt: {
28
+ id: string;
29
+ defaultMessage: string;
30
+ description: string;
31
+ };
32
+ };
33
+ export default messages;