@edx/frontend-app-alacarte-checkout 1.4.0 → 1.6.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 (134) hide show
  1. package/dist/Main.js +2 -1
  2. package/dist/Main.js.map +1 -1
  3. package/dist/components/AlacarteConfirmation/AlacarteConfirmation.d.ts +15 -0
  4. package/dist/components/AlacarteConfirmation/AlacarteConfirmation.js +75 -0
  5. package/dist/components/AlacarteConfirmation/AlacarteConfirmation.js.map +1 -0
  6. package/dist/components/AlacarteConfirmation/Messages.d.ts +118 -0
  7. package/dist/components/AlacarteConfirmation/Messages.js +120 -0
  8. package/dist/components/AlacarteConfirmation/Messages.js.map +1 -0
  9. package/dist/components/AlacarteDebugPanel/AlacarteDebugPanel.d.ts +11 -0
  10. package/dist/components/AlacarteDebugPanel/AlacarteDebugPanel.js +10 -0
  11. package/dist/components/AlacarteDebugPanel/AlacarteDebugPanel.js.map +1 -0
  12. package/dist/components/AlacarteNotice/AlacarteNotice.d.ts +6 -0
  13. package/dist/components/AlacarteNotice/AlacarteNotice.js +9 -0
  14. package/dist/components/AlacarteNotice/AlacarteNotice.js.map +1 -0
  15. package/dist/components/AlacarteNotice/Messages.d.ts +18 -0
  16. package/dist/components/AlacarteNotice/Messages.js +20 -0
  17. package/dist/components/AlacarteNotice/Messages.js.map +1 -0
  18. package/dist/components/CartSummary/CartSummary.d.ts +11 -2
  19. package/dist/components/CartSummary/CartSummary.js +42 -10
  20. package/dist/components/CartSummary/CartSummary.js.map +1 -1
  21. package/dist/components/CartSummary/Messages.d.ts +25 -0
  22. package/dist/components/CartSummary/Messages.js +25 -0
  23. package/dist/components/CartSummary/Messages.js.map +1 -1
  24. package/dist/components/Checkout/Checkout.d.ts +3 -1
  25. package/dist/components/Checkout/Checkout.js +135 -23
  26. package/dist/components/Checkout/Checkout.js.map +1 -1
  27. package/dist/components/Checkout/Messages.d.ts +15 -0
  28. package/dist/components/Checkout/Messages.js +15 -0
  29. package/dist/components/Checkout/Messages.js.map +1 -1
  30. package/dist/components/CheckoutGate/CheckoutGate.js +3 -3
  31. package/dist/components/CheckoutGate/CheckoutGate.js.map +1 -1
  32. package/dist/components/PaymentFields/PaymentFields.d.ts +1 -2
  33. package/dist/components/PaymentFields/PaymentFields.js +1 -1
  34. package/dist/components/PaymentFields/PaymentFields.js.map +1 -1
  35. package/dist/components/PaymentForm/Messages.d.ts +5 -0
  36. package/dist/components/PaymentForm/Messages.js +6 -1
  37. package/dist/components/PaymentForm/Messages.js.map +1 -1
  38. package/dist/components/PaymentForm/PaymentForm.d.ts +10 -4
  39. package/dist/components/PaymentForm/PaymentForm.js +22 -9
  40. package/dist/components/PaymentForm/PaymentForm.js.map +1 -1
  41. package/dist/components/ProgramEnrollmentCard/Messages.d.ts +28 -0
  42. package/dist/components/ProgramEnrollmentCard/Messages.js +30 -0
  43. package/dist/components/ProgramEnrollmentCard/Messages.js.map +1 -0
  44. package/dist/components/ProgramEnrollmentCard/ProgramEnrollmentCard.d.ts +8 -0
  45. package/dist/components/ProgramEnrollmentCard/ProgramEnrollmentCard.js +26 -0
  46. package/dist/components/ProgramEnrollmentCard/ProgramEnrollmentCard.js.map +1 -0
  47. package/dist/components/PromoCode/Messages.d.ts +28 -3
  48. package/dist/components/PromoCode/Messages.js +34 -9
  49. package/dist/components/PromoCode/Messages.js.map +1 -1
  50. package/dist/components/PromoCode/PromoCode.d.ts +27 -1
  51. package/dist/components/PromoCode/PromoCode.js +23 -7
  52. package/dist/components/PromoCode/PromoCode.js.map +1 -1
  53. package/dist/data/hooks/keys.d.ts +6 -1
  54. package/dist/data/hooks/keys.js +6 -1
  55. package/dist/data/hooks/keys.js.map +1 -1
  56. package/dist/data/hooks/useAlacarteCheckout.d.ts +98 -0
  57. package/dist/data/hooks/useAlacarteCheckout.js +366 -0
  58. package/dist/data/hooks/useAlacarteCheckout.js.map +1 -0
  59. package/dist/data/hooks/useAlacarteQueries.d.ts +21 -0
  60. package/dist/data/hooks/useAlacarteQueries.js +94 -0
  61. package/dist/data/hooks/useAlacarteQueries.js.map +1 -0
  62. package/dist/data/hooks/useCheckout.d.ts +8 -5
  63. package/dist/data/hooks/useCheckout.js +48 -8
  64. package/dist/data/hooks/useCheckout.js.map +1 -1
  65. package/dist/data/hooks/useCheckoutGate.d.ts +9 -1
  66. package/dist/data/hooks/useCheckoutGate.js +11 -21
  67. package/dist/data/hooks/useCheckoutGate.js.map +1 -1
  68. package/dist/data/hooks/useCheckoutMutations.js +9 -127
  69. package/dist/data/hooks/useCheckoutMutations.js.map +1 -1
  70. package/dist/data/hooks/useCheckoutQueries.d.ts +1 -13
  71. package/dist/data/hooks/useCheckoutQueries.js +1 -27
  72. package/dist/data/hooks/useCheckoutQueries.js.map +1 -1
  73. package/dist/style.scss +4 -0
  74. package/dist/styles/components/alacarteConfirmation.scss +148 -0
  75. package/dist/styles/components/alacarteDebugPanel.scss +28 -0
  76. package/dist/styles/components/alacarteNotice.scss +11 -0
  77. package/dist/styles/components/cartSummary.scss +1 -1
  78. package/dist/styles/components/checkout.scss +9 -4
  79. package/dist/styles/components/paymentForm.scss +1 -1
  80. package/dist/styles/components/programEnrollmentCard.scss +66 -0
  81. package/dist/styles/components/promoCode.scss +108 -11
  82. package/dist/styles/components/statusScreens.scss +3 -0
  83. package/dist/types/alacarte.d.ts +262 -0
  84. package/dist/types/alacarte.js +2 -0
  85. package/dist/types/alacarte.js.map +1 -0
  86. package/dist/types.d.ts +11 -6
  87. package/dist/types.js.map +1 -1
  88. package/dist/utils/alacarteApi.d.ts +24 -0
  89. package/dist/utils/alacarteApi.js +174 -0
  90. package/dist/utils/alacarteApi.js.map +1 -0
  91. package/dist/utils/alacarteCheckout.d.ts +6 -0
  92. package/dist/utils/alacarteCheckout.js +26 -0
  93. package/dist/utils/alacarteCheckout.js.map +1 -0
  94. package/dist/utils/alacartePayment.d.ts +62 -0
  95. package/dist/utils/alacartePayment.js +77 -0
  96. package/dist/utils/alacartePayment.js.map +1 -0
  97. package/dist/utils/alacarteQueries.d.ts +34 -0
  98. package/dist/utils/alacarteQueries.js +99 -0
  99. package/dist/utils/alacarteQueries.js.map +1 -0
  100. package/dist/utils/auth.js +0 -2
  101. package/dist/utils/auth.js.map +1 -1
  102. package/dist/utils/bootstrapApi.d.ts +1 -7
  103. package/dist/utils/bootstrapApi.js +5 -44
  104. package/dist/utils/bootstrapApi.js.map +1 -1
  105. package/dist/utils/checkout.js +0 -2
  106. package/dist/utils/checkout.js.map +1 -1
  107. package/dist/utils/couponErrors.d.ts +2 -0
  108. package/dist/utils/couponErrors.js +24 -0
  109. package/dist/utils/couponErrors.js.map +1 -0
  110. package/dist/utils/discount.d.ts +7 -0
  111. package/dist/utils/discount.js +18 -0
  112. package/dist/utils/discount.js.map +1 -0
  113. package/dist/utils/placeOrderErrors.d.ts +11 -0
  114. package/dist/utils/placeOrderErrors.js +28 -0
  115. package/dist/utils/placeOrderErrors.js.map +1 -0
  116. package/dist/utils/provision.js +2 -2
  117. package/dist/utils/provision.js.map +1 -1
  118. package/dist/utils/queries.d.ts +1 -4
  119. package/dist/utils/queries.js +1 -20
  120. package/dist/utils/queries.js.map +1 -1
  121. package/dist/utils/stripeCard.d.ts +30 -0
  122. package/dist/utils/stripeCard.js +70 -0
  123. package/dist/utils/stripeCard.js.map +1 -0
  124. package/package.json +2 -1
  125. package/README.md +0 -2
  126. package/dist/utils/billingDetails.d.ts +0 -30
  127. package/dist/utils/billingDetails.js +0 -48
  128. package/dist/utils/billingDetails.js.map +0 -1
  129. package/dist/utils/fetchActiveSubscriptions.d.ts +0 -4
  130. package/dist/utils/fetchActiveSubscriptions.js +0 -36
  131. package/dist/utils/fetchActiveSubscriptions.js.map +0 -1
  132. package/dist/utils/fetchBillingPlans.d.ts +0 -2
  133. package/dist/utils/fetchBillingPlans.js +0 -48
  134. package/dist/utils/fetchBillingPlans.js.map +0 -1
