@edx/frontend-app-subscription-checkout 1.3.0 → 1.5.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/app.js +6 -3
- package/dist/app.js.map +1 -1
- package/dist/checkoutPage/CheckoutPage.js +2 -1
- package/dist/checkoutPage/CheckoutPage.js.map +1 -1
- package/dist/components/CartSummary/CartSummary.d.ts +7 -2
- package/dist/components/CartSummary/CartSummary.js +16 -15
- package/dist/components/CartSummary/CartSummary.js.map +1 -1
- package/dist/components/Checkout/Checkout.d.ts +6 -1
- package/dist/components/Checkout/Checkout.js +25 -4
- package/dist/components/Checkout/Checkout.js.map +1 -1
- package/dist/components/EnrollmentSummary/EnrollmentSummary.d.ts +3 -2
- package/dist/components/EnrollmentSummary/EnrollmentSummary.js +5 -3
- package/dist/components/EnrollmentSummary/EnrollmentSummary.js.map +1 -1
- package/dist/components/EnrollmentSummary/Messages.js +2 -2
- package/dist/components/EnrollmentSummary/Messages.js.map +1 -1
- package/dist/components/PaymentForm/PaymentForm.js +4 -3
- package/dist/components/PaymentForm/PaymentForm.js.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +201 -196
- package/dist/constants.js.map +1 -1
- package/dist/data/hooks/useCheckout.js +65 -15
- package/dist/data/hooks/useCheckout.js.map +1 -1
- package/dist/data/hooks/useCheckoutMutations.d.ts +3 -1
- package/dist/data/hooks/useCheckoutMutations.js +7 -4
- package/dist/data/hooks/useCheckoutMutations.js.map +1 -1
- package/dist/styles/components/paymentForm.scss +10 -0
- package/dist/utils/billingDetails.d.ts +1 -1
- package/dist/utils/billingDetails.js +6 -5
- package/dist/utils/billingDetails.js.map +1 -1
- package/dist/utils/cartApi.js +11 -9
- package/dist/utils/cartApi.js.map +1 -1
- package/dist/utils/provision.js +2 -2
- package/dist/utils/provision.js.map +1 -1
- package/dist/utils/queries.d.ts +1 -1
- package/dist/utils/queries.js +0 -2
- package/dist/utils/queries.js.map +1 -1
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -5,9 +5,12 @@ const app = {
|
|
|
5
5
|
appId,
|
|
6
6
|
routes,
|
|
7
7
|
slots,
|
|
8
|
-
// Environment-specific values (STRIPE_PUBLIC_KEY, VIAX_API_URL
|
|
9
|
-
// by site.config.{dev,stage,prod}.tsx
|
|
10
|
-
|
|
8
|
+
// Environment-specific values (STRIPE_PUBLIC_KEY, VIAX_API_URL,
|
|
9
|
+
// ENABLE_ANNUAL_BILLING) are supplied by site.config.{dev,stage,prod}.tsx
|
|
10
|
+
// at site build time.
|
|
11
|
+
config: {
|
|
12
|
+
ENABLE_ANNUAL_BILLING: false,
|
|
13
|
+
},
|
|
11
14
|
};
|
|
12
15
|
export default app;
|
|
13
16
|
//# 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;IACL,
|
|
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,gEAAgE;IAChE,0EAA0E;IAC1E,sBAAsB;IACtB,MAAM,EAAE;QACN,qBAAqB,EAAE,KAAK;KAC7B;CACF,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,\n // ENABLE_ANNUAL_BILLING) are supplied by site.config.{dev,stage,prod}.tsx\n // at site build time.\n config: {\n ENABLE_ANNUAL_BILLING: false,\n },\n};\n\nexport default app;\n"]}
|
|
@@ -10,6 +10,7 @@ const CheckoutPage = () => {
|
|
|
10
10
|
const LMS_BASE_URL = siteConfig.lmsBaseUrl.replace(/\/$/, '');
|
|
11
11
|
const stripePublishableKey = config.STRIPE_PUBLIC_KEY;
|
|
12
12
|
const apiUrl = config.VIAX_API_URL;
|
|
13
|
+
const enableAnnualBilling = Boolean(config.ENABLE_ANNUAL_BILLING);
|
|
13
14
|
const isDevelopment = siteConfig.environment === 'development';
|
|
14
15
|
const edxSessionUrl = `${isDevelopment ? 'https://courses.stage.edx.org' : LMS_BASE_URL}/api/edx-session`;
|
|
15
16
|
console.log('siteConfig ===> ', siteConfig);
|
|
@@ -20,7 +21,7 @@ const CheckoutPage = () => {
|
|
|
20
21
|
if (!stripePublishableKey || !apiUrl || !edxSessionUrl) {
|
|
21
22
|
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" }), "."] }) }));
|
|
22
23
|
}
|
|
23
|
-
return (_jsx(PageWrapper, { children: _jsx(CheckoutGate, { stripePublishableKey: stripePublishableKey, apiUrl: apiUrl, edxSessionUrl: edxSessionUrl, learnerDashboardUrl: `${LMS_BASE_URL}/dashboard`, homeUrl: LMS_BASE_URL || '/', onComplete: (_subscriptionBiId) => {
|
|
24
|
+
return (_jsx(PageWrapper, { children: _jsx(CheckoutGate, { stripePublishableKey: stripePublishableKey, apiUrl: apiUrl, edxSessionUrl: edxSessionUrl, enableAnnualBilling: enableAnnualBilling, learnerDashboardUrl: `${LMS_BASE_URL}/dashboard`, homeUrl: LMS_BASE_URL || '/', onComplete: (_subscriptionBiId) => {
|
|
24
25
|
console.log(_subscriptionBiId);
|
|
25
26
|
// window.location.href = `/checkout/confirmation?sub=${_subscriptionBiId ?? ''}`;
|
|
26
27
|
// Success screen.
|
|
@@ -1 +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,UAAU,CAAC,WAAW,KAAK,aAAa,CAAC;IAC/D,MAAM,aAAa,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,YAAY,kBAAkB,CAAC;IAE1G,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,oBAAoB,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,aAAa,CAAC,CAAC;IAElD,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,mBAAmB,EAAE,GAAG,YAAY,YAAY,EAChD,OAAO,EAAE,YAAY,IAAI,GAAG,EAC5B,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 isDevelopment = siteConfig.environment === 'development';\n const edxSessionUrl = `${isDevelopment ? 'https://courses.stage.edx.org' : LMS_BASE_URL}/api/edx-session`;\n\n console.log('siteConfig ===> ', siteConfig);\n console.log('config ====> ', config);\n console.log('stripePublishableKey ===> ', stripePublishableKey);\n console.log('apiURL ==> ', apiUrl);\n console.log('edxSessionUrl ===> ', edxSessionUrl);\n\n if (!stripePublishableKey || !apiUrl || !edxSessionUrl) {\n return (\n <PageWrapper>\n <Alert variant=\"danger\">\n We'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 learnerDashboardUrl={`${LMS_BASE_URL}/dashboard`}\n homeUrl={LMS_BASE_URL || '/'}\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"]}
|
|
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,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,UAAU,CAAC,WAAW,KAAK,aAAa,CAAC;IAC/D,MAAM,aAAa,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,YAAY,kBAAkB,CAAC;IAE1G,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,oBAAoB,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,aAAa,CAAC,CAAC;IAElD,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,mBAAmB,EAAE,mBAAmB,EACxC,mBAAmB,EAAE,GAAG,YAAY,YAAY,EAChD,OAAO,EAAE,YAAY,IAAI,GAAG,EAC5B,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 enableAnnualBilling = Boolean(config.ENABLE_ANNUAL_BILLING);\n const isDevelopment = siteConfig.environment === 'development';\n const edxSessionUrl = `${isDevelopment ? 'https://courses.stage.edx.org' : LMS_BASE_URL}/api/edx-session`;\n\n console.log('siteConfig ===> ', siteConfig);\n console.log('config ====> ', config);\n console.log('stripePublishableKey ===> ', stripePublishableKey);\n console.log('apiURL ==> ', apiUrl);\n console.log('edxSessionUrl ===> ', edxSessionUrl);\n\n if (!stripePublishableKey || !apiUrl || !edxSessionUrl) {\n return (\n <PageWrapper>\n <Alert variant=\"danger\">\n We'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 enableAnnualBilling={enableAnnualBilling}\n learnerDashboardUrl={`${LMS_BASE_URL}/dashboard`}\n homeUrl={LMS_BASE_URL || '/'}\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"]}
|
|
@@ -16,11 +16,16 @@ export interface CartSummaryProps {
|
|
|
16
16
|
defaultCycle?: BillingCycle;
|
|
17
17
|
monthlyRenewalLabel?: string;
|
|
18
18
|
annualRenewalLabel?: string;
|
|
19
|
-
/**
|
|
19
|
+
/** Called when the learner switches monthly ↔ annual (requires enableAnnualBilling). */
|
|
20
20
|
onCycleChange?: (cycle: BillingCycle) => void;
|
|
21
|
+
/**
|
|
22
|
+
* When true, shows the Switch to annual/monthly control.
|
|
23
|
+
* Controlled via ENABLE_ANNUAL_BILLING in site.config.*.tsx.
|
|
24
|
+
*/
|
|
25
|
+
enableAnnualBilling?: boolean;
|
|
21
26
|
learnerCount?: number;
|
|
22
27
|
/** When set, shows the course enrollment preview card below the summary card. */
|
|
23
28
|
course?: CourseDetail | null;
|
|
24
29
|
}
|
|
25
|
-
declare const CartSummary: ({ productTitle, productBlurb, monthlyAmount, monthlyRegularAmount, promoMonths, annualAmount, currency, activeSubscriberCount, defaultCycle, learnerCount: learnerCountProp, course, }: CartSummaryProps) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
declare const CartSummary: ({ productTitle, productBlurb, monthlyAmount, monthlyRegularAmount, promoMonths, annualAmount, currency, activeSubscriberCount, defaultCycle, onCycleChange, enableAnnualBilling, learnerCount: learnerCountProp, course, }: CartSummaryProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
31
|
export default CartSummary;
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Badge, Card, Icon } from '@openedx/paragon';
|
|
2
|
+
import { Badge, Button, Card, Icon } from '@openedx/paragon';
|
|
3
3
|
import { Group, People, Institution } from '@openedx/paragon/icons';
|
|
4
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
5
5
|
import { EdxUnlimitedLogo } from '../BrandMarks/BrandMarks';
|
|
6
6
|
import CourseEnrollmentCard from '../CourseEnrollmentCard/CourseEnrollmentCard';
|
|
7
7
|
import messages from './Messages';
|
|
8
|
-
const CartSummary = ({ productTitle = 'edX Subscription', productBlurb = 'Subscribe and get access to hundreds of courses and programs.', monthlyAmount = '39', monthlyRegularAmount = '59', promoMonths = 3, annualAmount = '299', currency = 'USD', activeSubscriberCount, defaultCycle = 'monthly', learnerCount: learnerCountProp = 2203, course = null, }) => {
|
|
8
|
+
const CartSummary = ({ productTitle = 'edX Subscription', productBlurb = 'Subscribe and get access to hundreds of courses and programs.', monthlyAmount = '39', monthlyRegularAmount = '59', promoMonths = 3, annualAmount = '299', currency = 'USD', activeSubscriberCount, defaultCycle = 'monthly', onCycleChange, enableAnnualBilling = false, learnerCount: learnerCountProp = 2203, course = null, }) => {
|
|
9
9
|
const { formatMessage } = useIntl();
|
|
10
10
|
const isMonthly = defaultCycle === 'monthly';
|
|
11
|
+
const showCycleToggle = enableAnnualBilling && !!onCycleChange;
|
|
11
12
|
const learnerCount = (activeSubscriberCount != null ? activeSubscriberCount : learnerCountProp).toLocaleString();
|
|
12
13
|
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, {
|
|
13
14
|
count: learnerCount,
|
|
14
|
-
})] })] }), _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, {}),
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
})] })] }), _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-start mb-1", children: [_jsx("span", { className: "small text-gray-900", children: isMonthly
|
|
16
|
+
? formatMessage(messages.monthlySubscription)
|
|
17
|
+
: formatMessage(messages.annualSubscription) }), _jsxs("div", { className: "cart-summary__pricing text-right", children: [_jsx("div", { className: "text-success font-weight-bold small", children: formatMessage(messages.trialLabel) }), isMonthly ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "small text-gray-900 font-weight-bold", children: formatMessage(messages.promotionalPrice, {
|
|
18
|
+
amount: monthlyAmount,
|
|
19
|
+
months: promoMonths,
|
|
20
|
+
}) }), _jsx("div", { className: "small text-gray-900 font-weight-bold", children: formatMessage(messages.regularPrice, {
|
|
21
|
+
amount: monthlyRegularAmount,
|
|
22
|
+
currency,
|
|
23
|
+
}) })] })) : (_jsx("div", { className: "small text-gray-900 font-weight-bold", children: formatMessage(messages.priceDisplay, {
|
|
24
|
+
amount: annualAmount,
|
|
25
|
+
frequency: 'year',
|
|
26
|
+
currency,
|
|
27
|
+
}) }))] })] }), showCycleToggle && (_jsx("div", { className: "mt-2", children: _jsx(Button, { variant: "link", className: "cart-summary__cycle-toggle p-0", onClick: () => onCycleChange === null || onCycleChange === void 0 ? void 0 : onCycleChange(isMonthly ? 'annual' : 'monthly'), children: formatMessage(isMonthly ? messages.switchToAnnual : messages.switchToMonthly) }) }))] }), _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) })] })] })] })] }));
|
|
27
28
|
};
|
|
28
29
|
export default CartSummary;
|
|
29
30
|
//# sourceMappingURL=CartSummary.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartSummary.js","sourceRoot":"","sources":["../../../src/components/CartSummary/CartSummary.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,oBAAoB,MAAM,8CAA8C,CAAC;AAEhF,OAAO,QAAQ,MAAM,YAAY,CAAC;AA2BlC,MAAM,WAAW,GAAG,CAAC,EACnB,YAAY,GAAG,kBAAkB,EACjC,YAAY,GAAG,+DAA+D,EAC9E,aAAa,GAAG,IAAI,EACpB,oBAAoB,GAAG,IAAI,EAC3B,WAAW,GAAG,CAAC,EACf,YAAY,GAAG,KAAK,EACpB,QAAQ,GAAG,KAAK,EAChB,qBAAqB,EACrB,YAAY,GAAG,SAAS,EACxB,YAAY,EAAE,gBAAgB,GAAG,IAAI,EACrC,MAAM,GAAG,IAAI,GACI,EAAE,EAAE;IACrB,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,YAAY,KAAK,SAAS,CAAC;IAE7C,MAAM,YAAY,GAAG,CACnB,qBAAqB,IAAI,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,gBAAgB,CACzE,CAAC,cAAc,EAAE,CAAC;IAEnB,OAAO,CACL,eAAK,SAAS,EAAC,eAAe,aAC5B,MAAC,IAAI,IAAC,SAAS,EAAC,wBAAwB,aACtC,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,4DAA4D,aAClF,eAAM,SAAS,EAAC,gCAAgC,YAC7C,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,GAClC,EACP,MAAC,KAAK,IACJ,OAAO,EAAC,OAAO,EACf,SAAS,EAAC,qCAAqC,aAE/C,KAAC,IAAI,IACH,GAAG,EAAE,KAAK,EACV,SAAS,EAAC,MAAM,EAChB,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GACxC,EACD,aAAa,CAAC,QAAQ,CAAC,kBAAkB,EAAE;wCAC1C,KAAK,EAAE,YAAY;qCACpB,CAAC,IACI,IACK,EAEf,KAAC,IAAI,CAAC,OAAO,KAAG,EAEhB,KAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,UAAU,YAChC,eAAK,SAAS,EAAC,0BAA0B,aACvC,KAAC,gBAAgB,KAAG,EACpB,0BACE,YAAG,SAAS,EAAC,wCAAwC,YAClD,YAAY,GACX,EACJ,YAAG,SAAS,EAAC,0BAA0B,YAAE,YAAY,GAAK,IACtD,IACF,GACO,EAEf,KAAC,IAAI,CAAC,OAAO,KAAG,EAEhB,KAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,UAAU,YAChC,eAAK,SAAS,EAAC,uDAAuD,aACpE,eAAM,SAAS,EAAC,qBAAqB,YAClC,SAAS;wCACR,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC;wCAC7C,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GACzC,EACP,eAAK,SAAS,EAAC,kCAAkC,aAC/C,cAAK,SAAS,EAAC,qCAAqC,YACjD,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,GAC/B,EACL,SAAS,CAAC,CAAC,CAAC,CACX,8BACE,cAAK,SAAS,EAAC,sCAAsC,YAClD,aAAa,CAAC,QAAQ,CAAC,gBAAgB,EAAE;wDACxC,MAAM,EAAE,aAAa;wDACrB,MAAM,EAAE,WAAW;qDACpB,CAAC,GACE,EACN,cAAK,SAAS,EAAC,sCAAsC,YAClD,aAAa,CAAC,QAAQ,CAAC,YAAY,EAAE;wDACpC,MAAM,EAAE,oBAAoB;wDAC5B,QAAQ;qDACT,CAAC,GACE,IACL,CACJ,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,sCAAsC,YAClD,aAAa,CAAC,QAAQ,CAAC,YAAY,EAAE;gDACpC,MAAM,EAAE,YAAY;gDACpB,SAAS,EAAE,MAAM;gDACjB,QAAQ;6CACT,CAAC,GACE,CACP,IACG,IACF,GACO,EAEf,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,wDAAwD,aAC9E,eAAM,SAAS,EAAC,gCAAgC,YAC7C,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAC/B,EACP,eAAM,SAAS,EAAC,qCAAqC,YAClD,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GACpC,IACM,IACV,EAEN,MAAM,IAAI,CACT,KAAC,oBAAoB,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAC,UAAU,GAAG,CAC5D,EAGD,eAAK,SAAS,EAAC,2CAA2C,aACxD,eAAK,SAAS,EAAC,mDAAmD,aAChE,KAAC,IAAI,IACH,GAAG,EAAE,MAAM,EACX,SAAS,EAAC,iBAAiB,EAC3B,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAC5C,EACF,0BACE,YAAG,SAAS,EAAC,uBAAuB,YACjC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,GACpC,EACJ,YAAG,SAAS,EAAC,uBAAuB,YACjC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,GACpC,IACA,IACF,EACN,eAAK,SAAS,EAAC,8CAA8C,aAC3D,KAAC,IAAI,IACH,GAAG,EAAE,WAAW,EAChB,SAAS,EAAC,iBAAiB,EAC3B,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAC5C,EACF,0BACE,YAAG,SAAS,EAAC,uBAAuB,YACjC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GACxC,EACJ,YAAG,SAAS,EAAC,uBAAuB,YACjC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GACxC,IACA,IACF,IACF,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,WAAW,CAAC","sourcesContent":["import React 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 /** Promotional monthly price amount e.g. \"39\" */\n monthlyAmount?: string,\n /** Regular monthly price after the promo period e.g. \"59\" */\n monthlyRegularAmount?: string,\n /** Length of the promotional period in months */\n promoMonths?: number,\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 /** Reserved for re-enabling the annual/monthly cycle toggle. */\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 monthlyRegularAmount = '59',\n promoMonths = 3,\n annualAmount = '299',\n currency = 'USD',\n activeSubscriberCount,\n defaultCycle = 'monthly',\n learnerCount: learnerCountProp = 2203,\n course = null,\n}: CartSummaryProps) => {\n const { formatMessage } = useIntl();\n const isMonthly = defaultCycle === 'monthly';\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-start mb-1\">\n <span className=\"small text-gray-900\">\n {isMonthly\n ? formatMessage(messages.monthlySubscription)\n : formatMessage(messages.annualSubscription)}\n </span>\n <div className=\"cart-summary__pricing text-right\">\n <div className=\"text-success font-weight-bold small\">\n {formatMessage(messages.trialLabel)}\n </div>\n {isMonthly ? (\n <>\n <div className=\"small text-gray-900 font-weight-bold\">\n {formatMessage(messages.promotionalPrice, {\n amount: monthlyAmount,\n months: promoMonths,\n })}\n </div>\n <div className=\"small text-gray-900 font-weight-bold\">\n {formatMessage(messages.regularPrice, {\n amount: monthlyRegularAmount,\n currency,\n })}\n </div>\n </>\n ) : (\n <div className=\"small text-gray-900 font-weight-bold\">\n {formatMessage(messages.priceDisplay, {\n amount: annualAmount,\n frequency: 'year',\n currency,\n })}\n </div>\n )}\n </div>\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"]}
|
|
1
|
+
{"version":3,"file":"CartSummary.js","sourceRoot":"","sources":["../../../src/components/CartSummary/CartSummary.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Badge, Button, 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 /** Promotional monthly price amount e.g. \"39\" */\n monthlyAmount?: string,\n /** Regular monthly price after the promo period e.g. \"59\" */\n monthlyRegularAmount?: string,\n /** Length of the promotional period in months */\n promoMonths?: number,\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 /** Called when the learner switches monthly ↔ annual (requires enableAnnualBilling). */\n onCycleChange?: (cycle: BillingCycle) => void,\n /**\n * When true, shows the Switch to annual/monthly control.\n * Controlled via ENABLE_ANNUAL_BILLING in site.config.*.tsx.\n */\n enableAnnualBilling?: boolean,\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 monthlyRegularAmount = '59',\n promoMonths = 3,\n annualAmount = '299',\n currency = 'USD',\n activeSubscriberCount,\n defaultCycle = 'monthly',\n onCycleChange,\n enableAnnualBilling = false,\n learnerCount: learnerCountProp = 2203,\n course = null,\n}: CartSummaryProps) => {\n const { formatMessage } = useIntl();\n const isMonthly = defaultCycle === 'monthly';\n const showCycleToggle = enableAnnualBilling && !!onCycleChange;\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-start mb-1\">\n <span className=\"small text-gray-900\">\n {isMonthly\n ? formatMessage(messages.monthlySubscription)\n : formatMessage(messages.annualSubscription)}\n </span>\n <div className=\"cart-summary__pricing text-right\">\n <div className=\"text-success font-weight-bold small\">\n {formatMessage(messages.trialLabel)}\n </div>\n {isMonthly ? (\n <>\n <div className=\"small text-gray-900 font-weight-bold\">\n {formatMessage(messages.promotionalPrice, {\n amount: monthlyAmount,\n months: promoMonths,\n })}\n </div>\n <div className=\"small text-gray-900 font-weight-bold\">\n {formatMessage(messages.regularPrice, {\n amount: monthlyRegularAmount,\n currency,\n })}\n </div>\n </>\n ) : (\n <div className=\"small text-gray-900 font-weight-bold\">\n {formatMessage(messages.priceDisplay, {\n amount: annualAmount,\n frequency: 'year',\n currency,\n })}\n </div>\n )}\n </div>\n </div>\n {showCycleToggle && (\n <div className=\"mt-2\">\n <Button\n variant=\"link\"\n className=\"cart-summary__cycle-toggle p-0\"\n onClick={() => onCycleChange?.(isMonthly ? 'annual' : 'monthly')}\n >\n {formatMessage(\n isMonthly ? messages.switchToAnnual : messages.switchToMonthly,\n )}\n </Button>\n </div>\n )}\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"]}
|
|
@@ -2,6 +2,11 @@ import type { UseCheckoutOptions } from '../../data/hooks/useCheckout';
|
|
|
2
2
|
export type CheckoutProps = UseCheckoutOptions & {
|
|
3
3
|
/** Homepage URL for the country-unavailable modal CTA. */
|
|
4
4
|
homeUrl?: string;
|
|
5
|
+
/**
|
|
6
|
+
* When true, learners can switch between monthly and annual billing.
|
|
7
|
+
* Sourced from ENABLE_ANNUAL_BILLING in site.config.*.tsx.
|
|
8
|
+
*/
|
|
9
|
+
enableAnnualBilling?: boolean;
|
|
5
10
|
};
|
|
6
|
-
declare const Checkout: ({ homeUrl, ...props }: CheckoutProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
declare const Checkout: ({ homeUrl, enableAnnualBilling, ...props }: CheckoutProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
12
|
export default Checkout;
|
|
@@ -10,6 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { useEffect } from 'react';
|
|
13
14
|
import { Alert, Col, Row } from '@openedx/paragon';
|
|
14
15
|
import { Error as ErrorIcon } from '@openedx/paragon/icons';
|
|
15
16
|
import useCheckout from '../../data/hooks/useCheckout';
|
|
@@ -21,10 +22,24 @@ import CountryUnavailableModal from '../CountryUnavailableModal/CountryUnavailab
|
|
|
21
22
|
import { getPlanPrice, getRenewalLabel } from '../../utils/billingDetails';
|
|
22
23
|
import { getTrialDateRange } from '../../utils';
|
|
23
24
|
import { SuccessScreen, BlockedScreen } from '../StatusScreens/StatusScreens';
|
|
25
|
+
/** Resolve purchased cycle from subscription details, falling back to checkout selection. */
|
|
26
|
+
function resolvePurchasedCycle(selectedCycle, planName, renewalType) {
|
|
27
|
+
const haystack = `${planName !== null && planName !== void 0 ? planName : ''} ${renewalType !== null && renewalType !== void 0 ? renewalType : ''}`.toLowerCase();
|
|
28
|
+
if (haystack.includes('annual') || haystack.includes('year'))
|
|
29
|
+
return 'annual';
|
|
30
|
+
if (haystack.includes('month'))
|
|
31
|
+
return 'monthly';
|
|
32
|
+
return selectedCycle;
|
|
33
|
+
}
|
|
24
34
|
const Checkout = (_a) => {
|
|
25
|
-
var _b, _c, _d;
|
|
26
|
-
var { homeUrl = '/' } = _a, props = __rest(_a, ["homeUrl"]);
|
|
35
|
+
var _b, _c, _d, _e, _f;
|
|
36
|
+
var { homeUrl = '/', enableAnnualBilling = false } = _a, props = __rest(_a, ["homeUrl", "enableAnnualBilling"]);
|
|
27
37
|
const c = useCheckout(props);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (!enableAnnualBilling && c.selectedCycle !== 'monthly') {
|
|
40
|
+
c.setCycle('monthly');
|
|
41
|
+
}
|
|
42
|
+
}, [enableAnnualBilling, c.selectedCycle, c.setCycle]);
|
|
28
43
|
const showForm = c.phase === 'init'
|
|
29
44
|
|| c.phase === 'ready'
|
|
30
45
|
|| c.phase === 'failed'
|
|
@@ -36,6 +51,12 @@ const Checkout = (_a) => {
|
|
|
36
51
|
const isBillingCountryBlocked = GATE_CHECK_COUNTRY
|
|
37
52
|
&& !!c.billing.country
|
|
38
53
|
&& !ALLOWED_CHECKOUT_COUNTRIES.includes(c.billing.country);
|
|
54
|
+
// Keep annual selection only when the feature flag is on.
|
|
55
|
+
const selectedCycle = enableAnnualBilling
|
|
56
|
+
? c.selectedCycle
|
|
57
|
+
: 'monthly';
|
|
58
|
+
const purchasedCycle = resolvePurchasedCycle(selectedCycle, (_b = c.subscriptionDetails) === null || _b === void 0 ? void 0 : _b.planName, (_c = c.subscriptionDetails) === null || _c === void 0 ? void 0 : _c.renewalType);
|
|
59
|
+
const purchasedPrice = getPlanPrice(c.billingPlans, purchasedCycle);
|
|
39
60
|
const handleStartCourse = () => {
|
|
40
61
|
var _a;
|
|
41
62
|
if ((_a = c.course) === null || _a === void 0 ? void 0 : _a.tUrlCourse) {
|
|
@@ -49,9 +70,9 @@ const Checkout = (_a) => {
|
|
|
49
70
|
? [c.course.tBrandText, c.course.maName].filter(Boolean).join(': ')
|
|
50
71
|
: null;
|
|
51
72
|
return (_jsxs(Row, { className: "checkout__container bg-light-200", children: [_jsx(CountryUnavailableModal, { isOpen: isBillingCountryBlocked, homeUrl: homeUrl }), _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
|
|
52
|
-
|| '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:
|
|
73
|
+
|| '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: selectedCycle === 'monthly' ? monthlyPrice : annualPrice, cycleToShow: selectedCycle === 'monthly' ? 'monthly' : 'annual', userCountry: c.userCountry })] })), c.phase === 'success' && (_jsx(SuccessScreen, { subscriptionBiId: ((_d = c.subscriptionDetails) === null || _d === void 0 ? void 0 : _d.biId) || '', cardLast4: ((_e = c.subscriptionDetails) === null || _e === void 0 ? void 0 : _e.cardLast4) || '', purchaseDate: displayStart, trialStart: displayStart, trialEnd: displayEnd, priceToShow: purchasedCycle === 'monthly'
|
|
53
74
|
? monthlyPrice === null || monthlyPrice === void 0 ? void 0 : monthlyPrice.label
|
|
54
|
-
: annualPrice === null || annualPrice === void 0 ? void 0 : annualPrice.label, cycleToShow:
|
|
75
|
+
: annualPrice === null || annualPrice === void 0 ? void 0 : annualPrice.label, cycleToShow: purchasedCycle === 'monthly' ? 'monthly' : 'annual', courseLabel: courseLabel, onFindCourse: handleStartCourse })), 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, { amount: purchasedPrice === null || purchasedPrice === void 0 ? void 0 : purchasedPrice.amount, currency: purchasedPrice === null || purchasedPrice === void 0 ? void 0 : purchasedPrice.currency, cycleToShow: purchasedCycle, course: c.course, onStartCourse: handleStartCourse })) : (_jsx(CartSummary, { monthlyRegularAmount: monthlyPrice === null || monthlyPrice === void 0 ? void 0 : monthlyPrice.amount, annualAmount: annualPrice === null || annualPrice === void 0 ? void 0 : annualPrice.amount, currency: (_f = monthlyPrice === null || monthlyPrice === void 0 ? void 0 : monthlyPrice.currency) !== null && _f !== void 0 ? _f : annualPrice === null || annualPrice === void 0 ? void 0 : annualPrice.currency, monthlyRenewalLabel: getRenewalLabel(c.billingPlans, 'monthly'), annualRenewalLabel: getRenewalLabel(c.billingPlans, 'annual'), activeSubscriberCount: c.activeSubscriberCount, defaultCycle: selectedCycle, onCycleChange: c.setCycle, enableAnnualBilling: enableAnnualBilling, course: c.course })) })] }) })] }));
|
|
55
76
|
};
|
|
56
77
|
export default Checkout;
|
|
57
78
|
//# sourceMappingURL=Checkout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkout.js","sourceRoot":"","sources":["../../../src/components/Checkout/Checkout.tsx"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,WAAW,MAAM,8BAA8B,CAAC;AAEvD,OAAO,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,WAAW,MAAM,4BAA4B,CAAC;AACrD,OAAO,iBAAiB,MAAM,wCAAwC,CAAC;AACvE,OAAO,WAAW,MAAM,4BAA4B,CAAC;AACrD,OAAO,uBAAuB,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAO9E,MAAM,QAAQ,GAAG,CAAC,EAA0C,EAAE,EAAE;;QAA9C,EAAE,OAAO,GAAG,GAAG,OAA2B,EAAtB,KAAK,cAAzB,WAA2B,CAAF;IACzC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAE7B,MAAM,QAAQ,GACV,CAAC,CAAC,KAAK,KAAK,MAAM;WACf,CAAC,CAAC,KAAK,KAAK,OAAO;WACnB,CAAC,CAAC,KAAK,KAAK,QAAQ;WACpB,CAAC,CAAC,KAAK,KAAK,YAAY,CAAC;IAChC,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,CAAC,CAAC,sBAAsB,CAAC;IAE9C,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAEzD,MAAM,uBAAuB,GAAG,kBAAkB;WAC7C,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO;WACnB,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7D,MAAM,iBAAiB,GAAG,GAAG,EAAE;;QAC7B,IAAI,MAAA,CAAC,CAAC,MAAM,0CAAE,UAAU,EAAE,CAAC;YACzB,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,sBAAsB,CAAC;QAChD,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM;QAC1B,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACnE,CAAC,CAAC,IAAI,CAAC;IAET,OAAO,CACL,MAAC,GAAG,IAAC,SAAS,EAAC,kCAAkC,aAC/C,KAAC,uBAAuB,IACtB,MAAM,EAAE,uBAAuB,EAC/B,OAAO,EAAE,OAAO,GAChB,EACF,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAC,WAAW,YAChC,aAAI,SAAS,EAAC,mCAAmC,yBAAc,GAC3D,EACN,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,YACT,MAAC,GAAG,IAAC,SAAS,EAAC,uCAAuC,aAEpD,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAC,kBAAkB,YACtD,0BACE,aAAI,SAAS,EAAC,qDAAqD,yBAE9D,EACJ,CAAC,CAAC,KAAK,IAAI,CACV,KAAC,KAAK,IACJ,OAAO,EAAC,QAAQ,EAChB,IAAI,EAAE,SAAS,EACf,WAAW,QACX,OAAO,EAAE,CAAC,CAAC,UAAU,YAEpB,CAAC,CAAC,KAAK,GACF,CACT,EAEA,QAAQ,IAAI,CACX,8BACG,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CACvB,KAAC,KAAK,IAAC,OAAO,EAAC,QAAQ,EAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAC,MAAM,YACtD,CAAC,CAAC,WAAW;uDACX,oFAAoF,GACjF,CACT,EACD,KAAC,WAAW,IACV,OAAO,EAAE,CAAC,CAAC,OAAO,EAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ,EACpB,cAAc,EAAE,CAAC,CAAC,cAAc,EAChC,cAAc,EAAE,CAAC,CAAC,cAAc,EAChC,WAAW,EAAE,CAAC,CAAC,WAAW,EAC1B,SAAS,EAAE,CAAC,CAAC,SAAS,EACtB,WAAW,EAAE,CAAC,CAAC,WAAW,EAC1B,YAAY,EAAE,CAAC,CAAC,YAAY,EAC5B,UAAU,EAAE,YAAY,EACxB,YAAY,EAAE,CAAC,CAAC,UAAU,EAC1B,QAAQ,EAAE,UAAU,EACpB,WAAW,EACT,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,EAE5D,WAAW,EACT,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAEtD,WAAW,EAAE,CAAC,CAAC,WAAW,GAC1B,IACD,CACJ,EAEA,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CACxB,KAAC,aAAa,IACZ,gBAAgB,EAAE,CAAA,MAAA,CAAC,CAAC,mBAAmB,0CAAE,IAAI,KAAI,EAAE,EACnD,SAAS,EAAE,CAAA,MAAA,CAAC,CAAC,mBAAmB,0CAAE,SAAS,KAAI,EAAE,EACjD,UAAU,EAAE,YAAY,EACxB,QAAQ,EAAE,UAAU,EACpB,WAAW,EACT,CAAC,CAAC,aAAa,KAAK,SAAS;4CAC3B,CAAC,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK;4CACrB,CAAC,CAAC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,EAExB,WAAW,EACT,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAEtD,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,iBAAiB,GAC/B,CACH,EAEA,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CACxB,KAAC,aAAa,IAAC,MAAM,EAAE,CAAC,CAAC,WAAW,GAAI,CACzC,IACG,GACF,EAGN,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAC,kBAAkB,YACrD,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACvB,KAAC,iBAAiB,IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAChB,aAAa,EAAE,iBAAiB,GAChC,CACH,CAAC,CAAC,CAAC,CACF,KAAC,WAAW,IACV,aAAa,EAAE,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAM,EACnC,YAAY,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,EACjC,QAAQ,EAAE,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,QAAQ,mCAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,QAAQ,EACzD,mBAAmB,EAAE,eAAe,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC,EAC/D,kBAAkB,EAAE,eAAe,CAAC,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,EAC7D,qBAAqB,EAAE,CAAC,CAAC,qBAAqB,EAC9C,YAAY,EAAE,CAAC,CAAC,aAAa,EAC7B,aAAa,EAAE,CAAC,CAAC,QAAQ,EACzB,MAAM,EAAE,CAAC,CAAC,MAAM,GAChB,CACH,GACG,IACF,GACF,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,QAAQ,CAAC","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 { ALLOWED_CHECKOUT_COUNTRIES, GATE_CHECK_COUNTRY } from '../../constants';\nimport CartSummary from '../CartSummary/CartSummary';\nimport EnrollmentSummary from '../EnrollmentSummary/EnrollmentSummary';\nimport PaymentForm from '../PaymentForm/PaymentForm';\nimport CountryUnavailableModal from '../CountryUnavailableModal/CountryUnavailableModal';\nimport { getPlanPrice, getRenewalLabel } from '../../utils/billingDetails';\nimport { getTrialDateRange } from '@src/utils';\nimport { SuccessScreen, BlockedScreen } from '../StatusScreens/StatusScreens';\n\nexport type CheckoutProps = UseCheckoutOptions & {\n /** Homepage URL for the country-unavailable modal CTA. */\n homeUrl?: string,\n};\n\nconst Checkout = ({ homeUrl = '/', ...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 isBillingCountryBlocked = GATE_CHECK_COUNTRY\n && !!c.billing.country\n && !ALLOWED_CHECKOUT_COUNTRIES.includes(c.billing.country);\n\n const handleStartCourse = () => {\n if (c.course?.tUrlCourse) {\n window.location.href = c.course.tUrlCourse;\n } else {\n window.location.href = '/subscription-search';\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 <CountryUnavailableModal\n isOpen={isBillingCountryBlocked}\n homeUrl={homeUrl}\n />\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={handleStartCourse}\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 monthlyAmount={monthlyPrice?.amount}\n annualAmount={annualPrice?.amount}\n currency={monthlyPrice?.currency ?? annualPrice?.currency}\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"]}
|
|
1
|
+
{"version":3,"file":"Checkout.js","sourceRoot":"","sources":["../../../src/components/Checkout/Checkout.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect } 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 { ALLOWED_CHECKOUT_COUNTRIES, GATE_CHECK_COUNTRY } from '../../constants';\nimport CartSummary from '../CartSummary/CartSummary';\nimport EnrollmentSummary from '../EnrollmentSummary/EnrollmentSummary';\nimport PaymentForm from '../PaymentForm/PaymentForm';\nimport CountryUnavailableModal from '../CountryUnavailableModal/CountryUnavailableModal';\nimport { getPlanPrice, getRenewalLabel } from '../../utils/billingDetails';\nimport { getTrialDateRange } from '@src/utils';\nimport { SuccessScreen, BlockedScreen } from '../StatusScreens/StatusScreens';\nimport type { BillingCycle } from '../../types';\n\n/** Resolve purchased cycle from subscription details, falling back to checkout selection. */\nfunction resolvePurchasedCycle(\n selectedCycle: BillingCycle,\n planName?: string | null,\n renewalType?: string | null,\n): BillingCycle {\n const haystack = `${planName ?? ''} ${renewalType ?? ''}`.toLowerCase();\n if (haystack.includes('annual') || haystack.includes('year')) return 'annual';\n if (haystack.includes('month')) return 'monthly';\n return selectedCycle;\n}\n\nexport type CheckoutProps = UseCheckoutOptions & {\n /** Homepage URL for the country-unavailable modal CTA. */\n homeUrl?: string,\n /**\n * When true, learners can switch between monthly and annual billing.\n * Sourced from ENABLE_ANNUAL_BILLING in site.config.*.tsx.\n */\n enableAnnualBilling?: boolean,\n};\n\nconst Checkout = ({\n homeUrl = '/',\n enableAnnualBilling = false,\n ...props\n}: CheckoutProps) => {\n const c = useCheckout(props);\n\n useEffect(() => {\n if (!enableAnnualBilling && c.selectedCycle !== 'monthly') {\n c.setCycle('monthly');\n }\n }, [enableAnnualBilling, c.selectedCycle, c.setCycle]);\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 isBillingCountryBlocked = GATE_CHECK_COUNTRY\n && !!c.billing.country\n && !ALLOWED_CHECKOUT_COUNTRIES.includes(c.billing.country);\n\n // Keep annual selection only when the feature flag is on.\n const selectedCycle: BillingCycle = enableAnnualBilling\n ? c.selectedCycle\n : 'monthly';\n\n const purchasedCycle = resolvePurchasedCycle(\n selectedCycle,\n c.subscriptionDetails?.planName,\n c.subscriptionDetails?.renewalType,\n );\n const purchasedPrice = getPlanPrice(c.billingPlans, purchasedCycle);\n\n const handleStartCourse = () => {\n if (c.course?.tUrlCourse) {\n window.location.href = c.course.tUrlCourse;\n } else {\n window.location.href = '/subscription-search';\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 <CountryUnavailableModal\n isOpen={isBillingCountryBlocked}\n homeUrl={homeUrl}\n />\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 selectedCycle === 'monthly' ? monthlyPrice : annualPrice\n }\n cycleToShow={\n 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 purchaseDate={displayStart}\n trialStart={displayStart}\n trialEnd={displayEnd}\n priceToShow={\n purchasedCycle === 'monthly'\n ? monthlyPrice?.label\n : annualPrice?.label\n }\n cycleToShow={\n purchasedCycle === 'monthly' ? 'monthly' : 'annual'\n }\n courseLabel={courseLabel}\n onFindCourse={handleStartCourse}\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 amount={purchasedPrice?.amount}\n currency={purchasedPrice?.currency}\n cycleToShow={purchasedCycle}\n course={c.course}\n onStartCourse={handleStartCourse}\n />\n ) : (\n <CartSummary\n monthlyRegularAmount={monthlyPrice?.amount}\n annualAmount={annualPrice?.amount}\n currency={monthlyPrice?.currency ?? annualPrice?.currency}\n monthlyRenewalLabel={getRenewalLabel(c.billingPlans, 'monthly')}\n annualRenewalLabel={getRenewalLabel(c.billingPlans, 'annual')}\n activeSubscriberCount={c.activeSubscriberCount}\n defaultCycle={selectedCycle}\n onCycleChange={c.setCycle}\n enableAnnualBilling={enableAnnualBilling}\n course={c.course}\n />\n )}\n </Col>\n </Row>\n </Col>\n </Row>\n );\n};\n\nexport default Checkout;\n"]}
|
|
@@ -2,11 +2,12 @@ import type { CourseDetail } from '../../types';
|
|
|
2
2
|
export interface EnrollmentSummaryProps {
|
|
3
3
|
productTitle?: string;
|
|
4
4
|
productBlurb?: string;
|
|
5
|
-
/** e.g. "
|
|
5
|
+
/** e.g. "59" or "396" from getBillingPlans */
|
|
6
6
|
amount?: string;
|
|
7
7
|
/** e.g. "USD" */
|
|
8
8
|
currency?: string;
|
|
9
|
-
|
|
9
|
+
/** Billing cycle for the purchased plan. */
|
|
10
|
+
cycleToShow?: 'monthly' | 'annual';
|
|
10
11
|
/** When set, shows the enrolled course card below the purchase summary. */
|
|
11
12
|
course?: CourseDetail | null;
|
|
12
13
|
onStartCourse?: () => void;
|
|
@@ -4,18 +4,20 @@ import { useIntl } from '@openedx/frontend-base';
|
|
|
4
4
|
import { EdxUnlimitedLogo } from '../BrandMarks/BrandMarks';
|
|
5
5
|
import CourseEnrollmentCard from '../CourseEnrollmentCard/CourseEnrollmentCard';
|
|
6
6
|
import messages from './Messages';
|
|
7
|
-
const EnrollmentSummary = ({ productTitle = 'edX
|
|
7
|
+
const EnrollmentSummary = ({ productTitle = 'edX Plus', productBlurb = 'Access to hundreds of courses and programs.', amount, currency = 'USD', cycleToShow = 'monthly', course = null, onStartCourse, }) => {
|
|
8
8
|
const { formatMessage } = useIntl();
|
|
9
9
|
const isMonthly = cycleToShow === 'monthly';
|
|
10
10
|
const frequency = isMonthly ? 'month' : 'year';
|
|
11
11
|
const cycleLabel = isMonthly
|
|
12
12
|
? formatMessage(messages.monthlySubscription)
|
|
13
13
|
: formatMessage(messages.annualSubscription);
|
|
14
|
-
return (_jsxs("div", { className: "enrollment-summary", children: [_jsxs(Card, { className: "enrollment-
|
|
14
|
+
return (_jsxs("div", { className: "enrollment-summary", children: [_jsxs(Card, { className: "enrollment-summary__card p-3", children: [_jsx(Card.Section, { className: "p-0 pb-3", children: _jsx("p", { className: "font-weight-bold mb-0 text-gray-900", children: formatMessage(messages.purchaseSummary) }) }), _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, {}), _jsx(Card.Section, { className: "p-0 pt-3 pb-2", children: _jsxs("div", { className: "d-flex justify-content-between align-items-start", children: [_jsx("span", { className: "small text-gray-900", children: cycleLabel }), _jsx("span", { className: "small text-gray-900 font-weight-bold", children: amount
|
|
15
|
+
? formatMessage(messages.priceDisplay, {
|
|
15
16
|
amount,
|
|
16
17
|
frequency,
|
|
17
18
|
currency,
|
|
18
|
-
})
|
|
19
|
+
})
|
|
20
|
+
: null })] }) }), _jsxs(Card.Section, { className: "d-flex justify-content-between align-items-center px-0 pt-1", children: [_jsx("span", { className: "font-weight-bold text-gray-900", children: formatMessage(messages.todaysTotal) }), _jsx("span", { className: "font-weight-bold mb-0 text-success", children: formatMessage(messages.todaysTotalValue) })] })] }), course && (_jsx(CourseEnrollmentCard, { course: course, variant: "success", onStartCourse: onStartCourse }))] }));
|
|
19
21
|
};
|
|
20
22
|
export default EnrollmentSummary;
|
|
21
23
|
//# sourceMappingURL=EnrollmentSummary.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnrollmentSummary.js","sourceRoot":"","sources":["../../../src/components/EnrollmentSummary/EnrollmentSummary.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,oBAAoB,MAAM,8CAA8C,CAAC;AAEhF,OAAO,QAAQ,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"EnrollmentSummary.js","sourceRoot":"","sources":["../../../src/components/EnrollmentSummary/EnrollmentSummary.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,oBAAoB,MAAM,8CAA8C,CAAC;AAEhF,OAAO,QAAQ,MAAM,YAAY,CAAC;AAgBlC,MAAM,iBAAiB,GAAG,CAAC,EACzB,YAAY,GAAG,UAAU,EACzB,YAAY,GAAG,6CAA6C,EAC5D,MAAM,EACN,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,SAAS,EACvB,MAAM,GAAG,IAAI,EACb,aAAa,GACU,EAAE,EAAE;IAC3B,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,MAAM,SAAS,GAAG,WAAW,KAAK,SAAS,CAAC;IAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,UAAU,GAAG,SAAS;QAC1B,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAC7C,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAE/C,OAAO,CACL,eAAK,SAAS,EAAC,oBAAoB,aACjC,MAAC,IAAI,IAAC,SAAS,EAAC,8BAA8B,aAC5C,KAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,UAAU,YAChC,YAAG,SAAS,EAAC,qCAAqC,YAC/C,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,GACtC,GACS,EAEf,KAAC,IAAI,CAAC,OAAO,KAAG,EAEhB,KAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,UAAU,YAChC,eAAK,SAAS,EAAC,0BAA0B,aACvC,KAAC,gBAAgB,KAAG,EACpB,0BACE,YAAG,SAAS,EAAC,wCAAwC,YAClD,YAAY,GACX,EACJ,YAAG,SAAS,EAAC,0BAA0B,YAAE,YAAY,GAAK,IACtD,IACF,GACO,EAEf,KAAC,IAAI,CAAC,OAAO,KAAG,EAEhB,KAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,eAAe,YACrC,eAAK,SAAS,EAAC,kDAAkD,aAC/D,eAAM,SAAS,EAAC,qBAAqB,YAAE,UAAU,GAAQ,EACzD,eAAM,SAAS,EAAC,sCAAsC,YACnD,MAAM;wCACL,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,EAAE;4CACnC,MAAM;4CACN,SAAS;4CACT,QAAQ;yCACT,CAAC;wCACJ,CAAC,CAAC,IAAI,GACH,IACH,GACO,EAEf,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,6DAA6D,aACnF,eAAM,SAAS,EAAC,gCAAgC,YAC7C,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAC/B,EACP,eAAM,SAAS,EAAC,oCAAoC,YACjD,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GACpC,IACM,IACV,EAEN,MAAM,IAAI,CACT,KAAC,oBAAoB,IACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAC,SAAS,EACjB,aAAa,EAAE,aAAa,GAC5B,CACH,IACG,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC","sourcesContent":["import React from 'react';\nimport { Card } from '@openedx/paragon';\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 interface EnrollmentSummaryProps {\n productTitle?: string,\n productBlurb?: string,\n /** e.g. \"59\" or \"396\" from getBillingPlans */\n amount?: string,\n /** e.g. \"USD\" */\n currency?: string,\n /** Billing cycle for the purchased plan. */\n cycleToShow?: 'monthly' | 'annual',\n /** When set, shows the enrolled course card below the purchase summary. */\n course?: CourseDetail | null,\n onStartCourse?: () => void,\n}\n\nconst EnrollmentSummary = ({\n productTitle = 'edX Plus',\n productBlurb = 'Access to hundreds of courses and programs.',\n amount,\n currency = 'USD',\n cycleToShow = 'monthly',\n course = null,\n onStartCourse,\n}: EnrollmentSummaryProps) => {\n const { formatMessage } = useIntl();\n\n const isMonthly = cycleToShow === 'monthly';\n const frequency = isMonthly ? 'month' : 'year';\n const cycleLabel = isMonthly\n ? formatMessage(messages.monthlySubscription)\n : formatMessage(messages.annualSubscription);\n\n return (\n <div className=\"enrollment-summary\">\n <Card className=\"enrollment-summary__card p-3\">\n <Card.Section className=\"p-0 pb-3\">\n <p className=\"font-weight-bold mb-0 text-gray-900\">\n {formatMessage(messages.purchaseSummary)}\n </p>\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 pt-3 pb-2\">\n <div className=\"d-flex justify-content-between align-items-start\">\n <span className=\"small text-gray-900\">{cycleLabel}</span>\n <span className=\"small text-gray-900 font-weight-bold\">\n {amount\n ? formatMessage(messages.priceDisplay, {\n amount,\n frequency,\n currency,\n })\n : null}\n </span>\n </div>\n </Card.Section>\n\n <Card.Section className=\"d-flex justify-content-between align-items-center px-0 pt-1\">\n <span className=\"font-weight-bold text-gray-900\">\n {formatMessage(messages.todaysTotal)}\n </span>\n <span className=\"font-weight-bold mb-0 text-success\">\n {formatMessage(messages.todaysTotalValue)}\n </span>\n </Card.Section>\n </Card>\n\n {course && (\n <CourseEnrollmentCard\n course={course}\n variant=\"success\"\n onStartCourse={onStartCourse}\n />\n )}\n </div>\n );\n};\n\nexport default EnrollmentSummary;\n"]}
|
|
@@ -17,8 +17,8 @@ const messages = defineMessages({
|
|
|
17
17
|
},
|
|
18
18
|
priceDisplay: {
|
|
19
19
|
id: 'checkout.enrollmentSummary.priceDisplay',
|
|
20
|
-
defaultMessage: '${amount}/{frequency}
|
|
21
|
-
description: 'Price display in the purchase summary',
|
|
20
|
+
defaultMessage: '${amount}/{frequency} {currency}',
|
|
21
|
+
description: 'Price display in the purchase summary e.g. $396/year USD',
|
|
22
22
|
},
|
|
23
23
|
todaysTotal: {
|
|
24
24
|
id: 'checkout.enrollmentSummary.todaysTotal',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../src/components/EnrollmentSummary/Messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,6DAA6D;KAC3E;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,gDAAgD;QACpD,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,qDAAqD;KACnE;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,oDAAoD;KAClE;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../src/components/EnrollmentSummary/Messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,6DAA6D;KAC3E;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,gDAAgD;QACpD,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,qDAAqD;KACnE;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,oDAAoD;KAClE;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,kCAAkC;QAClD,WAAW,EAAE,0DAA0D;KACxE;IACD,WAAW,EAAE;QACX,EAAE,EAAE,wCAAwC;QAC5C,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,6BAA6B;KAC3C;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,yCAAyC;KACvD;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n purchaseSummary: {\n id: 'checkout.enrollmentSummary.purchaseSummary',\n defaultMessage: 'Purchase summary',\n description: 'Heading for the purchase summary card on the success screen',\n },\n monthlySubscription: {\n id: 'checkout.enrollmentSummary.monthlySubscription',\n defaultMessage: 'Monthly subscription',\n description: 'Label for monthly billing cycle in purchase summary',\n },\n annualSubscription: {\n id: 'checkout.enrollmentSummary.annualSubscription',\n defaultMessage: 'Annual subscription',\n description: 'Label for annual billing cycle in purchase summary',\n },\n priceDisplay: {\n id: 'checkout.enrollmentSummary.priceDisplay',\n defaultMessage: '${amount}/{frequency} {currency}',\n description: 'Price display in the purchase summary e.g. $396/year USD',\n },\n todaysTotal: {\n id: 'checkout.enrollmentSummary.todaysTotal',\n defaultMessage: \"Today's total\",\n description: \"Label for today's total row\",\n },\n todaysTotalValue: {\n id: 'checkout.enrollmentSummary.todaysTotalValue',\n defaultMessage: '$0',\n description: \"Today's total value during trial period\",\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -3,7 +3,7 @@ import { useState } from 'react';
|
|
|
3
3
|
import { Button, Form, Spinner } from '@openedx/paragon';
|
|
4
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
5
5
|
import PaymentFields from '../PaymentFields/PaymentFields';
|
|
6
|
-
import { COUNTRIES_REQUIRING_EXTRA_CONFIRM,
|
|
6
|
+
import { COUNTRIES_REQUIRING_EXTRA_CONFIRM, BILLING_COUNTRIES } from '../../constants';
|
|
7
7
|
import messages from './Messages';
|
|
8
8
|
const PaymentForm = ({ billing, setField, numberMountRef, expiryMountRef, cvcMountRef, cardError, stripeReady, sessionReady, submitting, onPlaceOrder, priceToShow, cycleToShow, trialEnd, userCountry, }) => {
|
|
9
9
|
var _a;
|
|
@@ -48,9 +48,9 @@ const PaymentForm = ({ billing, setField, numberMountRef, expiryMountRef, cvcMou
|
|
|
48
48
|
};
|
|
49
49
|
return (_jsxs("div", { className: "payment-form bg-white", children: [_jsx("h2", { className: "payment-form__heading font-weight-bold mb-3 text-primary-500", children: formatMessage(messages.selectPaymentMethod) }), _jsxs("p", { className: "payment-form__help small mb-4", children: [_jsx("strong", { className: "d-block text-primary-500", children: formatMessage(messages.needAssistance) }), ' ', _jsx("span", { className: "text-gray-700", children: formatMessage(messages.needAssistanceBody, {
|
|
50
50
|
link: (_jsx("a", { href: "https://support.edx.org", target: "_blank", rel: "noreferrer", className: "text-gray-700", children: formatMessage(messages.learnerHelpCenter) })),
|
|
51
|
-
}) })] }), _jsxs("div", { className: "payment-form__methods mb-4", children: [_jsxs("div", { className: `payment-form__method${paymentMethod === 'card' ? ' payment-form__method--selected' : ''}`, children: [_jsxs("label", { htmlFor: "paymentMethod-card", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-card", type: "radio", name: "paymentMethod", value: "card", checked: paymentMethod === 'card', onChange: () => setPaymentMethod('card'), className: "payment-form__radio" }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M0 4C0 3.46957 0.210714 2.96086 0.585786 2.58579C0.960859 2.21071 1.46957 2 2 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4H0ZM0 6V12C0 12.5304 0.210714 13.0391 0.585786 13.4142C0.960859 13.7893 1.46957 14 2 14H14C14.5304 14 15.0391 13.7893 15.4142 13.4142C15.7893 13.0391 16 12.5304 16 12V6H0ZM3 11C3 10.7348 3.10536 10.4804 3.29289 10.2929C3.48043 10.1054 3.73478 10 4 10H5C5.26522 10 5.51957 10.1054 5.70711 10.2929C5.89464 10.4804 6 10.7348 6 11C6 11.2652 5.89464 11.5196 5.70711 11.7071C5.51957 11.8946 5.26522 12 5 12H4C3.73478 12 3.48043 11.8946 3.29289 11.7071C3.10536 11.5196 3 11.2652 3 11Z", fill: "#0270DE" }) }), _jsx("span", { className: "payment-form__method-name text-info-500", children: formatMessage(messages.card) })] }),
|
|
51
|
+
}) })] }), _jsxs("div", { className: "payment-form__methods mb-4", children: [_jsxs("div", { className: `payment-form__method${paymentMethod === 'card' ? ' payment-form__method--selected' : ''}`, children: [_jsxs("label", { htmlFor: "paymentMethod-card", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-card", type: "radio", name: "paymentMethod", value: "card", checked: paymentMethod === 'card', onChange: () => setPaymentMethod('card'), className: "payment-form__radio" }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M0 4C0 3.46957 0.210714 2.96086 0.585786 2.58579C0.960859 2.21071 1.46957 2 2 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4H0ZM0 6V12C0 12.5304 0.210714 13.0391 0.585786 13.4142C0.960859 13.7893 1.46957 14 2 14H14C14.5304 14 15.0391 13.7893 15.4142 13.4142C15.7893 13.0391 16 12.5304 16 12V6H0ZM3 11C3 10.7348 3.10536 10.4804 3.29289 10.2929C3.48043 10.1054 3.73478 10 4 10H5C5.26522 10 5.51957 10.1054 5.70711 10.2929C5.89464 10.4804 6 10.7348 6 11C6 11.2652 5.89464 11.5196 5.70711 11.7071C5.51957 11.8946 5.26522 12 5 12H4C3.73478 12 3.48043 11.8946 3.29289 11.7071C3.10536 11.5196 3 11.2652 3 11Z", fill: "#0270DE" }) }), _jsx("span", { className: "payment-form__method-name text-info-500", children: formatMessage(messages.card) })] }), _jsxs("div", { className: `payment-form__card-panel${paymentMethod === 'card' ? '' : ' payment-form__card-panel--collapsed'}`, "aria-hidden": paymentMethod !== 'card', children: [_jsx(PaymentFields, { numberMountRef: numberMountRef, expiryMountRef: expiryMountRef, cvcMountRef: cvcMountRef, cardError: cardError }), _jsxs(Form.Group, { controlId: "country", className: "mt-3 mb-0 payment__field--country", children: [_jsx(Form.Label, { className: "small m-0 x-small", children: formatMessage(messages.country) }), _jsx(Form.Control, { as: "select", value: billing.country, onChange: (e) => setField('country', e.target.value), children: BILLING_COUNTRIES.map((country) => {
|
|
52
52
|
return (_jsx("option", { value: country[0], children: country[1] }, country[0]));
|
|
53
|
-
}) })] })] })
|
|
53
|
+
}) })] })] })] }), _jsx("div", { className: `my-3 payment-form__method payment-form__method--hidden${paymentMethod === 'googlepay' ? ' payment-form__method--selected' : ''}`, children: _jsxs("label", { htmlFor: "paymentMethod-googlepay", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-googlepay", type: "radio", name: "paymentMethod", value: "googlepay", checked: paymentMethod === 'googlepay', onChange: () => setPaymentMethod('googlepay'), className: "payment-form__radio" }), _jsx("span", { className: "payment-form__method-icon payment-form__method-icon--gpay", "aria-hidden": "true", children: "G" }), _jsx("span", { className: "payment-form__method-name", children: formatMessage(messages.googlePay) })] }) }), _jsx("div", { className: `my-3 payment-form__method${paymentMethod === 'paypal' ? ' payment-form__method--selected' : ''}`, children: _jsxs("label", { htmlFor: "paymentMethod-paypal", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-paypal", type: "radio", name: "paymentMethod", value: "paypal", checked: paymentMethod === 'paypal', onChange: () => setPaymentMethod('paypal'), className: "payment-form__radio" }), _jsx("span", { className: "payment-form__method-icon payment-form__method-icon--paypal", "aria-hidden": "true", children: "P" }), _jsx("span", { className: "payment-form__method-name", children: formatMessage(messages.paypal) })] }) })] }), _jsx("p", { className: "payment-form__terms text-gray-700 mb-3", children: formatMessage(messages.termsNotice, {
|
|
54
54
|
renewalDate: trialEnd !== null && trialEnd !== void 0 ? trialEnd : '{date}',
|
|
55
55
|
price: amount,
|
|
56
56
|
frequency,
|
|
@@ -63,6 +63,7 @@ const PaymentForm = ({ billing, setField, numberMountRef, expiryMountRef, cvcMou
|
|
|
63
63
|
}) }) }) }), showExtraConfirm && (_jsx(Form.Group, { controlId: "ukCaConfirm", className: "mb-4", children: _jsx(Form.Checkbox, { id: "ukCaConfirm", checked: ukCaConfirmed, onChange: (e) => setUkCaConfirmed(e.target.checked), children: _jsx("span", { className: "text-gray-700", children: formatMessage(messages.ukCaResidentConfirm) }) }) })), _jsxs(Button, { variant: "brand", className: "payment-form__submit", onClick: () => onPlaceOrder(buildConsent()), disabled: !stripeReady
|
|
64
64
|
|| submitting
|
|
65
65
|
|| !confirmed
|
|
66
|
+
|| paymentMethod === 'paypal'
|
|
66
67
|
|| (showExtraConfirm && !ukCaConfirmed), children: [busy && (_jsx(Spinner, { animation: "border", size: "sm", className: "mr-2", screenReaderText: formatMessage(messages.spinnerScreenReaderText) })), buttonLabel] })] }));
|
|
67
68
|
};
|
|
68
69
|
export default PaymentForm;
|