@edx/frontend-app-subscription-manage 1.3.2 → 1.4.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 (226) hide show
  1. package/dist/app.js +2 -2
  2. package/dist/app.js.map +1 -1
  3. package/dist/components/ActiveSubscription/ActiveSubscription.d.ts +7 -0
  4. package/dist/components/ActiveSubscription/ActiveSubscription.js +24 -0
  5. package/dist/components/ActiveSubscription/ActiveSubscription.js.map +1 -0
  6. package/dist/components/BecomeSubscriber/BecomeSubscriber.d.ts +7 -0
  7. package/dist/components/BecomeSubscriber/BecomeSubscriber.js +19 -0
  8. package/dist/components/BecomeSubscriber/BecomeSubscriber.js.map +1 -0
  9. package/dist/components/CancelConfirmation/CancelConfirmation.d.ts +12 -0
  10. package/dist/components/CancelConfirmation/CancelConfirmation.js +21 -0
  11. package/dist/components/CancelConfirmation/CancelConfirmation.js.map +1 -0
  12. package/dist/components/CancelSuccess/CancelSuccess.d.ts +7 -0
  13. package/dist/components/CancelSuccess/CancelSuccess.js +17 -0
  14. package/dist/components/CancelSuccess/CancelSuccess.js.map +1 -0
  15. package/dist/components/CanceledSubscription/CanceledSubscription.d.ts +13 -0
  16. package/dist/components/CanceledSubscription/CanceledSubscription.js +27 -0
  17. package/dist/components/CanceledSubscription/CanceledSubscription.js.map +1 -0
  18. package/dist/components/EnrolledCoursesList/EnrolledCoursesList.d.ts +8 -0
  19. package/dist/components/EnrolledCoursesList/EnrolledCoursesList.js +20 -0
  20. package/dist/components/EnrolledCoursesList/EnrolledCoursesList.js.map +1 -0
  21. package/dist/components/HelpFooter/HelpFooter.d.ts +3 -0
  22. package/dist/components/HelpFooter/HelpFooter.js +12 -0
  23. package/dist/components/HelpFooter/HelpFooter.js.map +1 -0
  24. package/dist/components/OrderHistoryHeader/OrderHistoryHeader.d.ts +3 -0
  25. package/dist/components/OrderHistoryHeader/OrderHistoryHeader.js +9 -0
  26. package/dist/components/OrderHistoryHeader/OrderHistoryHeader.js.map +1 -0
  27. package/dist/components/PaymentHistory/PaymentHistory.d.ts +10 -0
  28. package/dist/components/PaymentHistory/PaymentHistory.js +23 -0
  29. package/dist/components/PaymentHistory/PaymentHistory.js.map +1 -0
  30. package/dist/components/RenewSubscriptionModal/RenewSubscriptionModal.d.ts +17 -0
  31. package/dist/components/RenewSubscriptionModal/RenewSubscriptionModal.js +63 -0
  32. package/dist/components/RenewSubscriptionModal/RenewSubscriptionModal.js.map +1 -0
  33. package/dist/components/ResubscribeCard/ResubscribeCard.d.ts +9 -0
  34. package/dist/components/ResubscribeCard/ResubscribeCard.js +25 -0
  35. package/dist/components/ResubscribeCard/ResubscribeCard.js.map +1 -0
  36. package/dist/components/SubscriptionTabs/SubscriptionTabs.d.ts +8 -0
  37. package/dist/components/SubscriptionTabs/SubscriptionTabs.js +9 -0
  38. package/dist/components/SubscriptionTabs/SubscriptionTabs.js.map +1 -0
  39. package/dist/components/UpdatePaymentMethodModal/UpdatePaymentMethodModal.d.ts +9 -0
  40. package/dist/components/UpdatePaymentMethodModal/UpdatePaymentMethodModal.js +135 -0
  41. package/dist/components/UpdatePaymentMethodModal/UpdatePaymentMethodModal.js.map +1 -0
  42. package/dist/components/messages.d.ts +473 -0
  43. package/dist/components/messages.js +482 -0
  44. package/dist/components/messages.js.map +1 -0
  45. package/dist/constants.d.ts +14 -56
  46. package/dist/constants.js +23 -272
  47. package/dist/constants.js.map +1 -1
  48. package/dist/data/hooks/keys.d.ts +8 -13
  49. package/dist/data/hooks/keys.js +8 -13
  50. package/dist/data/hooks/keys.js.map +1 -1
  51. package/dist/data/hooks/useManageQueries.d.ts +37 -0
  52. package/dist/data/hooks/useManageQueries.js +206 -0
  53. package/dist/data/hooks/useManageQueries.js.map +1 -0
  54. package/dist/data/services/subs/urls.d.ts +2 -2
  55. package/dist/data/services/subs/urls.js.map +1 -1
  56. package/dist/data/services/subscription/cancelSubscription.d.ts +6 -0
  57. package/dist/data/services/subscription/cancelSubscription.js +31 -0
  58. package/dist/data/services/subscription/cancelSubscription.js.map +1 -0
  59. package/dist/data/services/subscription/getBillingPlans.d.ts +3 -0
  60. package/dist/{utils/fetchBillingPlans.js → data/services/subscription/getBillingPlans.js} +10 -21
  61. package/dist/data/services/subscription/getBillingPlans.js.map +1 -0
  62. package/dist/data/services/subscription/getIsCurrentUserSubscriber.d.ts +3 -0
  63. package/dist/data/services/subscription/getIsCurrentUserSubscriber.js +35 -0
  64. package/dist/data/services/subscription/getIsCurrentUserSubscriber.js.map +1 -0
  65. package/dist/data/services/subscription/getPaymentHistory.d.ts +6 -0
  66. package/dist/data/services/subscription/getPaymentHistory.js +65 -0
  67. package/dist/data/services/subscription/getPaymentHistory.js.map +1 -0
  68. package/dist/data/services/subscription/getSubscriptionEnrollments.d.ts +7 -0
  69. package/dist/data/services/subscription/getSubscriptionEnrollments.js +98 -0
  70. package/dist/data/services/subscription/getSubscriptionEnrollments.js.map +1 -0
  71. package/dist/data/services/subscription/getSubscriptionPaymentMethod.d.ts +8 -0
  72. package/dist/data/services/subscription/getSubscriptionPaymentMethod.js +42 -0
  73. package/dist/data/services/subscription/getSubscriptionPaymentMethod.js.map +1 -0
  74. package/dist/data/services/subscription/reactivateSubscription.d.ts +6 -0
  75. package/dist/data/services/subscription/reactivateSubscription.js +30 -0
  76. package/dist/data/services/subscription/reactivateSubscription.js.map +1 -0
  77. package/dist/data/services/subscription/updateSubscriptionPaymentMethod.d.ts +10 -0
  78. package/dist/data/services/subscription/updateSubscriptionPaymentMethod.js +31 -0
  79. package/dist/data/services/subscription/updateSubscriptionPaymentMethod.js.map +1 -0
  80. package/dist/icons/ExternalLinkIcon.d.ts +6 -0
  81. package/dist/icons/ExternalLinkIcon.js +18 -0
  82. package/dist/icons/ExternalLinkIcon.js.map +1 -0
  83. package/dist/icons/index.d.ts +1 -0
  84. package/dist/icons/index.js +2 -0
  85. package/dist/icons/index.js.map +1 -0
  86. package/dist/manageSubscriptionPage/CancelSubscriptionPage.d.ts +3 -0
  87. package/dist/manageSubscriptionPage/CancelSubscriptionPage.js +53 -0
  88. package/dist/manageSubscriptionPage/CancelSubscriptionPage.js.map +1 -0
  89. package/dist/manageSubscriptionPage/CancelSuccessPage.d.ts +3 -0
  90. package/dist/manageSubscriptionPage/CancelSuccessPage.js +24 -0
  91. package/dist/manageSubscriptionPage/CancelSuccessPage.js.map +1 -0
  92. package/dist/manageSubscriptionPage/ManageSubscriptionPage.d.ts +3 -0
  93. package/dist/manageSubscriptionPage/ManageSubscriptionPage.js +87 -0
  94. package/dist/manageSubscriptionPage/ManageSubscriptionPage.js.map +1 -0
  95. package/dist/messages.js +2 -2
  96. package/dist/messages.js.map +1 -1
  97. package/dist/routes.d.ts +9 -2
  98. package/dist/routes.js +26 -6
  99. package/dist/routes.js.map +1 -1
  100. package/dist/style.scss +1 -14
  101. package/dist/styles/components/manageSubscription.scss +454 -0
  102. package/dist/types.d.ts +57 -201
  103. package/dist/types.js +3 -0
  104. package/dist/types.js.map +1 -1
  105. package/dist/utils/billingDetails.d.ts +3 -20
  106. package/dist/utils/billingDetails.js +4 -25
  107. package/dist/utils/billingDetails.js.map +1 -1
  108. package/dist/utils/edxSession.d.ts +18 -0
  109. package/dist/utils/edxSession.js +72 -0
  110. package/dist/utils/edxSession.js.map +1 -0
  111. package/dist/utils/formatDate.d.ts +16 -0
  112. package/dist/utils/formatDate.js +69 -0
  113. package/dist/utils/formatDate.js.map +1 -0
  114. package/dist/utils/graphqlClient.d.ts +9 -10
  115. package/dist/utils/graphqlClient.js +22 -11
  116. package/dist/utils/graphqlClient.js.map +1 -1
  117. package/dist/utils/invoiceAmount.d.ts +22 -0
  118. package/dist/utils/invoiceAmount.js +59 -0
  119. package/dist/utils/invoiceAmount.js.map +1 -0
  120. package/dist/utils/queries.d.ts +38 -33
  121. package/dist/utils/queries.js +83 -123
  122. package/dist/utils/queries.js.map +1 -1
  123. package/dist/utils/subscriptionView.d.ts +15 -0
  124. package/dist/utils/subscriptionView.js +50 -0
  125. package/dist/utils/subscriptionView.js.map +1 -0
  126. package/dist/utils/urls.d.ts +13 -0
  127. package/dist/utils/urls.js +52 -0
  128. package/dist/utils/urls.js.map +1 -0
  129. package/package.json +7 -2
  130. package/dist/checkoutPage/CheckoutPage.d.ts +0 -3
  131. package/dist/checkoutPage/CheckoutPage.js +0 -30
  132. package/dist/checkoutPage/CheckoutPage.js.map +0 -1
  133. package/dist/components/BrandMarks/BrandMarks.d.ts +0 -3
  134. package/dist/components/BrandMarks/BrandMarks.js +0 -9
  135. package/dist/components/BrandMarks/BrandMarks.js.map +0 -1
  136. package/dist/components/CartSummary/CartSummary.d.ts +0 -21
  137. package/dist/components/CartSummary/CartSummary.js +0 -30
  138. package/dist/components/CartSummary/CartSummary.js.map +0 -1
  139. package/dist/components/CartSummary/Messages.d.ts +0 -73
  140. package/dist/components/CartSummary/Messages.js +0 -76
  141. package/dist/components/CartSummary/Messages.js.map +0 -1
  142. package/dist/components/Checkout/Checkout.d.ts +0 -4
  143. package/dist/components/Checkout/Checkout.js +0 -40
  144. package/dist/components/Checkout/Checkout.js.map +0 -1
  145. package/dist/components/CheckoutGate/CheckoutGate.d.ts +0 -7
  146. package/dist/components/CheckoutGate/CheckoutGate.js +0 -35
  147. package/dist/components/CheckoutGate/CheckoutGate.js.map +0 -1
  148. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.d.ts +0 -9
  149. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.js +0 -31
  150. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.js.map +0 -1
  151. package/dist/components/CourseEnrollmentCard/Messages.d.ts +0 -33
  152. package/dist/components/CourseEnrollmentCard/Messages.js +0 -35
  153. package/dist/components/CourseEnrollmentCard/Messages.js.map +0 -1
  154. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.d.ts +0 -13
  155. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.js +0 -11
  156. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.js.map +0 -1
  157. package/dist/components/EnrollmentSummary/EnrollmentSummary.d.ts +0 -15
  158. package/dist/components/EnrollmentSummary/EnrollmentSummary.js +0 -21
  159. package/dist/components/EnrollmentSummary/EnrollmentSummary.js.map +0 -1
  160. package/dist/components/EnrollmentSummary/Messages.d.ts +0 -33
  161. package/dist/components/EnrollmentSummary/Messages.js +0 -35
  162. package/dist/components/EnrollmentSummary/Messages.js.map +0 -1
  163. package/dist/components/PaymentFields/PaymentFields.d.ts +0 -9
  164. package/dist/components/PaymentFields/PaymentFields.js +0 -7
  165. package/dist/components/PaymentFields/PaymentFields.js.map +0 -1
  166. package/dist/components/PaymentForm/Messages.d.ts +0 -88
  167. package/dist/components/PaymentForm/Messages.js +0 -95
  168. package/dist/components/PaymentForm/Messages.js.map +0 -1
  169. package/dist/components/PaymentForm/PaymentForm.d.ts +0 -21
  170. package/dist/components/PaymentForm/PaymentForm.js +0 -69
  171. package/dist/components/PaymentForm/PaymentForm.js.map +0 -1
  172. package/dist/components/StatusScreens/Messages.d.ts +0 -103
  173. package/dist/components/StatusScreens/Messages.js +0 -108
  174. package/dist/components/StatusScreens/Messages.js.map +0 -1
  175. package/dist/components/StatusScreens/StatusScreens.d.ts +0 -23
  176. package/dist/components/StatusScreens/StatusScreens.js +0 -25
  177. package/dist/components/StatusScreens/StatusScreens.js.map +0 -1
  178. package/dist/data/hooks/useCheckout.d.ts +0 -57
  179. package/dist/data/hooks/useCheckout.js +0 -249
  180. package/dist/data/hooks/useCheckout.js.map +0 -1
  181. package/dist/data/hooks/useCheckoutGate.d.ts +0 -15
  182. package/dist/data/hooks/useCheckoutGate.js +0 -39
  183. package/dist/data/hooks/useCheckoutGate.js.map +0 -1
  184. package/dist/data/hooks/useCheckoutMutations.d.ts +0 -16
  185. package/dist/data/hooks/useCheckoutMutations.js +0 -131
  186. package/dist/data/hooks/useCheckoutMutations.js.map +0 -1
  187. package/dist/data/hooks/useCheckoutQueries.d.ts +0 -30
  188. package/dist/data/hooks/useCheckoutQueries.js +0 -97
  189. package/dist/data/hooks/useCheckoutQueries.js.map +0 -1
  190. package/dist/styles/components/brandMarks.scss +0 -54
  191. package/dist/styles/components/cartSummary.scss +0 -18
  192. package/dist/styles/components/checkout.scss +0 -29
  193. package/dist/styles/components/checkoutStepper.scss +0 -9
  194. package/dist/styles/components/courseEnrollmentCard.scss +0 -38
  195. package/dist/styles/components/edxUnlimitedBanner.scss +0 -138
  196. package/dist/styles/components/enrollmentSummary.scss +0 -13
  197. package/dist/styles/components/paymentFields.scss +0 -15
  198. package/dist/styles/components/paymentForm.scss +0 -105
  199. package/dist/styles/components/statusScreens.scss +0 -29
  200. package/dist/styles/components/successScreen.scss +0 -0
  201. package/dist/utils/auth.d.ts +0 -7
  202. package/dist/utils/auth.js +0 -28
  203. package/dist/utils/auth.js.map +0 -1
  204. package/dist/utils/bootstrapApi.d.ts +0 -20
  205. package/dist/utils/bootstrapApi.js +0 -142
  206. package/dist/utils/bootstrapApi.js.map +0 -1
  207. package/dist/utils/cartApi.d.ts +0 -16
  208. package/dist/utils/cartApi.js +0 -118
  209. package/dist/utils/cartApi.js.map +0 -1
  210. package/dist/utils/checkout.d.ts +0 -6
  211. package/dist/utils/checkout.js +0 -28
  212. package/dist/utils/checkout.js.map +0 -1
  213. package/dist/utils/fetchActiveSubscriptions.d.ts +0 -4
  214. package/dist/utils/fetchActiveSubscriptions.js +0 -36
  215. package/dist/utils/fetchActiveSubscriptions.js.map +0 -1
  216. package/dist/utils/fetchBillingPlans.d.ts +0 -2
  217. package/dist/utils/fetchBillingPlans.js.map +0 -1
  218. package/dist/utils/index.d.ts +0 -3
  219. package/dist/utils/index.js +0 -17
  220. package/dist/utils/index.js.map +0 -1
  221. package/dist/utils/provision.d.ts +0 -25
  222. package/dist/utils/provision.js +0 -95
  223. package/dist/utils/provision.js.map +0 -1
  224. package/dist/utils/stripe.d.ts +0 -7
  225. package/dist/utils/stripe.js +0 -43
  226. package/dist/utils/stripe.js.map +0 -1
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from '@openedx/paragon';
3
+ import { useIntl } from '@openedx/frontend-base';
4
+ import { formatDisplayDate } from '../../utils/formatDate';
5
+ import { getCheckoutUrl } from '../../utils/urls';
6
+ import messages from '../messages';
7
+ const ResubscribeCard = ({ subscriber, price = null, currency = null, }) => {
8
+ var _a, _b;
9
+ const { formatMessage } = useIntl();
10
+ const checkoutUrl = getCheckoutUrl();
11
+ const canceledOn = formatDisplayDate((_b = (_a = subscriber === null || subscriber === void 0 ? void 0 : subscriber.canceledAt) !== null && _a !== void 0 ? _a : subscriber === null || subscriber === void 0 ? void 0 : subscriber.subscriptionEndDate) !== null && _b !== void 0 ? _b : subscriber === null || subscriber === void 0 ? void 0 : subscriber.currentPeriodEnd);
12
+ const displayPrice = (subscriber === null || subscriber === void 0 ? void 0 : subscriber.amount) || price || null;
13
+ const displayCurrency = (subscriber === null || subscriber === void 0 ? void 0 : subscriber.currency) || currency || null;
14
+ const hasPrice = Boolean(displayPrice);
15
+ return (_jsxs("section", { className: "manage-section mt-4", children: [_jsx("h2", { className: "manage-section__title h3 font-weight-bold text-primary-500 mb-1", children: formatMessage(messages['manage.expired.heading']) }), _jsx("p", { className: "manage-section__subtitle text-gray-700 mb-3", children: formatMessage(messages['manage.expired.subheading']) }), _jsxs("div", { className: "manage-card d-flex flex-column flex-md-row align-items-md-center justify-content-md-between bg-white border p-4 rounded", children: [_jsxs("div", { className: "manage-card__content", children: [_jsx("h3", { className: "manage-card__title font-weight-bold text-primary-500 mb-1", children: hasPrice
16
+ ? formatMessage(messages['manage.expired.resubscribeTitle'], {
17
+ price: displayPrice,
18
+ currency: displayCurrency !== null && displayCurrency !== void 0 ? displayCurrency : '',
19
+ })
20
+ : formatMessage(messages['manage.expired.resubscribeTitleNoPrice']) }), _jsx("p", { className: "manage-card__body text-gray-700 mb-0", children: canceledOn
21
+ ? formatMessage(messages['manage.expired.canceledOn'], { date: canceledOn })
22
+ : formatMessage(messages['manage.expired.canceledOnNoDate']) })] }), _jsx("div", { className: "manage-card__actions d-flex flex-wrap align-items-center flex-shrink-0", children: _jsx(Button, { className: "manage-btn manage-btn--brand", href: checkoutUrl, children: formatMessage(messages['manage.canceled.renew']) }) })] })] }));
23
+ };
24
+ export default ResubscribeCard;
25
+ //# sourceMappingURL=ResubscribeCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResubscribeCard.js","sourceRoot":"","sources":["../../../src/components/ResubscribeCard/ResubscribeCard.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,QAAQ,MAAM,aAAa,CAAC;AAQnC,MAAM,eAAe,GAAmC,CAAC,EACvD,UAAU,EACV,KAAK,GAAG,IAAI,EACZ,QAAQ,GAAG,IAAI,GAChB,EAAE,EAAE;;IACH,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,UAAU,GAAG,iBAAiB,CAClC,MAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,UAAU,mCAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,mBAAmB,mCAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,gBAAgB,CAC1F,CAAC;IACF,MAAM,YAAY,GAAG,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,KAAI,KAAK,IAAI,IAAI,CAAC;IACzD,MAAM,eAAe,GAAG,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ,KAAI,QAAQ,IAAI,IAAI,CAAC;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAEvC,OAAO,CACL,mBAAS,SAAS,EAAC,qBAAqB,aACtC,aAAI,SAAS,EAAC,iEAAiE,YAC5E,aAAa,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,GAC/C,EACL,YAAG,SAAS,EAAC,6CAA6C,YACvD,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,GACnD,EAEJ,eAAK,SAAS,EAAC,yHAAyH,aACtI,eAAK,SAAS,EAAC,sBAAsB,aACnC,aAAI,SAAS,EAAC,2DAA2D,YACtE,QAAQ;oCACP,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,iCAAiC,CAAC,EAAE;wCACzD,KAAK,EAAE,YAAY;wCACnB,QAAQ,EAAE,eAAe,aAAf,eAAe,cAAf,eAAe,GAAI,EAAE;qCAChC,CAAC;oCACJ,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC,GAClE,EACL,YAAG,SAAS,EAAC,sCAAsC,YAChD,UAAU;oCACT,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;oCAC5E,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,iCAAiC,CAAC,CAAC,GAC5D,IACA,EACN,cAAK,SAAS,EAAC,wEAAwE,YACrF,KAAC,MAAM,IAAC,SAAS,EAAC,8BAA8B,EAAC,IAAI,EAAE,WAAW,YAC/D,aAAa,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,GAC1C,GACL,IACF,IACE,CACX,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC","sourcesContent":["import React from 'react';\nimport { Button } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\n\nimport type { CurrentUserSubscriberResult } from '../../types';\nimport { formatDisplayDate } from '../../utils/formatDate';\nimport { getCheckoutUrl } from '../../utils/urls';\nimport messages from '../messages';\n\ninterface ResubscribeCardProps {\n subscriber: CurrentUserSubscriberResult | null,\n price?: string | null,\n currency?: string | null,\n}\n\nconst ResubscribeCard: React.FC<ResubscribeCardProps> = ({\n subscriber,\n price = null,\n currency = null,\n}) => {\n const { formatMessage } = useIntl();\n const checkoutUrl = getCheckoutUrl();\n const canceledOn = formatDisplayDate(\n subscriber?.canceledAt ?? subscriber?.subscriptionEndDate ?? subscriber?.currentPeriodEnd,\n );\n const displayPrice = subscriber?.amount || price || null;\n const displayCurrency = subscriber?.currency || currency || null;\n const hasPrice = Boolean(displayPrice);\n\n return (\n <section className=\"manage-section mt-4\">\n <h2 className=\"manage-section__title h3 font-weight-bold text-primary-500 mb-1\">\n {formatMessage(messages['manage.expired.heading'])}\n </h2>\n <p className=\"manage-section__subtitle text-gray-700 mb-3\">\n {formatMessage(messages['manage.expired.subheading'])}\n </p>\n\n <div className=\"manage-card d-flex flex-column flex-md-row align-items-md-center justify-content-md-between bg-white border p-4 rounded\">\n <div className=\"manage-card__content\">\n <h3 className=\"manage-card__title font-weight-bold text-primary-500 mb-1\">\n {hasPrice\n ? formatMessage(messages['manage.expired.resubscribeTitle'], {\n price: displayPrice,\n currency: displayCurrency ?? '',\n })\n : formatMessage(messages['manage.expired.resubscribeTitleNoPrice'])}\n </h3>\n <p className=\"manage-card__body text-gray-700 mb-0\">\n {canceledOn\n ? formatMessage(messages['manage.expired.canceledOn'], { date: canceledOn })\n : formatMessage(messages['manage.expired.canceledOnNoDate'])}\n </p>\n </div>\n <div className=\"manage-card__actions d-flex flex-wrap align-items-center flex-shrink-0\">\n <Button className=\"manage-btn manage-btn--brand\" href={checkoutUrl}>\n {formatMessage(messages['manage.canceled.renew'])}\n </Button>\n </div>\n </div>\n </section>\n );\n};\n\nexport default ResubscribeCard;\n"]}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { ManageTab } from '../../types';
3
+ interface SubscriptionTabsProps {
4
+ activeTab: ManageTab;
5
+ onChange: (tab: ManageTab) => void;
6
+ }
7
+ declare const SubscriptionTabs: React.FC<SubscriptionTabsProps>;
8
+ export default SubscriptionTabs;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useIntl } from '@openedx/frontend-base';
3
+ import messages from '../messages';
4
+ const SubscriptionTabs = ({ activeTab, onChange }) => {
5
+ const { formatMessage } = useIntl();
6
+ return (_jsxs("div", { className: "manage-tabs d-flex border-bottom mt-4", role: "tablist", "aria-label": formatMessage(messages['manage.header.title']), children: [_jsx("button", { type: "button", role: "tab", id: "manage-tab-subscription", "aria-selected": activeTab === 'subscription', "aria-controls": "manage-tabpanel-subscription", className: `manage-tabs__tab${activeTab === 'subscription' ? ' manage-tabs__tab--active' : ''}`, onClick: () => onChange('subscription'), children: formatMessage(messages['manage.tab.subscription']) }), _jsx("button", { type: "button", role: "tab", id: "manage-tab-payment-history", "aria-selected": activeTab === 'payment-history', "aria-controls": "manage-tabpanel-payment-history", className: `manage-tabs__tab${activeTab === 'payment-history' ? ' manage-tabs__tab--active' : ''}`, onClick: () => onChange('payment-history'), children: formatMessage(messages['manage.tab.paymentHistory']) })] }));
7
+ };
8
+ export default SubscriptionTabs;
9
+ //# sourceMappingURL=SubscriptionTabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionTabs.js","sourceRoot":"","sources":["../../../src/components/SubscriptionTabs/SubscriptionTabs.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,QAAQ,MAAM,aAAa,CAAC;AAOnC,MAAM,gBAAgB,GAAoC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;IACpF,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,OAAO,CACL,eACE,SAAS,EAAC,uCAAuC,EACjD,IAAI,EAAC,SAAS,gBACF,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,aAE1D,iBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,EACV,EAAE,EAAC,yBAAyB,mBACb,SAAS,KAAK,cAAc,mBAC7B,8BAA8B,EAC5C,SAAS,EAAE,mBAAmB,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,EAAE,EAC/F,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,YAEtC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,GAC5C,EACT,iBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,EACV,EAAE,EAAC,4BAA4B,mBAChB,SAAS,KAAK,iBAAiB,mBAChC,iCAAiC,EAC/C,SAAS,EAAE,mBAAmB,SAAS,KAAK,iBAAiB,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,EAAE,EAClG,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,YAEzC,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,GAC9C,IACL,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import React from 'react';\nimport { useIntl } from '@openedx/frontend-base';\n\nimport type { ManageTab } from '../../types';\nimport messages from '../messages';\n\ninterface SubscriptionTabsProps {\n activeTab: ManageTab,\n onChange: (tab: ManageTab) => void,\n}\n\nconst SubscriptionTabs: React.FC<SubscriptionTabsProps> = ({ activeTab, onChange }) => {\n const { formatMessage } = useIntl();\n\n return (\n <div\n className=\"manage-tabs d-flex border-bottom mt-4\"\n role=\"tablist\"\n aria-label={formatMessage(messages['manage.header.title'])}\n >\n <button\n type=\"button\"\n role=\"tab\"\n id=\"manage-tab-subscription\"\n aria-selected={activeTab === 'subscription'}\n aria-controls=\"manage-tabpanel-subscription\"\n className={`manage-tabs__tab${activeTab === 'subscription' ? ' manage-tabs__tab--active' : ''}`}\n onClick={() => onChange('subscription')}\n >\n {formatMessage(messages['manage.tab.subscription'])}\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n id=\"manage-tab-payment-history\"\n aria-selected={activeTab === 'payment-history'}\n aria-controls=\"manage-tabpanel-payment-history\"\n className={`manage-tabs__tab${activeTab === 'payment-history' ? ' manage-tabs__tab--active' : ''}`}\n onClick={() => onChange('payment-history')}\n >\n {formatMessage(messages['manage.tab.paymentHistory'])}\n </button>\n </div>\n );\n};\n\nexport default SubscriptionTabs;\n"]}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface UpdatePaymentMethodModalProps {
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ subscriptionBiId: string | null | undefined;
6
+ nextBillingDate: string | null;
7
+ }
8
+ declare const UpdatePaymentMethodModal: React.FC<UpdatePaymentMethodModalProps>;
9
+ export default UpdatePaymentMethodModal;
@@ -0,0 +1,135 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ import { useCallback, useEffect, useMemo, useState, } from 'react';
12
+ import { Alert, Form, ModalDialog, Button, ActionRow, Icon, } from '@openedx/paragon';
13
+ import { getAppConfig, useIntl } from '@openedx/frontend-base';
14
+ import { CreditCard } from '@openedx/paragon/icons';
15
+ import { Elements, CardNumberElement, CardCvcElement, CardExpiryElement, useElements, useStripe, } from '@stripe/react-stripe-js';
16
+ import { loadStripe } from '@stripe/stripe-js';
17
+ import { appId } from '../../constants';
18
+ import { useUpdatePaymentMethodMutation, useViaxClient, } from '../../data/hooks/useManageQueries';
19
+ import messages from '../messages';
20
+ const ELEMENT_STYLE = {
21
+ base: {
22
+ color: '#00262b',
23
+ fontSize: '16px',
24
+ lineHeight: '24px',
25
+ fontFamily: '"Open Sans", "Helvetica Neue", Arial, sans-serif',
26
+ fontSmoothing: 'antialiased',
27
+ '::placeholder': {
28
+ color: '#707070',
29
+ },
30
+ },
31
+ invalid: {
32
+ color: '#b91c1c',
33
+ iconColor: '#b91c1c',
34
+ },
35
+ };
36
+ const PaymentForm = ({ subscriptionBiId, onClose, onSuccess, }) => {
37
+ const { formatMessage } = useIntl();
38
+ const stripe = useStripe();
39
+ const elements = useElements();
40
+ const client = useViaxClient();
41
+ const updateMutation = useUpdatePaymentMethodMutation(client);
42
+ const [postalCode, setPostalCode] = useState('');
43
+ const [cardError, setCardError] = useState(null);
44
+ const [isSubmitting, setIsSubmitting] = useState(false);
45
+ const handleSubmit = (event) => __awaiter(void 0, void 0, void 0, function* () {
46
+ event.preventDefault();
47
+ setCardError(null);
48
+ if (!stripe || !elements) {
49
+ return;
50
+ }
51
+ const cardNumber = elements.getElement(CardNumberElement);
52
+ if (!cardNumber) {
53
+ return;
54
+ }
55
+ const trimmedPostal = postalCode.trim();
56
+ if (!trimmedPostal) {
57
+ setCardError(formatMessage(messages['manage.updatePayment.postalRequired']));
58
+ return;
59
+ }
60
+ setIsSubmitting(true);
61
+ try {
62
+ const { error, paymentMethod } = yield stripe.createPaymentMethod({
63
+ type: 'card',
64
+ card: cardNumber,
65
+ billing_details: {
66
+ address: {
67
+ postal_code: trimmedPostal,
68
+ },
69
+ },
70
+ });
71
+ if (error || !(paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.id)) {
72
+ setCardError((error === null || error === void 0 ? void 0 : error.message) || formatMessage(messages['manage.updatePayment.error']));
73
+ return;
74
+ }
75
+ yield updateMutation.mutateAsync({
76
+ biId: subscriptionBiId,
77
+ tStripePaymentMethodId: paymentMethod.id,
78
+ });
79
+ onSuccess();
80
+ }
81
+ catch (err) {
82
+ const message = err instanceof Error && err.message
83
+ ? err.message
84
+ : formatMessage(messages['manage.updatePayment.error']);
85
+ setCardError(message);
86
+ }
87
+ finally {
88
+ setIsSubmitting(false);
89
+ }
90
+ });
91
+ return (_jsxs("form", { className: "manage-update-payment", onSubmit: handleSubmit, children: [_jsx("p", { className: "manage-update-payment__intro text-primary-500 mb-4", children: formatMessage(messages['manage.updatePayment.intro']) }), _jsx("h3", { className: "manage-update-payment__section font-weight-bold text-primary-500 mb-3", children: formatMessage(messages['manage.updatePayment.sectionTitle']) }), _jsxs("div", { className: "manage-update-payment__row manage-update-payment__row--card mb-0", children: [_jsxs(Form.Group, { className: "manage-update-payment__field manage-update-payment__field--card-number mb-3", children: [_jsx(Form.Label, { className: "manage-update-payment__label d-block text-primary-500 mb-1", children: formatMessage(messages['manage.updatePayment.cardNumber']) }), _jsx("div", { className: "manage-update-payment__element bg-white d-flex align-items-center", children: _jsx(CardNumberElement, { options: {
92
+ style: ELEMENT_STYLE,
93
+ showIcon: true,
94
+ placeholder: '1234 1234 1234 1234',
95
+ } }) })] }), _jsxs(Form.Group, { className: "manage-update-payment__field manage-update-payment__field--cvc mb-3", children: [_jsx(Form.Label, { className: "manage-update-payment__label d-block text-primary-500 mb-1", children: formatMessage(messages['manage.updatePayment.cvc']) }), _jsxs("div", { className: "manage-update-payment__element manage-update-payment__element--cvc bg-white d-flex align-items-center", children: [_jsx(CardCvcElement, { options: { style: ELEMENT_STYLE, placeholder: 'CVC' } }), _jsx(Icon, { src: CreditCard, className: "manage-update-payment__cvc-icon", "aria-hidden": true })] })] }), _jsxs(Form.Group, { className: "manage-update-payment__field manage-update-payment__field--expiry mb-3", children: [_jsx(Form.Label, { className: "manage-update-payment__label d-block text-primary-500 mb-1", children: formatMessage(messages['manage.updatePayment.expiry']) }), _jsx("div", { className: "manage-update-payment__element bg-white d-flex align-items-center", children: _jsx(CardExpiryElement, { options: { style: ELEMENT_STYLE, placeholder: 'MM / YY' } }) })] })] }), _jsx("div", { className: "manage-update-payment__row manage-update-payment__row--postal mb-0", children: _jsxs(Form.Group, { className: "manage-update-payment__field manage-update-payment__field--postal mb-3", children: [_jsx(Form.Label, { className: "manage-update-payment__label d-block text-primary-500 mb-1", children: formatMessage(messages['manage.updatePayment.postal']) }), _jsx("div", { className: "manage-update-payment__element bg-white d-flex align-items-center", children: _jsx("input", { className: "manage-update-payment__control w-100 m-0 p-0 bg-transparent border-0", type: "text", name: "postal-code", value: postalCode, onChange: (e) => setPostalCode(e.target.value), autoComplete: "postal-code", required: true }) })] }) }), cardError && (_jsx(Alert, { variant: "danger", className: "mt-3 mb-0", children: cardError })), _jsxs(ActionRow, { className: "manage-update-payment__actions mt-4 w-100 justify-content-end flex-wrap flex-column-reverse flex-sm-row align-items-stretch align-items-sm-center", children: [_jsx(Button, { type: "button", variant: "tertiary", className: "w-100 w-sm-auto", onClick: onClose, disabled: isSubmitting, children: formatMessage(messages['manage.updatePayment.close']) }), _jsx(Button, { type: "submit", variant: "primary", className: "manage-btn manage-btn--dark w-100 w-sm-auto", disabled: !stripe || isSubmitting, children: isSubmitting
96
+ ? formatMessage(messages['manage.updatePayment.submitting'])
97
+ : formatMessage(messages['manage.updatePayment.submit']) })] })] }));
98
+ };
99
+ const UpdatePaymentMethodModal = ({ isOpen, onClose, subscriptionBiId, nextBillingDate, }) => {
100
+ const { formatMessage } = useIntl();
101
+ const config = getAppConfig(appId);
102
+ const publishableKey = config.STRIPE_PUBLIC_KEY || '';
103
+ const [stripePromise, setStripePromise] = useState(null);
104
+ const [step, setStep] = useState('form');
105
+ useEffect(() => {
106
+ if (!publishableKey) {
107
+ setStripePromise(null);
108
+ return;
109
+ }
110
+ setStripePromise(loadStripe(publishableKey));
111
+ }, [publishableKey]);
112
+ useEffect(() => {
113
+ if (isOpen) {
114
+ setStep('form');
115
+ }
116
+ }, [isOpen]);
117
+ const handleClose = useCallback(() => {
118
+ setStep('form');
119
+ onClose();
120
+ }, [onClose]);
121
+ const title = step === 'success'
122
+ ? formatMessage(messages['manage.updatePayment.successTitle'])
123
+ : formatMessage(messages['manage.updatePayment.title']);
124
+ const canShowForm = Boolean(publishableKey && subscriptionBiId && stripePromise);
125
+ const elementsOptions = useMemo(() => ({
126
+ fonts: [{ cssSrc: 'https://fonts.googleapis.com/css?family=Open+Sans' }],
127
+ }), []);
128
+ return (_jsxs(ModalDialog, { title: title, isOpen: isOpen, onClose: handleClose, size: "lg", hasCloseButton: true, isOverflowVisible: false, isFullscreenOnMobile: true, className: "manage-update-payment-modal", children: [_jsx(ModalDialog.Header, { children: _jsx(ModalDialog.Title, { children: title }) }), _jsx(ModalDialog.Body, { children: step === 'success' ? (_jsxs("div", { className: "manage-update-payment manage-update-payment--success", children: [_jsx("p", { className: "manage-update-payment__intro text-primary-500 mb-0", children: nextBillingDate
129
+ ? formatMessage(messages['manage.updatePayment.successBody'], {
130
+ date: nextBillingDate,
131
+ })
132
+ : formatMessage(messages['manage.updatePayment.successBodyNoDate']) }), _jsx(ActionRow, { className: "manage-update-payment__actions mt-4 w-100 justify-content-end flex-wrap", children: _jsx(Button, { variant: "primary", className: "manage-btn manage-btn--dark", onClick: handleClose, children: formatMessage(messages['manage.updatePayment.close']) }) })] })) : !canShowForm ? (_jsx(Alert, { variant: "warning", children: formatMessage(messages['manage.updatePayment.stripeMissing']) })) : (_jsx(Elements, { stripe: stripePromise, options: elementsOptions, children: _jsx(PaymentForm, { subscriptionBiId: subscriptionBiId, onClose: handleClose, onSuccess: () => setStep('success') }) })) })] }));
133
+ };
134
+ export default UpdatePaymentMethodModal;
135
+ //# sourceMappingURL=UpdatePaymentMethodModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdatePaymentMethodModal.js","sourceRoot":"","sources":["../../../src/components/UpdatePaymentMethodModal/UpdatePaymentMethodModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Alert,\n Form,\n ModalDialog,\n Button,\n ActionRow,\n Icon,\n} from '@openedx/paragon';\nimport { getAppConfig, useIntl } from '@openedx/frontend-base';\nimport { CreditCard } from '@openedx/paragon/icons';\nimport {\n Elements,\n CardNumberElement,\n CardCvcElement,\n CardExpiryElement,\n useElements,\n useStripe,\n} from '@stripe/react-stripe-js';\nimport { loadStripe, type Stripe } from '@stripe/stripe-js';\n\nimport { appId } from '../../constants';\nimport {\n useUpdatePaymentMethodMutation,\n useViaxClient,\n} from '../../data/hooks/useManageQueries';\nimport messages from '../messages';\n\nconst ELEMENT_STYLE = {\n base: {\n color: '#00262b',\n fontSize: '16px',\n lineHeight: '24px',\n fontFamily: '\"Open Sans\", \"Helvetica Neue\", Arial, sans-serif',\n fontSmoothing: 'antialiased',\n '::placeholder': {\n color: '#707070',\n },\n },\n invalid: {\n color: '#b91c1c',\n iconColor: '#b91c1c',\n },\n};\n\ninterface UpdatePaymentMethodModalProps {\n isOpen: boolean,\n onClose: () => void,\n subscriptionBiId: string | null | undefined,\n nextBillingDate: string | null,\n}\n\ninterface PaymentFormProps {\n subscriptionBiId: string,\n onClose: () => void,\n onSuccess: () => void,\n}\n\nconst PaymentForm: React.FC<PaymentFormProps> = ({\n subscriptionBiId,\n onClose,\n onSuccess,\n}) => {\n const { formatMessage } = useIntl();\n const stripe = useStripe();\n const elements = useElements();\n const client = useViaxClient();\n const updateMutation = useUpdatePaymentMethodMutation(client);\n\n const [postalCode, setPostalCode] = useState('');\n const [cardError, setCardError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const handleSubmit = async (event: React.FormEvent) => {\n event.preventDefault();\n setCardError(null);\n\n if (!stripe || !elements) {\n return;\n }\n\n const cardNumber = elements.getElement(CardNumberElement);\n if (!cardNumber) {\n return;\n }\n\n const trimmedPostal = postalCode.trim();\n if (!trimmedPostal) {\n setCardError(formatMessage(messages['manage.updatePayment.postalRequired']));\n return;\n }\n\n setIsSubmitting(true);\n try {\n const { error, paymentMethod } = await stripe.createPaymentMethod({\n type: 'card',\n card: cardNumber,\n billing_details: {\n address: {\n postal_code: trimmedPostal,\n },\n },\n });\n\n if (error || !paymentMethod?.id) {\n setCardError(error?.message || formatMessage(messages['manage.updatePayment.error']));\n return;\n }\n\n await updateMutation.mutateAsync({\n biId: subscriptionBiId,\n tStripePaymentMethodId: paymentMethod.id,\n });\n onSuccess();\n } catch (err) {\n const message = err instanceof Error && err.message\n ? err.message\n : formatMessage(messages['manage.updatePayment.error']);\n setCardError(message);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <form className=\"manage-update-payment\" onSubmit={handleSubmit}>\n <p className=\"manage-update-payment__intro text-primary-500 mb-4\">\n {formatMessage(messages['manage.updatePayment.intro'])}\n </p>\n\n <h3 className=\"manage-update-payment__section font-weight-bold text-primary-500 mb-3\">\n {formatMessage(messages['manage.updatePayment.sectionTitle'])}\n </h3>\n\n <div className=\"manage-update-payment__row manage-update-payment__row--card mb-0\">\n <Form.Group className=\"manage-update-payment__field manage-update-payment__field--card-number mb-3\">\n <Form.Label className=\"manage-update-payment__label d-block text-primary-500 mb-1\">\n {formatMessage(messages['manage.updatePayment.cardNumber'])}\n </Form.Label>\n <div className=\"manage-update-payment__element bg-white d-flex align-items-center\">\n <CardNumberElement\n options={{\n style: ELEMENT_STYLE,\n showIcon: true,\n placeholder: '1234 1234 1234 1234',\n }}\n />\n </div>\n </Form.Group>\n\n <Form.Group className=\"manage-update-payment__field manage-update-payment__field--cvc mb-3\">\n <Form.Label className=\"manage-update-payment__label d-block text-primary-500 mb-1\">\n {formatMessage(messages['manage.updatePayment.cvc'])}\n </Form.Label>\n <div className=\"manage-update-payment__element manage-update-payment__element--cvc bg-white d-flex align-items-center\">\n <CardCvcElement options={{ style: ELEMENT_STYLE, placeholder: 'CVC' }} />\n <Icon\n src={CreditCard}\n className=\"manage-update-payment__cvc-icon\"\n aria-hidden\n />\n </div>\n </Form.Group>\n\n <Form.Group className=\"manage-update-payment__field manage-update-payment__field--expiry mb-3\">\n <Form.Label className=\"manage-update-payment__label d-block text-primary-500 mb-1\">\n {formatMessage(messages['manage.updatePayment.expiry'])}\n </Form.Label>\n <div className=\"manage-update-payment__element bg-white d-flex align-items-center\">\n <CardExpiryElement options={{ style: ELEMENT_STYLE, placeholder: 'MM / YY' }} />\n </div>\n </Form.Group>\n </div>\n\n <div className=\"manage-update-payment__row manage-update-payment__row--postal mb-0\">\n <Form.Group className=\"manage-update-payment__field manage-update-payment__field--postal mb-3\">\n <Form.Label className=\"manage-update-payment__label d-block text-primary-500 mb-1\">\n {formatMessage(messages['manage.updatePayment.postal'])}\n </Form.Label>\n <div className=\"manage-update-payment__element bg-white d-flex align-items-center\">\n <input\n className=\"manage-update-payment__control w-100 m-0 p-0 bg-transparent border-0\"\n type=\"text\"\n name=\"postal-code\"\n value={postalCode}\n onChange={(e) => setPostalCode(e.target.value)}\n autoComplete=\"postal-code\"\n required\n />\n </div>\n </Form.Group>\n </div>\n\n {cardError && (\n <Alert variant=\"danger\" className=\"mt-3 mb-0\">\n {cardError}\n </Alert>\n )}\n\n <ActionRow className=\"manage-update-payment__actions mt-4 w-100 justify-content-end flex-wrap flex-column-reverse flex-sm-row align-items-stretch align-items-sm-center\">\n <Button\n type=\"button\"\n variant=\"tertiary\"\n className=\"w-100 w-sm-auto\"\n onClick={onClose}\n disabled={isSubmitting}\n >\n {formatMessage(messages['manage.updatePayment.close'])}\n </Button>\n <Button\n type=\"submit\"\n variant=\"primary\"\n className=\"manage-btn manage-btn--dark w-100 w-sm-auto\"\n disabled={!stripe || isSubmitting}\n >\n {isSubmitting\n ? formatMessage(messages['manage.updatePayment.submitting'])\n : formatMessage(messages['manage.updatePayment.submit'])}\n </Button>\n </ActionRow>\n </form>\n );\n};\n\nconst UpdatePaymentMethodModal: React.FC<UpdatePaymentMethodModalProps> = ({\n isOpen,\n onClose,\n subscriptionBiId,\n nextBillingDate,\n}) => {\n const { formatMessage } = useIntl();\n const config = getAppConfig(appId);\n const publishableKey = (config.STRIPE_PUBLIC_KEY as string | undefined) || '';\n const [stripePromise, setStripePromise] = useState<Promise<Stripe | null> | null>(null);\n const [step, setStep] = useState<'form' | 'success'>('form');\n\n useEffect(() => {\n if (!publishableKey) {\n setStripePromise(null);\n return;\n }\n setStripePromise(loadStripe(publishableKey));\n }, [publishableKey]);\n\n useEffect(() => {\n if (isOpen) {\n setStep('form');\n }\n }, [isOpen]);\n\n const handleClose = useCallback(() => {\n setStep('form');\n onClose();\n }, [onClose]);\n\n const title = step === 'success'\n ? formatMessage(messages['manage.updatePayment.successTitle'])\n : formatMessage(messages['manage.updatePayment.title']);\n\n const canShowForm = Boolean(publishableKey && subscriptionBiId && stripePromise);\n\n const elementsOptions = useMemo(() => ({\n fonts: [{ cssSrc: 'https://fonts.googleapis.com/css?family=Open+Sans' }],\n }), []);\n\n return (\n <ModalDialog\n title={title}\n isOpen={isOpen}\n onClose={handleClose}\n size=\"lg\"\n hasCloseButton\n isOverflowVisible={false}\n isFullscreenOnMobile\n className=\"manage-update-payment-modal\"\n >\n <ModalDialog.Header>\n <ModalDialog.Title>{title}</ModalDialog.Title>\n </ModalDialog.Header>\n\n <ModalDialog.Body>\n {step === 'success' ? (\n <div className=\"manage-update-payment manage-update-payment--success\">\n <p className=\"manage-update-payment__intro text-primary-500 mb-0\">\n {nextBillingDate\n ? formatMessage(messages['manage.updatePayment.successBody'], {\n date: nextBillingDate,\n })\n : formatMessage(messages['manage.updatePayment.successBodyNoDate'])}\n </p>\n <ActionRow className=\"manage-update-payment__actions mt-4 w-100 justify-content-end flex-wrap\">\n <Button\n variant=\"primary\"\n className=\"manage-btn manage-btn--dark\"\n onClick={handleClose}\n >\n {formatMessage(messages['manage.updatePayment.close'])}\n </Button>\n </ActionRow>\n </div>\n ) : !canShowForm ? (\n <Alert variant=\"warning\">\n {formatMessage(messages['manage.updatePayment.stripeMissing'])}\n </Alert>\n ) : (\n <Elements stripe={stripePromise} options={elementsOptions}>\n <PaymentForm\n subscriptionBiId={subscriptionBiId!}\n onClose={handleClose}\n onSuccess={() => setStep('success')}\n />\n </Elements>\n )}\n </ModalDialog.Body>\n </ModalDialog>\n );\n};\n\nexport default UpdatePaymentMethodModal;\n"]}