package/dist/Main.js CHANGED
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
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
+ import { NuqsAdapter } from 'nuqs/adapters/react-router/v6';
5
6
  import { appId } from './constants';
6
7
  import messages from './messages';
7
8
  import './style.scss';
@@ -9,7 +10,7 @@ const Main = () => {
9
10
  const { formatMessage } = useIntl();
10
11
  return (_jsxs(CurrentAppProvider, { appId: appId, children: [_jsx(Helmet, { children: _jsx("title", { children: formatMessage(messages['template.page.title'], {
11
12
  siteName: getSiteConfig().siteName,
12
- }) }) }), _jsx("main", { className: "d-flex flex-column flex-grow-1", children: _jsx(Outlet, {}) })] }));
13
+ }) }) }), _jsx(NuqsAdapter, { children: _jsx("main", { className: "d-flex flex-column flex-grow-1", children: _jsx(Outlet, {}) }) })] }));
13
14
  };
14
15
  export default Main;
15
16
  //# sourceMappingURL=Main.js.map
package/dist/Main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,OAAO,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"]}
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,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,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,KAAC,WAAW,cACV,eAAM,SAAS,EAAC,gCAAgC,YAC9C,KAAC,MAAM,KAAG,GACL,GACK,IACK,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 { NuqsAdapter } from 'nuqs/adapters/react-router/v6';\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 <NuqsAdapter>\n <main className=\"d-flex flex-column flex-grow-1\">\n <Outlet />\n </main>\n </NuqsAdapter>\n </CurrentAppProvider>\n );\n};\n\nexport default Main;\n"]}
@@ -0,0 +1,15 @@
1
+ import type { PlacedOrder, ProductDetail } from '../../types/alacarte';
2
+ export interface AlacarteConfirmationProps {
3
+ order: PlacedOrder | null;
4
+ awaiting: boolean;
5
+ error: string | null;
6
+ onContinue?: () => void;
7
+ /** Optional catalog detail from checkout — logo / brand. */
8
+ productDetail?: ProductDetail | null;
9
+ /** Display title from the checkout line (course or program name). */
10
+ productTitle?: string | null;
11
+ /** Learner order-history / dashboard URL for the secondary CTA. */
12
+ orderHistoryUrl?: string | null;
13
+ }
14
+ declare const AlacarteConfirmation: ({ order, awaiting, error, onContinue, productDetail, productTitle, orderHistoryUrl, }: AlacarteConfirmationProps) => import("react/jsx-runtime").JSX.Element | null;
15
+ export default AlacarteConfirmation;
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from 'react';
3
+ import { Alert, Button, Col, Icon, Row } from '@openedx/paragon';
4
+ import { Error as ErrorIcon, Monitor } from '@openedx/paragon/icons';
5
+ import { useIntl } from '@openedx/frontend-base';
6
+ import { ProcessingScreen } from '../StatusScreens/StatusScreens';
7
+ import messages from './Messages';
8
+ function isProgramOrder(order) {
9
+ return order.lines.some((line) => line.kind === 'program' || !!line.programId);
10
+ }
11
+ function formatPurchaseDate(locale, date = new Date()) {
12
+ return new Intl.DateTimeFormat(locale, {
13
+ month: 'long',
14
+ day: 'numeric',
15
+ year: 'numeric',
16
+ }).format(date);
17
+ }
18
+ function refundDeadline(locale, from = new Date()) {
19
+ const deadline = new Date(from);
20
+ deadline.setDate(deadline.getDate() + 14);
21
+ return formatPurchaseDate(locale, deadline);
22
+ }
23
+ const AlacarteConfirmation = ({ order, awaiting, error, onContinue, productDetail = null, productTitle = null, orderHistoryUrl = null, }) => {
24
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
25
+ const { formatMessage, locale = 'en-US' } = useIntl();
26
+ const purchaseDate = useMemo(() => formatPurchaseDate(locale), [locale]);
27
+ const refundBy = useMemo(() => refundDeadline(locale), [locale]);
28
+ if (awaiting && !order) {
29
+ return _jsx(ProcessingScreen, {});
30
+ }
31
+ if (error && !order) {
32
+ return (_jsx(Alert, { variant: "danger", icon: ErrorIcon, children: formatMessage(messages.orderLoadError, { error }) }));
33
+ }
34
+ if (!order) {
35
+ return null;
36
+ }
37
+ const programOrder = isProgramOrder(order);
38
+ const courseDetail = productDetail && 'maId' in productDetail
39
+ ? productDetail
40
+ : null;
41
+ const programDetail = productDetail && 'tCourses' in productDetail
42
+ ? productDetail
43
+ : null;
44
+ const firstLine = order.lines[0];
45
+ const brand = ((_a = courseDetail === null || courseDetail === void 0 ? void 0 : courseDetail.tBrandText) === null || _a === void 0 ? void 0 : _a.trim())
46
+ || ((_d = (_c = (_b = programDetail === null || programDetail === void 0 ? void 0 : programDetail.tCourses) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.tBrandText) === null || _d === void 0 ? void 0 : _d.trim())
47
+ || '';
48
+ const baseName = productTitle
49
+ || (firstLine === null || firstLine === void 0 ? void 0 : firstLine.name)
50
+ || (programOrder ? 'your program' : 'your course');
51
+ const productLabel = !programOrder && brand && !(productTitle === null || productTitle === void 0 ? void 0 : productTitle.includes(brand))
52
+ ? `${brand}: ${baseName}`
53
+ : baseName;
54
+ const orgLogo = (courseDetail === null || courseDetail === void 0 ? void 0 : courseDetail.imageUrl)
55
+ || ((_f = (_e = programDetail === null || programDetail === void 0 ? void 0 : programDetail.tCourses) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.tOrgLogoUrl)
56
+ || ((_h = (_g = programDetail === null || programDetail === void 0 ? void 0 : programDetail.tCourses) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.imageUrl)
57
+ || null;
58
+ const currency = (_k = (_j = order.totals) === null || _j === void 0 ? void 0 : _j.currency) !== null && _k !== void 0 ? _k : 'USD';
59
+ const subtotal = (_m = (_l = order.totals) === null || _l === void 0 ? void 0 : _l.price) !== null && _m !== void 0 ? _m : 0;
60
+ const discount = ((_p = (_o = order.totals) === null || _o === void 0 ? void 0 : _o.discount) !== null && _p !== void 0 ? _p : 0) + ((_r = (_q = order.totals) === null || _q === void 0 ? void 0 : _q.deduction) !== null && _r !== void 0 ? _r : 0);
61
+ const paid = (_t = (_s = order.totals) === null || _s === void 0 ? void 0 : _s.paid) !== null && _t !== void 0 ? _t : 0;
62
+ const money = (amount) => formatMessage(messages.moneyAmount, {
63
+ amount: amount.toFixed(2),
64
+ currency,
65
+ });
66
+ const programCourses = programOrder
67
+ ? order.lines.map((line) => line.name).filter(Boolean)
68
+ : [];
69
+ return (_jsx("div", { className: "alacarte-confirmation", "data-testid": "alacarte-confirmation", children: _jsxs(Row, { className: "alacarte-confirmation__row", children: [_jsxs(Col, { xs: 12, lg: 7, className: "alacarte-confirmation__main mb-5 mb-lg-0", children: [_jsx("h1", { className: "alacarte-confirmation__headline font-weight-bold mb-2", children: formatMessage(messages.headline) }), _jsx("p", { className: "alacarte-confirmation__subheadline text-muted mb-4", children: formatMessage(programOrder ? messages.subheadlineProgram : messages.subheadlineCourse, { productLabel }) }), _jsxs("div", { className: "alacarte-confirmation__ctas d-flex align-items-center flex-wrap mb-5", children: [_jsx(Button, { variant: "brand", className: "alacarte-confirmation__cta-primary", onClick: onContinue, children: formatMessage(programOrder ? messages.startProgram : messages.startCourse) }), orderHistoryUrl && (_jsx("a", { href: orderHistoryUrl, className: "alacarte-confirmation__order-history", children: formatMessage(messages.viewOrderHistory) }))] }), programOrder && programCourses.length > 0 && (_jsxs("div", { className: "alacarte-confirmation__about-program mb-5", children: [_jsx("h2", { className: "h5 font-weight-bold mb-2", children: formatMessage(messages.aboutProgram) }), _jsx("p", { className: "font-weight-bold mb-2", children: formatMessage(messages.coursesIncluded, { count: programCourses.length }) }), _jsx("ul", { className: "alacarte-confirmation__course-list mb-0", children: programCourses.map((name) => (_jsx("li", { children: name }, name))) })] })), _jsxs(Row, { children: [_jsxs(Col, { xs: 12, md: 7, className: "mb-4", children: [_jsx("h2", { className: "h5 font-weight-bold mb-3", children: formatMessage(messages.whatsIncluded) }), _jsxs("ul", { className: "alacarte-confirmation__benefits", children: [_jsx("li", { children: formatMessage(messages.benefit1) }), _jsx("li", { children: formatMessage(messages.benefit2) }), _jsx("li", { children: formatMessage(messages.benefit3) })] })] }), _jsxs(Col, { xs: 12, md: 5, className: "mb-4", children: [_jsxs("div", { className: "mb-3", children: [_jsx("p", { className: "font-weight-bold mb-0", children: formatMessage(messages.orderNumber) }), _jsx("p", { className: "text-muted mb-0", children: order.orderNumber })] }), _jsxs("div", { children: [_jsx("p", { className: "font-weight-bold mb-0", children: formatMessage(messages.purchaseDate) }), _jsx("p", { className: "text-muted mb-0", children: purchaseDate })] })] })] }), _jsx("hr", { className: "alacarte-confirmation__divider" }), _jsx("p", { className: "alacarte-confirmation__refund text-muted small mb-0", children: formatMessage(messages.refundNotice, { date: refundBy }) })] }), _jsx(Col, { xs: 12, lg: 5, children: _jsxs("aside", { className: "alacarte-confirmation__summary", "aria-label": formatMessage(messages.purchaseSummary), children: [_jsx("h2", { className: "alacarte-confirmation__summary-title font-weight-bold mb-3", children: formatMessage(messages.purchaseSummary) }), _jsxs("div", { className: "alacarte-confirmation__product d-flex align-items-start mb-4", children: [orgLogo ? (_jsx("img", { src: orgLogo, alt: "", className: "alacarte-confirmation__org-logo" })) : (_jsx("div", { className: "alacarte-confirmation__org-logo alacarte-confirmation__org-logo--placeholder", "aria-hidden": true })), _jsxs("div", { children: [_jsxs("span", { className: "alacarte-confirmation__badge", children: [_jsx(Icon, { src: Monitor, className: "alacarte-confirmation__badge-icon" }), formatMessage(messages.verifiedCertificate)] }), _jsx("p", { className: "alacarte-confirmation__product-name font-weight-bold mb-0", children: productLabel })] })] }), _jsx("hr", { className: "alacarte-confirmation__summary-divider" }), _jsxs("div", { className: "alacarte-confirmation__price-row", children: [_jsx("span", { children: formatMessage(messages.subtotal) }), _jsx("span", { children: money(subtotal) })] }), discount > 0 && (_jsxs("div", { className: "alacarte-confirmation__price-row alacarte-confirmation__price-row--discount", children: [_jsx("span", { children: formatMessage(messages.discountsApplied) }), _jsx("span", { children: formatMessage(messages.discountAmount, {
70
+ amount: discount.toFixed(2),
71
+ currency,
72
+ }) })] })), _jsxs("div", { className: "alacarte-confirmation__price-row alacarte-confirmation__price-row--paid", children: [_jsx("span", { children: formatMessage(messages.amountPaid) }), _jsx("span", { children: money(paid) })] })] }) })] }) }));
73
+ };
74
+ export default AlacarteConfirmation;
75
+ //# sourceMappingURL=AlacarteConfirmation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlacarteConfirmation.js","sourceRoot":"","sources":["../../../src/components/AlacarteConfirmation/AlacarteConfirmation.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useMemo } from 'react';\nimport { Alert, Button, Col, Icon, Row } from '@openedx/paragon';\nimport { Error as ErrorIcon, Monitor } from '@openedx/paragon/icons';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ProcessingScreen } from '../StatusScreens/StatusScreens';\nimport type { CourseDetail } from '../../types';\nimport type { PlacedOrder, ProductDetail, ProgramDetail } from '../../types/alacarte';\nimport messages from './Messages';\n\nexport interface AlacarteConfirmationProps {\n order: PlacedOrder | null,\n awaiting: boolean,\n error: string | null,\n onContinue?: () => void,\n /** Optional catalog detail from checkout — logo / brand. */\n productDetail?: ProductDetail | null,\n /** Display title from the checkout line (course or program name). */\n productTitle?: string | null,\n /** Learner order-history / dashboard URL for the secondary CTA. */\n orderHistoryUrl?: string | null,\n}\n\nfunction isProgramOrder(order: PlacedOrder): boolean {\n return order.lines.some((line) => line.kind === 'program' || !!line.programId);\n}\n\nfunction formatPurchaseDate(locale: string, date = new Date()): string {\n return new Intl.DateTimeFormat(locale, {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n }).format(date);\n}\n\nfunction refundDeadline(locale: string, from = new Date()): string {\n const deadline = new Date(from);\n deadline.setDate(deadline.getDate() + 14);\n return formatPurchaseDate(locale, deadline);\n}\n\nconst AlacarteConfirmation = ({\n order,\n awaiting,\n error,\n onContinue,\n productDetail = null,\n productTitle = null,\n orderHistoryUrl = null,\n}: AlacarteConfirmationProps) => {\n const { formatMessage, locale = 'en-US' } = useIntl();\n\n const purchaseDate = useMemo(() => formatPurchaseDate(locale), [locale]);\n const refundBy = useMemo(() => refundDeadline(locale), [locale]);\n\n if (awaiting && !order) {\n return <ProcessingScreen />;\n }\n\n if (error && !order) {\n return (\n <Alert variant=\"danger\" icon={ErrorIcon}>\n {formatMessage(messages.orderLoadError, { error })}\n </Alert>\n );\n }\n\n if (!order) {\n return null;\n }\n\n const programOrder = isProgramOrder(order);\n const courseDetail = productDetail && 'maId' in productDetail\n ? (productDetail as CourseDetail)\n : null;\n const programDetail = productDetail && 'tCourses' in productDetail\n ? (productDetail as ProgramDetail)\n : null;\n\n const firstLine = order.lines[0];\n const brand = courseDetail?.tBrandText?.trim()\n || programDetail?.tCourses?.[0]?.tBrandText?.trim()\n || '';\n const baseName = productTitle\n || firstLine?.name\n || (programOrder ? 'your program' : 'your course');\n\n const productLabel = !programOrder && brand && !productTitle?.includes(brand)\n ? `${brand}: ${baseName}`\n : baseName;\n\n const orgLogo = courseDetail?.imageUrl\n || programDetail?.tCourses?.[0]?.tOrgLogoUrl\n || programDetail?.tCourses?.[0]?.imageUrl\n || null;\n\n const currency = order.totals?.currency ?? 'USD';\n const subtotal = order.totals?.price ?? 0;\n const discount = (order.totals?.discount ?? 0) + (order.totals?.deduction ?? 0);\n const paid = order.totals?.paid ?? 0;\n\n const money = (amount: number) => formatMessage(messages.moneyAmount, {\n amount: amount.toFixed(2),\n currency,\n });\n\n const programCourses = programOrder\n ? order.lines.map((line) => line.name).filter(Boolean)\n : [];\n\n return (\n <div className=\"alacarte-confirmation\" data-testid=\"alacarte-confirmation\">\n <Row className=\"alacarte-confirmation__row\">\n <Col xs={12} lg={7} className=\"alacarte-confirmation__main mb-5 mb-lg-0\">\n <h1 className=\"alacarte-confirmation__headline font-weight-bold mb-2\">\n {formatMessage(messages.headline)}\n </h1>\n <p className=\"alacarte-confirmation__subheadline text-muted mb-4\">\n {formatMessage(\n programOrder ? messages.subheadlineProgram : messages.subheadlineCourse,\n { productLabel },\n )}\n </p>\n\n <div className=\"alacarte-confirmation__ctas d-flex align-items-center flex-wrap mb-5\">\n <Button\n variant=\"brand\"\n className=\"alacarte-confirmation__cta-primary\"\n onClick={onContinue}\n >\n {formatMessage(programOrder ? messages.startProgram : messages.startCourse)}\n </Button>\n {orderHistoryUrl && (\n <a href={orderHistoryUrl} className=\"alacarte-confirmation__order-history\">\n {formatMessage(messages.viewOrderHistory)}\n </a>\n )}\n </div>\n\n {programOrder && programCourses.length > 0 && (\n <div className=\"alacarte-confirmation__about-program mb-5\">\n <h2 className=\"h5 font-weight-bold mb-2\">\n {formatMessage(messages.aboutProgram)}\n </h2>\n <p className=\"font-weight-bold mb-2\">\n {formatMessage(messages.coursesIncluded, { count: programCourses.length })}\n </p>\n <ul className=\"alacarte-confirmation__course-list mb-0\">\n {programCourses.map((name) => (\n <li key={name}>{name}</li>\n ))}\n </ul>\n </div>\n )}\n\n <Row>\n <Col xs={12} md={7} className=\"mb-4\">\n <h2 className=\"h5 font-weight-bold mb-3\">\n {formatMessage(messages.whatsIncluded)}\n </h2>\n <ul className=\"alacarte-confirmation__benefits\">\n <li>{formatMessage(messages.benefit1)}</li>\n <li>{formatMessage(messages.benefit2)}</li>\n <li>{formatMessage(messages.benefit3)}</li>\n </ul>\n </Col>\n <Col xs={12} md={5} className=\"mb-4\">\n <div className=\"mb-3\">\n <p className=\"font-weight-bold mb-0\">\n {formatMessage(messages.orderNumber)}\n </p>\n <p className=\"text-muted mb-0\">{order.orderNumber}</p>\n </div>\n <div>\n <p className=\"font-weight-bold mb-0\">\n {formatMessage(messages.purchaseDate)}\n </p>\n <p className=\"text-muted mb-0\">{purchaseDate}</p>\n </div>\n </Col>\n </Row>\n\n <hr className=\"alacarte-confirmation__divider\" />\n <p className=\"alacarte-confirmation__refund text-muted small mb-0\">\n {formatMessage(messages.refundNotice, { date: refundBy })}\n </p>\n </Col>\n\n <Col xs={12} lg={5}>\n <aside\n className=\"alacarte-confirmation__summary\"\n aria-label={formatMessage(messages.purchaseSummary)}\n >\n <h2 className=\"alacarte-confirmation__summary-title font-weight-bold mb-3\">\n {formatMessage(messages.purchaseSummary)}\n </h2>\n\n <div className=\"alacarte-confirmation__product d-flex align-items-start mb-4\">\n {orgLogo ? (\n <img\n src={orgLogo}\n alt=\"\"\n className=\"alacarte-confirmation__org-logo\"\n />\n ) : (\n <div\n className=\"alacarte-confirmation__org-logo alacarte-confirmation__org-logo--placeholder\"\n aria-hidden\n />\n )}\n <div>\n <span className=\"alacarte-confirmation__badge\">\n <Icon src={Monitor} className=\"alacarte-confirmation__badge-icon\" />\n {formatMessage(messages.verifiedCertificate)}\n </span>\n <p className=\"alacarte-confirmation__product-name font-weight-bold mb-0\">\n {productLabel}\n </p>\n </div>\n </div>\n\n <hr className=\"alacarte-confirmation__summary-divider\" />\n\n <div className=\"alacarte-confirmation__price-row\">\n <span>{formatMessage(messages.subtotal)}</span>\n <span>{money(subtotal)}</span>\n </div>\n {discount > 0 && (\n <div className=\"alacarte-confirmation__price-row alacarte-confirmation__price-row--discount\">\n <span>{formatMessage(messages.discountsApplied)}</span>\n <span>\n {formatMessage(messages.discountAmount, {\n amount: discount.toFixed(2),\n currency,\n })}\n </span>\n </div>\n )}\n <div className=\"alacarte-confirmation__price-row alacarte-confirmation__price-row--paid\">\n <span>{formatMessage(messages.amountPaid)}</span>\n <span>{money(paid)}</span>\n </div>\n </aside>\n </Col>\n </Row>\n </div>\n );\n};\n\nexport default AlacarteConfirmation;\n"]}
@@ -0,0 +1,118 @@
1
+ declare const messages: {
2
+ orderLoadError: {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ headline: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ description: string;
11
+ };
12
+ subheadlineCourse: {
13
+ id: string;
14
+ defaultMessage: string;
15
+ description: string;
16
+ };
17
+ subheadlineProgram: {
18
+ id: string;
19
+ defaultMessage: string;
20
+ description: string;
21
+ };
22
+ startCourse: {
23
+ id: string;
24
+ defaultMessage: string;
25
+ description: string;
26
+ };
27
+ startProgram: {
28
+ id: string;
29
+ defaultMessage: string;
30
+ description: string;
31
+ };
32
+ viewOrderHistory: {
33
+ id: string;
34
+ defaultMessage: string;
35
+ description: string;
36
+ };
37
+ aboutProgram: {
38
+ id: string;
39
+ defaultMessage: string;
40
+ description: string;
41
+ };
42
+ coursesIncluded: {
43
+ id: string;
44
+ defaultMessage: string;
45
+ description: string;
46
+ };
47
+ whatsIncluded: {
48
+ id: string;
49
+ defaultMessage: string;
50
+ description: string;
51
+ };
52
+ benefit1: {
53
+ id: string;
54
+ defaultMessage: string;
55
+ description: string;
56
+ };
57
+ benefit2: {
58
+ id: string;
59
+ defaultMessage: string;
60
+ description: string;
61
+ };
62
+ benefit3: {
63
+ id: string;
64
+ defaultMessage: string;
65
+ description: string;
66
+ };
67
+ orderNumber: {
68
+ id: string;
69
+ defaultMessage: string;
70
+ description: string;
71
+ };
72
+ purchaseDate: {
73
+ id: string;
74
+ defaultMessage: string;
75
+ description: string;
76
+ };
77
+ refundNotice: {
78
+ id: string;
79
+ defaultMessage: string;
80
+ description: string;
81
+ };
82
+ purchaseSummary: {
83
+ id: string;
84
+ defaultMessage: string;
85
+ description: string;
86
+ };
87
+ verifiedCertificate: {
88
+ id: string;
89
+ defaultMessage: string;
90
+ description: string;
91
+ };
92
+ subtotal: {
93
+ id: string;
94
+ defaultMessage: string;
95
+ description: string;
96
+ };
97
+ discountsApplied: {
98
+ id: string;
99
+ defaultMessage: string;
100
+ description: string;
101
+ };
102
+ amountPaid: {
103
+ id: string;
104
+ defaultMessage: string;
105
+ description: string;
106
+ };
107
+ moneyAmount: {
108
+ id: string;
109
+ defaultMessage: string;
110
+ description: string;
111
+ };
112
+ discountAmount: {
113
+ id: string;
114
+ defaultMessage: string;
115
+ description: string;
116
+ };
117
+ };
118
+ export default messages;
@@ -0,0 +1,120 @@
1
+ import { defineMessages } from '@openedx/frontend-base';
2
+ const messages = defineMessages({
3
+ orderLoadError: {
4
+ id: 'checkout.alacarteConfirmation.orderLoadError',
5
+ defaultMessage: 'We could not load your order ({error}). Please refresh or check your learner dashboard.',
6
+ description: 'Error shown when tPlacedOrder fails on the confirmation page',
7
+ },
8
+ headline: {
9
+ id: 'checkout.alacarteConfirmation.headline',
10
+ defaultMessage: "You're ready to begin learning.",
11
+ description: 'Main headline on the à la carte order confirmation page',
12
+ },
13
+ subheadlineCourse: {
14
+ id: 'checkout.alacarteConfirmation.subheadlineCourse',
15
+ defaultMessage: "Your payment is complete and you're enrolled in {productLabel}. Below is a summary of your order.",
16
+ description: 'Confirmation subheadline for a course purchase',
17
+ },
18
+ subheadlineProgram: {
19
+ id: 'checkout.alacarteConfirmation.subheadlineProgram',
20
+ defaultMessage: "Your payment is complete and you're enrolled in {productLabel}. Below is a summary of your order.",
21
+ description: 'Confirmation subheadline for a program purchase',
22
+ },
23
+ startCourse: {
24
+ id: 'checkout.alacarteConfirmation.startCourse',
25
+ defaultMessage: 'Start course',
26
+ description: 'Primary CTA after buying a course',
27
+ },
28
+ startProgram: {
29
+ id: 'checkout.alacarteConfirmation.startProgram',
30
+ defaultMessage: 'Start program',
31
+ description: 'Primary CTA after buying a program',
32
+ },
33
+ viewOrderHistory: {
34
+ id: 'checkout.alacarteConfirmation.viewOrderHistory',
35
+ defaultMessage: 'View order history',
36
+ description: 'Secondary link to the learner order history',
37
+ },
38
+ aboutProgram: {
39
+ id: 'checkout.alacarteConfirmation.aboutProgram',
40
+ defaultMessage: 'About program',
41
+ description: 'Heading for the list of courses included in a program order',
42
+ },
43
+ coursesIncluded: {
44
+ id: 'checkout.alacarteConfirmation.coursesIncluded',
45
+ defaultMessage: 'Courses included in this program ({count}):',
46
+ description: 'Subheading above the program course list',
47
+ },
48
+ whatsIncluded: {
49
+ id: 'checkout.alacarteConfirmation.whatsIncluded',
50
+ defaultMessage: "What's included",
51
+ description: 'Benefits section heading on the confirmation page',
52
+ },
53
+ benefit1: {
54
+ id: 'checkout.alacarteConfirmation.benefit1',
55
+ defaultMessage: 'Access to graded assignments and exams',
56
+ description: 'First à la carte purchase benefit',
57
+ },
58
+ benefit2: {
59
+ id: 'checkout.alacarteConfirmation.benefit2',
60
+ defaultMessage: 'Shareable Certificate upon completion',
61
+ description: 'Second à la carte purchase benefit',
62
+ },
63
+ benefit3: {
64
+ id: 'checkout.alacarteConfirmation.benefit3',
65
+ defaultMessage: '24/7 Global Support',
66
+ description: 'Third à la carte purchase benefit',
67
+ },
68
+ orderNumber: {
69
+ id: 'checkout.alacarteConfirmation.orderNumber',
70
+ defaultMessage: 'Order number',
71
+ description: 'Order number label',
72
+ },
73
+ purchaseDate: {
74
+ id: 'checkout.alacarteConfirmation.purchaseDate',
75
+ defaultMessage: 'Purchase date',
76
+ description: 'Purchase date label',
77
+ },
78
+ refundNotice: {
79
+ id: 'checkout.alacarteConfirmation.refundNotice',
80
+ defaultMessage: "Don't like your course? Unenroll by {date} to get a full refund.",
81
+ description: 'Refund / unenroll notice at the bottom of the confirmation page',
82
+ },
83
+ purchaseSummary: {
84
+ id: 'checkout.alacarteConfirmation.purchaseSummary',
85
+ defaultMessage: 'Purchase summary',
86
+ description: 'Sidebar heading for the purchase summary card',
87
+ },
88
+ verifiedCertificate: {
89
+ id: 'checkout.alacarteConfirmation.verifiedCertificate',
90
+ defaultMessage: 'Verified certificate',
91
+ description: 'Badge on the purchase summary product',
92
+ },
93
+ subtotal: {
94
+ id: 'checkout.alacarteConfirmation.subtotal',
95
+ defaultMessage: 'Subtotal',
96
+ description: 'Subtotal row label',
97
+ },
98
+ discountsApplied: {
99
+ id: 'checkout.alacarteConfirmation.discountsApplied',
100
+ defaultMessage: 'Discounts applied',
101
+ description: 'Discount row label',
102
+ },
103
+ amountPaid: {
104
+ id: 'checkout.alacarteConfirmation.amountPaid',
105
+ defaultMessage: 'Amount paid',
106
+ description: 'Amount paid row label',
107
+ },
108
+ moneyAmount: {
109
+ id: 'checkout.alacarteConfirmation.moneyAmount',
110
+ defaultMessage: '${amount} {currency}',
111
+ description: 'Formatted money amount e.g. $12.00 USD',
112
+ },
113
+ discountAmount: {
114
+ id: 'checkout.alacarteConfirmation.discountAmount',
115
+ defaultMessage: '-${amount} {currency}',
116
+ description: 'Formatted discount amount e.g. -$10.00 USD',
117
+ },
118
+ });
119
+ export default messages;
120
+ //# sourceMappingURL=Messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../src/components/AlacarteConfirmation/Messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n orderLoadError: {\n id: 'checkout.alacarteConfirmation.orderLoadError',\n defaultMessage: 'We could not load your order ({error}). Please refresh or check your learner dashboard.',\n description: 'Error shown when tPlacedOrder fails on the confirmation page',\n },\n headline: {\n id: 'checkout.alacarteConfirmation.headline',\n defaultMessage: \"You're ready to begin learning.\",\n description: 'Main headline on the à la carte order confirmation page',\n },\n subheadlineCourse: {\n id: 'checkout.alacarteConfirmation.subheadlineCourse',\n defaultMessage: \"Your payment is complete and you're enrolled in {productLabel}. Below is a summary of your order.\",\n description: 'Confirmation subheadline for a course purchase',\n },\n subheadlineProgram: {\n id: 'checkout.alacarteConfirmation.subheadlineProgram',\n defaultMessage: \"Your payment is complete and you're enrolled in {productLabel}. Below is a summary of your order.\",\n description: 'Confirmation subheadline for a program purchase',\n },\n startCourse: {\n id: 'checkout.alacarteConfirmation.startCourse',\n defaultMessage: 'Start course',\n description: 'Primary CTA after buying a course',\n },\n startProgram: {\n id: 'checkout.alacarteConfirmation.startProgram',\n defaultMessage: 'Start program',\n description: 'Primary CTA after buying a program',\n },\n viewOrderHistory: {\n id: 'checkout.alacarteConfirmation.viewOrderHistory',\n defaultMessage: 'View order history',\n description: 'Secondary link to the learner order history',\n },\n aboutProgram: {\n id: 'checkout.alacarteConfirmation.aboutProgram',\n defaultMessage: 'About program',\n description: 'Heading for the list of courses included in a program order',\n },\n coursesIncluded: {\n id: 'checkout.alacarteConfirmation.coursesIncluded',\n defaultMessage: 'Courses included in this program ({count}):',\n description: 'Subheading above the program course list',\n },\n whatsIncluded: {\n id: 'checkout.alacarteConfirmation.whatsIncluded',\n defaultMessage: \"What's included\",\n description: 'Benefits section heading on the confirmation page',\n },\n benefit1: {\n id: 'checkout.alacarteConfirmation.benefit1',\n defaultMessage: 'Access to graded assignments and exams',\n description: 'First à la carte purchase benefit',\n },\n benefit2: {\n id: 'checkout.alacarteConfirmation.benefit2',\n defaultMessage: 'Shareable Certificate upon completion',\n description: 'Second à la carte purchase benefit',\n },\n benefit3: {\n id: 'checkout.alacarteConfirmation.benefit3',\n defaultMessage: '24/7 Global Support',\n description: 'Third à la carte purchase benefit',\n },\n orderNumber: {\n id: 'checkout.alacarteConfirmation.orderNumber',\n defaultMessage: 'Order number',\n description: 'Order number label',\n },\n purchaseDate: {\n id: 'checkout.alacarteConfirmation.purchaseDate',\n defaultMessage: 'Purchase date',\n description: 'Purchase date label',\n },\n refundNotice: {\n id: 'checkout.alacarteConfirmation.refundNotice',\n defaultMessage: \"Don't like your course? Unenroll by {date} to get a full refund.\",\n description: 'Refund / unenroll notice at the bottom of the confirmation page',\n },\n purchaseSummary: {\n id: 'checkout.alacarteConfirmation.purchaseSummary',\n defaultMessage: 'Purchase summary',\n description: 'Sidebar heading for the purchase summary card',\n },\n verifiedCertificate: {\n id: 'checkout.alacarteConfirmation.verifiedCertificate',\n defaultMessage: 'Verified certificate',\n description: 'Badge on the purchase summary product',\n },\n subtotal: {\n id: 'checkout.alacarteConfirmation.subtotal',\n defaultMessage: 'Subtotal',\n description: 'Subtotal row label',\n },\n discountsApplied: {\n id: 'checkout.alacarteConfirmation.discountsApplied',\n defaultMessage: 'Discounts applied',\n description: 'Discount row label',\n },\n amountPaid: {\n id: 'checkout.alacarteConfirmation.amountPaid',\n defaultMessage: 'Amount paid',\n description: 'Amount paid row label',\n },\n moneyAmount: {\n id: 'checkout.alacarteConfirmation.moneyAmount',\n defaultMessage: '${amount} {currency}',\n description: 'Formatted money amount e.g. $12.00 USD',\n },\n discountAmount: {\n id: 'checkout.alacarteConfirmation.discountAmount',\n defaultMessage: '-${amount} {currency}',\n description: 'Formatted discount amount e.g. -$10.00 USD',\n },\n});\n\nexport default messages;\n"]}
@@ -0,0 +1,11 @@
1
+ export interface AlacarteDebugPanelProps {
2
+ data: unknown;
3
+ }
4
+ /**
5
+ * TEMPORARY — dumps the à la carte checkout hook's data (selector, phase,
6
+ * checkout/line, productDetail, error) so the flow can be eyeballed against
7
+ * the real backend while it's being validated. Remove once confirmed working
8
+ * end to end; not meant to ship.
9
+ */
10
+ declare const AlacarteDebugPanel: ({ data }: AlacarteDebugPanelProps) => import("react/jsx-runtime").JSX.Element;
11
+ export default AlacarteDebugPanel;
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * TEMPORARY — dumps the à la carte checkout hook's data (selector, phase,
4
+ * checkout/line, productDetail, error) so the flow can be eyeballed against
5
+ * the real backend while it's being validated. Remove once confirmed working
6
+ * end to end; not meant to ship.
7
+ */
8
+ const AlacarteDebugPanel = ({ data }) => (_jsxs("div", { className: "alacarte-debug-panel", children: [_jsx("p", { className: "alacarte-debug-panel__title", children: "\uD83D\uDC1B Alacarte debug (temporary)" }), _jsx("pre", { className: "alacarte-debug-panel__content", children: JSON.stringify(data, null, 2) })] }));
9
+ export default AlacarteDebugPanel;
10
+ //# sourceMappingURL=AlacarteDebugPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlacarteDebugPanel.js","sourceRoot":"","sources":["../../../src/components/AlacarteDebugPanel/AlacarteDebugPanel.tsx"],"names":[],"mappings":";AAMA;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,CAAC,EAAE,IAAI,EAA2B,EAAE,EAAE,CAAC,CAChE,eAAK,SAAS,EAAC,sBAAsB,aACnC,YAAG,SAAS,EAAC,6BAA6B,wDAAkC,EAC5E,cAAK,SAAS,EAAC,+BAA+B,YAC3C,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAC1B,IACF,CACP,CAAC;AAEF,eAAe,kBAAkB,CAAC","sourcesContent":["import React from 'react';\n\nexport interface AlacarteDebugPanelProps {\n data: unknown,\n}\n\n/**\n * TEMPORARY — dumps the à la carte checkout hook's data (selector, phase,\n * checkout/line, productDetail, error) so the flow can be eyeballed against\n * the real backend while it's being validated. Remove once confirmed working\n * end to end; not meant to ship.\n */\nconst AlacarteDebugPanel = ({ data }: AlacarteDebugPanelProps) => (\n <div className=\"alacarte-debug-panel\">\n <p className=\"alacarte-debug-panel__title\">🐛 Alacarte debug (temporary)</p>\n <pre className=\"alacarte-debug-panel__content\">\n {JSON.stringify(data, null, 2)}\n </pre>\n </div>\n);\n\nexport default AlacarteDebugPanel;\n"]}
@@ -0,0 +1,6 @@
1
+ export type AlacarteNoticeMessageId = 'alreadyOwnedCourse' | 'alreadyOwnedProgram' | 'noActiveCheckout';
2
+ export interface AlacarteNoticeProps {
3
+ messageId: AlacarteNoticeMessageId;
4
+ }
5
+ declare const AlacarteNotice: ({ messageId }: AlacarteNoticeProps) => import("react/jsx-runtime").JSX.Element;
6
+ export default AlacarteNotice;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useIntl } from '@openedx/frontend-base';
3
+ import messages from './Messages';
4
+ const AlacarteNotice = ({ messageId }) => {
5
+ const { formatMessage } = useIntl();
6
+ return (_jsx("div", { className: "alacarte-notice", children: formatMessage(messages[messageId]) }));
7
+ };
8
+ export default AlacarteNotice;
9
+ //# sourceMappingURL=AlacarteNotice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlacarteNotice.js","sourceRoot":"","sources":["../../../src/components/AlacarteNotice/AlacarteNotice.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAQlC,MAAM,cAAc,GAAG,CAAC,EAAE,SAAS,EAAuB,EAAE,EAAE;IAC5D,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,OAAO,CACL,cAAK,SAAS,EAAC,iBAAiB,YAC7B,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAC/B,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["import React from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport messages from './Messages';\n\nexport type AlacarteNoticeMessageId = 'alreadyOwnedCourse' | 'alreadyOwnedProgram' | 'noActiveCheckout';\n\nexport interface AlacarteNoticeProps {\n messageId: AlacarteNoticeMessageId,\n}\n\nconst AlacarteNotice = ({ messageId }: AlacarteNoticeProps) => {\n const { formatMessage } = useIntl();\n return (\n <div className=\"alacarte-notice\">\n {formatMessage(messages[messageId])}\n </div>\n );\n};\n\nexport default AlacarteNotice;\n"]}
@@ -0,0 +1,18 @@
1
+ declare const messages: {
2
+ alreadyOwnedCourse: {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ alreadyOwnedProgram: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ description: string;
11
+ };
12
+ noActiveCheckout: {
13
+ id: string;
14
+ defaultMessage: string;
15
+ description: string;
16
+ };
17
+ };
18
+ export default messages;
@@ -0,0 +1,20 @@
1
+ import { defineMessages } from '@openedx/frontend-base';
2
+ const messages = defineMessages({
3
+ alreadyOwnedCourse: {
4
+ id: 'checkout.alacarteNotice.alreadyOwnedCourse',
5
+ defaultMessage: 'You already own this course.',
6
+ description: 'Shown when the learner already owns the course they were linked to.',
7
+ },
8
+ alreadyOwnedProgram: {
9
+ id: 'checkout.alacarteNotice.alreadyOwnedProgram',
10
+ defaultMessage: 'You already own this program.',
11
+ description: 'Shown when the learner already owns the program they were linked to.',
12
+ },
13
+ noActiveCheckout: {
14
+ id: 'checkout.alacarteNotice.noActiveCheckout',
15
+ defaultMessage: 'No course or program was passed in the URL, and there is no active cart.',
16
+ description: 'Banner shown when there are no query params and no open checkout. Temporary — redirect-home is disabled for now so this case stays visible.',
17
+ },
18
+ });
19
+ export default messages;
20
+ //# sourceMappingURL=Messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../src/components/AlacarteNotice/Messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,kBAAkB,EAAE;QAClB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,8BAA8B;QAC9C,WAAW,EAAE,qEAAqE;KACnF;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,+BAA+B;QAC/C,WAAW,EAAE,sEAAsE;KACpF;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,0CAA0C;QAC9C,cAAc,EAAE,0EAA0E;QAC1F,WAAW,EAAE,6IAA6I;KAC3J;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n alreadyOwnedCourse: {\n id: 'checkout.alacarteNotice.alreadyOwnedCourse',\n defaultMessage: 'You already own this course.',\n description: 'Shown when the learner already owns the course they were linked to.',\n },\n alreadyOwnedProgram: {\n id: 'checkout.alacarteNotice.alreadyOwnedProgram',\n defaultMessage: 'You already own this program.',\n description: 'Shown when the learner already owns the program they were linked to.',\n },\n noActiveCheckout: {\n id: 'checkout.alacarteNotice.noActiveCheckout',\n defaultMessage: 'No course or program was passed in the URL, and there is no active cart.',\n description: 'Banner shown when there are no query params and no open checkout. Temporary — redirect-home is disabled for now so this case stays visible.',\n },\n});\n\nexport default messages;\n"]}
@@ -1,4 +1,6 @@
1
+ import type { PromoCodeProps } from '../PromoCode/PromoCode';
1
2
  import type { CourseDetail } from '../../types';
3
+ import type { AlacarteLine, ProgramDetail } from '../../types/alacarte';
2
4
  export type BillingCycle = 'monthly' | 'annual';
3
5
  export interface CartSummaryProps {
4
6
  productTitle?: string;
@@ -12,7 +14,6 @@ export interface CartSummaryProps {
12
14
  /** Annual price amount e.g. "299" */
13
15
  annualAmount?: string;
14
16
  currency?: string;
15
- activeSubscriberCount?: number | null;
16
17
  defaultCycle?: BillingCycle;
17
18
  monthlyRenewalLabel?: string;
18
19
  annualRenewalLabel?: string;
@@ -21,6 +22,14 @@ export interface CartSummaryProps {
21
22
  learnerCount?: number;
22
23
  /** When set, shows the course enrollment preview card below the summary card. */
23
24
  course?: CourseDetail | null;
25
+ /** À la carte checkout line — when present, drives the subtotal/total and
26
+ * the product name shown, in place of the generic edX Plus placeholder. */
27
+ alacarteLine?: AlacarteLine | null;
28
+ /** Program catalog detail (filterTwouProgram) — when the line is a program,
29
+ * drives the "Courses included in this program" list. */
30
+ programDetail?: ProgramDetail | null;
31
+ /** Coupon input — when set, wires PromoCode to tCheckoutUpdate. */
32
+ promoCode?: PromoCodeProps | null;
24
33
  }
25
- declare const CartSummary: ({ productTitle, productBlurb, activeSubscriberCount, learnerCount: learnerCountProp, course, }: CartSummaryProps) => import("react/jsx-runtime").JSX.Element;
34
+ declare const CartSummary: ({ productTitle, productBlurb, learnerCount: learnerCountProp, course, alacarteLine, programDetail, promoCode, }: CartSummaryProps) => import("react/jsx-runtime").JSX.Element;
26
35
  export default CartSummary;