@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
@@ -8,32 +8,43 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  export function createGqlClient({ apiUrl }) {
11
- if (!apiUrl)
11
+ if (!apiUrl) {
12
12
  throw new Error('createGqlClient: apiUrl is required');
13
+ }
13
14
  let token = null;
14
15
  const setToken = (raw) => {
16
+ if (!raw) {
17
+ token = null;
18
+ return;
19
+ }
15
20
  token = raw.startsWith('Bearer ') ? raw : `Bearer ${raw}`;
16
21
  };
17
- const gql = (query_1, variables_1, ...args_1) => __awaiter(this, [query_1, variables_1, ...args_1], void 0, function* (query, variables, retry = false) {
22
+ const gql = (query, variables) => __awaiter(this, void 0, void 0, function* () {
18
23
  var _a, _b;
19
- if (!token)
20
- throw new Error('No viax token available. Please try placing your order again.');
24
+ const headers = {
25
+ 'Content-Type': 'application/json',
26
+ };
27
+ if (token) {
28
+ headers.Authorization = token;
29
+ }
21
30
  const res = yield fetch(apiUrl, {
22
31
  method: 'POST',
23
- headers: { 'Content-Type': 'application/json', Authorization: token },
32
+ headers,
24
33
  body: JSON.stringify({ query, variables }),
25
34
  });
26
- if (res.status === 401 && !retry) {
27
- token = null;
28
- throw new Error('Session expired. Please try placing your order again.');
35
+ if (!res.ok) {
36
+ throw new Error(`VIAX request failed (${res.status}). Please try again.`);
29
37
  }
30
38
  const json = yield res.json();
31
39
  if ((_a = json.errors) === null || _a === void 0 ? void 0 : _a.length) {
32
- const msg = ((_b = json.errors[0]) === null || _b === void 0 ? void 0 : _b.message) || 'GraphQL error';
33
- throw new Error(msg);
40
+ throw new Error(((_b = json.errors[0]) === null || _b === void 0 ? void 0 : _b.message) || 'GraphQL error');
34
41
  }
35
42
  return json.data;
36
43
  });
37
- return { gql, setToken };
44
+ return {
45
+ gql,
46
+ setToken,
47
+ hasToken: () => Boolean(token),
48
+ };
38
49
  }
39
50
  //# sourceMappingURL=graphqlClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graphqlClient.js","sourceRoot":"","sources":["../../src/utils/graphqlClient.ts"],"names":[],"mappings":";;;;;;;;;AAiBA,MAAM,UAAU,eAAe,CAC7B,EAAE,MAAM,EAAsB;IAE9B,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAEpE,IAAI,KAAK,GAAkB,IAAI,CAAC;IAEhC,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAQ,EAAE;QACrC,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,GAAG,EAAE,CAAC;IAC5D,CAAC,CAAC;IAEF,MAAM,GAAG,GAAc,kCAAwC,EAAE,uEAAnC,KAAK,EAAE,SAAS,EAAE,KAAK,GAAG,KAAK;;QAC3D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QAE7F,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;YAC9B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,EAAE;YACrE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YACjC,KAAK,GAAG,IAAI,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,IAAI,GAAgB,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,MAAA,IAAI,CAAC,MAAM,0CAAE,MAAM,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,CAAA,MAAA,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,0CAAE,OAAO,KAAI,eAAe,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC,CAAA,CAAC;IAEF,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["/**\n * api/graphqlClient.ts — authed GraphQL client.\n *\n * No token is required at construction. Call setToken(viaxToken) after\n * GET /edx-session returns — typically on checkout page mount.\n *\n * On 401 the token is cleared and the request fails — the mutation will\n * surface the error and the user can retry.\n */\nimport type { GqlRunner } from '../types';\n\ninterface GqlResponse {\n\n data?: any,\n errors?: { message?: string }[],\n}\n\nexport function createGqlClient(\n { apiUrl }: { apiUrl: string },\n): { gql: GqlRunner, setToken: (token: string) => void } {\n if (!apiUrl) throw new Error('createGqlClient: apiUrl is required');\n\n let token: string | null = null;\n\n const setToken = (raw: string): void => {\n token = raw.startsWith('Bearer ') ? raw : `Bearer ${raw}`;\n };\n\n const gql: GqlRunner = async (query, variables, retry = false) => {\n if (!token) throw new Error('No viax token available. Please try placing your order again.');\n\n const res = await fetch(apiUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Authorization: token },\n body: JSON.stringify({ query, variables }),\n });\n\n if (res.status === 401 && !retry) {\n token = null;\n throw new Error('Session expired. Please try placing your order again.');\n }\n\n const json: GqlResponse = await res.json();\n if (json.errors?.length) {\n const msg = json.errors[0]?.message || 'GraphQL error';\n throw new Error(msg);\n }\n return json.data;\n };\n\n return { gql, setToken };\n}\n"]}
1
+ {"version":3,"file":"graphqlClient.js","sourceRoot":"","sources":["../../src/utils/graphqlClient.ts"],"names":[],"mappings":";;;;;;;;;AAmBA,MAAM,UAAU,eAAe,CAC7B,EAAE,MAAM,EAAsB;IAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,KAAK,GAAkB,IAAI,CAAC;IAEhC,MAAM,QAAQ,GAAG,CAAC,GAAkB,EAAQ,EAAE;QAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,KAAK,GAAG,IAAI,CAAC;YACb,OAAO;QACT,CAAC;QACD,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,GAAG,EAAE,CAAC;IAC5D,CAAC,CAAC;IAEF,MAAM,GAAG,GAAc,CAAO,KAAK,EAAE,SAAS,EAAE,EAAE;;QAChD,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;SACnC,CAAC;QACF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,aAAa,GAAG,KAAK,CAAC;QAChC,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;YAC9B,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,MAAM,sBAAsB,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,IAAI,GAAgB,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,MAAA,IAAI,CAAC,MAAM,0CAAE,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,CAAA,MAAA,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,0CAAE,OAAO,KAAI,eAAe,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC,CAAA,CAAC;IAEF,OAAO;QACL,GAAG;QACH,QAAQ;QACR,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KAC/B,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Minimal GraphQL client for VIAX.\n *\n * Authenticated calls (subscriber check, enrollments, cancel) require setToken()\n * after exchanging the edX session for a Viax JWT.\n */\nimport type { GqlRunner } from '../types';\n\ninterface GqlResponse {\n data?: any,\n errors?: { message?: string }[],\n}\n\nexport interface ViaxGqlClient {\n gql: GqlRunner,\n setToken: (token: string | null) => void,\n hasToken: () => boolean,\n}\n\nexport function createGqlClient(\n { apiUrl }: { apiUrl: string },\n): ViaxGqlClient {\n if (!apiUrl) {\n throw new Error('createGqlClient: apiUrl is required');\n }\n\n let token: string | null = null;\n\n const setToken = (raw: string | null): void => {\n if (!raw) {\n token = null;\n return;\n }\n token = raw.startsWith('Bearer ') ? raw : `Bearer ${raw}`;\n };\n\n const gql: GqlRunner = async (query, variables) => {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (token) {\n headers.Authorization = token;\n }\n\n const res = await fetch(apiUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({ query, variables }),\n });\n\n if (!res.ok) {\n throw new Error(`VIAX request failed (${res.status}). Please try again.`);\n }\n\n const json: GqlResponse = await res.json();\n if (json.errors?.length) {\n throw new Error(json.errors[0]?.message || 'GraphQL error');\n }\n return json.data;\n };\n\n return {\n gql,\n setToken,\n hasToken: () => Boolean(token),\n };\n}\n"]}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Money helpers for TwouInvoice billFinancialCharges amounts.
3
+ *
4
+ * Newer invoices store major units (e.g. 11.00); some older rows are still in
5
+ * minor units / cents (e.g. 11100) pending a backfill.
6
+ */
7
+ /** Normalize a raw Viax amount into major currency units. */
8
+ export declare function normalizeInvoiceAmount(raw: unknown): number;
9
+ /** Sum fichAmount values from billFinancialCharges. */
10
+ export declare function sumFinancialCharges(charges: {
11
+ fichAmount?: {
12
+ amount?: unknown;
13
+ units?: {
14
+ code?: string;
15
+ } | null;
16
+ } | null;
17
+ }[] | null | undefined): {
18
+ amount: number;
19
+ currency: string;
20
+ };
21
+ /** Format major-unit amount for display, e.g. "$59.00 USD". */
22
+ export declare function formatMoney(amount: number, currency?: string, locale?: string): string;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Money helpers for TwouInvoice billFinancialCharges amounts.
3
+ *
4
+ * Newer invoices store major units (e.g. 11.00); some older rows are still in
5
+ * minor units / cents (e.g. 11100) pending a backfill.
6
+ */
7
+ /** Normalize a raw Viax amount into major currency units. */
8
+ export function normalizeInvoiceAmount(raw) {
9
+ if (raw == null || raw === '') {
10
+ return 0;
11
+ }
12
+ const asString = String(raw).trim();
13
+ const value = Number(asString);
14
+ if (!Number.isFinite(value)) {
15
+ return 0;
16
+ }
17
+ // Explicit decimal → already major units (e.g. "11.00", "59.99").
18
+ if (asString.includes('.')) {
19
+ return value;
20
+ }
21
+ // Whole numbers ≥ 1000 are treated as cents until the backfill lands
22
+ // (e.g. 11100 → 111.00). Smaller integers stay as major units (e.g. 59).
23
+ if (Number.isInteger(value) && Math.abs(value) >= 1000) {
24
+ return value / 100;
25
+ }
26
+ return value;
27
+ }
28
+ /** Sum fichAmount values from billFinancialCharges. */
29
+ export function sumFinancialCharges(charges) {
30
+ if (!Array.isArray(charges) || charges.length === 0) {
31
+ return { amount: 0, currency: 'USD' };
32
+ }
33
+ let total = 0;
34
+ let currency = 'USD';
35
+ charges.forEach((charge) => {
36
+ var _a, _b, _c;
37
+ total += normalizeInvoiceAmount((_a = charge === null || charge === void 0 ? void 0 : charge.fichAmount) === null || _a === void 0 ? void 0 : _a.amount);
38
+ const code = (_c = (_b = charge === null || charge === void 0 ? void 0 : charge.fichAmount) === null || _b === void 0 ? void 0 : _b.units) === null || _c === void 0 ? void 0 : _c.code;
39
+ if (code) {
40
+ currency = code;
41
+ }
42
+ });
43
+ return { amount: total, currency };
44
+ }
45
+ /** Format major-unit amount for display, e.g. "$59.00 USD". */
46
+ export function formatMoney(amount, currency = 'USD', locale = 'en-US') {
47
+ try {
48
+ const formatted = new Intl.NumberFormat(locale, {
49
+ style: 'currency',
50
+ currency,
51
+ currencyDisplay: 'symbol',
52
+ }).format(amount);
53
+ return `${formatted} ${currency}`;
54
+ }
55
+ catch (_a) {
56
+ return `$${amount.toFixed(2)} ${currency}`;
57
+ }
58
+ }
59
+ //# sourceMappingURL=invoiceAmount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoiceAmount.js","sourceRoot":"","sources":["../../src/utils/invoiceAmount.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,6DAA6D;AAC7D,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,kEAAkE;IAClE,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qEAAqE;IACrE,yEAAyE;IACzE,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QACvD,OAAO,KAAK,GAAG,GAAG,CAAC;IACrB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,mBAAmB,CACjC,OAA4G;IAE5G,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;;QACzB,KAAK,IAAI,sBAAsB,CAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,0CAAE,MAAM,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,MAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,0CAAE,KAAK,0CAAE,IAAI,CAAC;QAC7C,IAAI,IAAI,EAAE,CAAC;YACT,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACrC,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,QAAQ,GAAG,KAAK,EAChB,MAAM,GAAG,OAAO;IAEhB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;YAC9C,KAAK,EAAE,UAAU;YACjB,QAAQ;YACR,eAAe,EAAE,QAAQ;SAC1B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAClB,OAAO,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC;IACpC,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;IAC7C,CAAC;AACH,CAAC","sourcesContent":["/**\n * Money helpers for TwouInvoice billFinancialCharges amounts.\n *\n * Newer invoices store major units (e.g. 11.00); some older rows are still in\n * minor units / cents (e.g. 11100) pending a backfill.\n */\n\n/** Normalize a raw Viax amount into major currency units. */\nexport function normalizeInvoiceAmount(raw: unknown): number {\n if (raw == null || raw === '') {\n return 0;\n }\n\n const asString = String(raw).trim();\n const value = Number(asString);\n if (!Number.isFinite(value)) {\n return 0;\n }\n\n // Explicit decimal → already major units (e.g. \"11.00\", \"59.99\").\n if (asString.includes('.')) {\n return value;\n }\n\n // Whole numbers ≥ 1000 are treated as cents until the backfill lands\n // (e.g. 11100 → 111.00). Smaller integers stay as major units (e.g. 59).\n if (Number.isInteger(value) && Math.abs(value) >= 1000) {\n return value / 100;\n }\n\n return value;\n}\n\n/** Sum fichAmount values from billFinancialCharges. */\nexport function sumFinancialCharges(\n charges: { fichAmount?: { amount?: unknown, units?: { code?: string } | null } | null }[] | null | undefined,\n): { amount: number, currency: string } {\n if (!Array.isArray(charges) || charges.length === 0) {\n return { amount: 0, currency: 'USD' };\n }\n\n let total = 0;\n let currency = 'USD';\n charges.forEach((charge) => {\n total += normalizeInvoiceAmount(charge?.fichAmount?.amount);\n const code = charge?.fichAmount?.units?.code;\n if (code) {\n currency = code;\n }\n });\n\n return { amount: total, currency };\n}\n\n/** Format major-unit amount for display, e.g. \"$59.00 USD\". */\nexport function formatMoney(\n amount: number,\n currency = 'USD',\n locale = 'en-US',\n): string {\n try {\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n currencyDisplay: 'symbol',\n }).format(amount);\n return `${formatted} ${currency}`;\n } catch {\n return `$${amount.toFixed(2)} ${currency}`;\n }\n}\n"]}
@@ -1,35 +1,40 @@
1
1
  /**
2
- * api/queries.ts — GraphQL documents for the checkout flow.
3
- * Kept as plain strings so they can be reused, logged, or tested in isolation.
4
- *
5
- * Mutation reference (from API doc):
6
- * updateTwouCustomer — toggle Stripe test clock on/off
7
- * createTwouCart — user proceeds to payment
8
- * updateTwouCartItem — attach billing plan / payment method to cart
9
- * updateTwouCart — persist auto-renewal consent (SUBS-228)
10
- * startBusinessProcessableTransition — place order
11
- * updateTwouCartItem — retry: attach new payment method
12
- */
13
- /** Creates a new cart during checkout. */
14
- export declare const CREATE_CART = "mutation CreateCart($input: TwouCartInput!) {\n createTwouCart(input: $input) { biId uid }\n}";
15
- /** Updates a cart item — attach billing plan / payment method. */
16
- export declare const UPDATE_CART_ITEM = "mutation UpdateCartItem($input: TwouCartItemInput!) {\n updateTwouCartItem(input: $input) { uid }\n}";
17
- /** Persists auto-renewal consent fields on the TwouCart BI (SUBS-228). */
18
- export declare const UPDATE_CART = "mutation UpdateCart($input: TwouCartInput!) {\n updateTwouCart(input: $input) { uid }\n}";
19
- /** Triggers the backend workflow to place the order. */
20
- export declare const PLACE_ORDER = "mutation PlaceOrder($input: StartBusinessProcessableTransitionInput!) {\n startBusinessProcessableTransition(input: $input) { uid bpStatus { code } }\n}";
21
- export declare const GET_CART_ITEM = "query GetCartItem($biId: String!) {\n getBusinessInteraction(biId: $biId) {\n uid\n hiConsistsOf { ... on TwouCartItem { uid } }\n }\n}";
22
- export declare const GET_CART_STATUS = "query GetCartStatus($biId: String!) {\n getBusinessInteraction(biId: $biId) {\n bpStatus { code }\n hiConsistsOf { ... on TwouCartItem { tStripeSubscriptionId } }\n ... on TwouCart {\n cmComments { edges { node { comText } } }\n }\n }\n}";
23
- export declare const FIND_SUBSCRIPTION = "query FindSubscription($filter: String!) {\n filterTwouSubscription(_first: 1, _filter: $filter) {\n edges {\n node {\n biId\n tTrialStart\n tTrialEnd\n tRenewalType\n hiConsistsOf {\n ... on TwouSubscriptionItem {\n paybBillingPlan {\n tStripePriceId\n bipOwnershipModel { omName }\n }\n paybPayment {\n ... on TwouStripePayment {\n tStripePaymentMethodId\n tPaymentMethodLast4\n tPaymentMethodBrand\n }\n }\n }\n }\n }\n }\n }\n}";
24
- /** Fetch the viax customer uid by email using filterTwouCustomer. */
25
- export declare const GET_CUSTOMER = "query GetCustomer($filter: String!) {\n filterTwouCustomer(_first: 1, _filter: $filter) {\n edges {\n node {\n uid\n parId\n parParty {\n paName\n paContacts {\n edges {\n node {\n ... on EmailAddressContactMedium {\n email\n }\n }\n }\n }\n ... on Individual {\n indFirstName\n indLastName\n }\n }\n }\n }\n }\n}";
26
- /** Fetch the TwouSubscriptionPlan uid to use as biiSalable in createTwouCart. */
27
- export declare const GET_PRODUCT = "query GetProduct($maId: String!) {\n getProduct(maId: $maId) {\n maName\n uid\n ... on TwouSubscriptionPlan {\n saOwnershipModels {\n uid\n omName\n }\n }\n }\n}";
28
- export declare const GET_BILLING_PLANS = "query GetBillingPlans {\n filterCustomerBillingPlan(_first: 10) {\n edges {\n node {\n uid\n tStripePriceId\n tStripeAmount {\n amount\n units { code }\n }\n bipIsTemplate\n bipOwnershipModel { uid omName }\n }\n }\n }\n}";
29
- /** Fetch the number of active subscriptions — unauthenticated. */
30
- export declare const GET_ACTIVE_SUBSCRIPTIONS_STATE = "query activeSubscriptions {\n tActiveSubscriptionsState\n}";
31
- /** Check whether the currently authenticated user already has an active subscription.
32
- * tIsCurrentUserSubscriber is a JSON scalar — returns the full object, no subfield selection allowed. */
2
+ * GraphQL documents for the manage-subscription MFE.
3
+ */
4
+ /**
5
+ * tIsCurrentUserSubscriber is a JSON scalar — returns the full object;
6
+ * no subfield selection is allowed.
7
+ */
33
8
  export declare const GET_IS_CURRENT_USER_SUBSCRIBER = "query IsCurrentUserSubscriber {\n tIsCurrentUserSubscriber\n}";
34
- /** Fetch a course for the enrollment card when ?course_run_key= is present. */
35
- export declare const GET_COURSE_DETAIL = "query CourseDetail($filter: String!) {\n filterTwouCourse(_first: 1, _filter: $filter) {\n edges {\n node {\n maId\n maName\n maDescription\n tShortDescription\n imageUrl\n tCourseKey\n tBrandText\n tPrimarySubjectArea\n tLevelType\n tLanguage\n tPacingType { code }\n tDurationLow\n tDurationHigh\n tDurationUnit { code }\n tEffortLow\n tEffortHigh\n tEffortUnit { code }\n tUrlCourse\n tB2cSubscriptionInclusion\n tHasOfacRestrictions\n tCatalogActive\n }\n }\n }\n}";
9
+ /**
10
+ * Enrollments for cancel confirmation.
11
+ * Build `_filter` client-side, e.g. tSubscriptionBiId IN ('BI…', 'BI…').
12
+ */
13
+ export declare const GET_SUBSCRIPTION_ENROLLMENTS = "query EnrollmentsForSubscriptions($filter: String!) {\n filterTwouEnrollment(_first: 200, _filter: $filter) {\n edges {\n node {\n biId\n tSubscriptionBiId\n bpStatus { code }\n tCourseRunKey\n tCourse {\n maId\n maName\n imageUrl\n tBrandText\n tSchools {\n tName\n tSortValue\n }\n }\n }\n }\n }\n}";
14
+ /**
15
+ * Invoices for the learner's subscription (payment history).
16
+ * Filter is inlined client-side: biRelatesTo.biId = '<subscriptionBiId>'.
17
+ */
18
+ export declare const GET_PAYMENT_HISTORY = "query PaymentHistory($filter: String!, $first: Int!) {\n filterTwouInvoice(_first: $first, _filter: $filter) {\n edges {\n node {\n biId\n tStripeInvoiceId\n bpStatus { code name }\n billDate\n billBillingPeriod { start end }\n billFinancialCharges {\n fichAmount {\n amount\n units { code }\n }\n }\n }\n }\n }\n}";
19
+ /**
20
+ * Cancel the learner's subscription (default: at period end).
21
+ * Pass `immediate: true` to end access immediately.
22
+ */
23
+ export declare const CANCEL_SUBSCRIPTION = "mutation CancelSubscription($biId: String!, $immediate: Boolean) {\n tCancelSubscription(biId: $biId, immediate: $immediate)\n}";
24
+ /**
25
+ * Resume a cancelled subscription before the period end / cancellation date.
26
+ */
27
+ export declare const REACTIVATE_SUBSCRIPTION = "mutation ReactivateSubscription($biId: String!) {\n tReactivateSubscription(biId: $biId)\n}";
28
+ /**
29
+ * Payment method on an existing subscription (for renew / manage display).
30
+ */
31
+ export declare const GET_SUBSCRIPTION_PAYMENT_METHOD = "query SubscriptionPaymentMethod($filter: String!) {\n filterTwouSubscription(_first: 1, _filter: $filter) {\n edges {\n node {\n biId\n hiConsistsOf {\n ... on TwouSubscriptionItem {\n paybPayment {\n ... on TwouStripePayment {\n tStripePaymentMethodId\n tPaymentMethodLast4\n tPaymentMethodBrand\n }\n }\n }\n }\n }\n }\n }\n}";
32
+ /**
33
+ * Available customer billing plans (monthly / annual template prices).
34
+ * Same query as frontend-app-subscription-checkout.
35
+ */
36
+ export declare const GET_BILLING_PLANS = "query GetBillingPlans {\n filterCustomerBillingPlan(_first: 10) {\n edges {\n node {\n uid\n tStripePriceId\n tStripeAmount {\n amount\n units { code }\n }\n bipIsTemplate\n bipOwnershipModel { uid omName }\n }\n }\n }\n}";
37
+ /**
38
+ * Attach a new Stripe payment method (pm_…) as the subscription default.
39
+ */
40
+ export declare const UPDATE_SUBSCRIPTION_PAYMENT_METHOD = "mutation UpdateSubscriptionPaymentMethod(\n $biId: String!\n $tStripePaymentMethodId: String!\n) {\n tUpdateSubscriptionPaymentMethod(\n biId: $biId\n tStripePaymentMethodId: $tStripePaymentMethodId\n )\n}";
@@ -1,62 +1,85 @@
1
1
  /**
2
- * api/queries.ts — GraphQL documents for the checkout flow.
3
- * Kept as plain strings so they can be reused, logged, or tested in isolation.
4
- *
5
- * Mutation reference (from API doc):
6
- * updateTwouCustomer — toggle Stripe test clock on/off
7
- * createTwouCart — user proceeds to payment
8
- * updateTwouCartItem — attach billing plan / payment method to cart
9
- * updateTwouCart — persist auto-renewal consent (SUBS-228)
10
- * startBusinessProcessableTransition — place order
11
- * updateTwouCartItem — retry: attach new payment method
2
+ * GraphQL documents for the manage-subscription MFE.
12
3
  */
13
- // ─── Mutations ────────────────────────────────────────────────────────────────
14
- /** Creates a new cart during checkout. */
15
- export const CREATE_CART = `mutation CreateCart($input: TwouCartInput!) {
16
- createTwouCart(input: $input) { biId uid }
17
- }`;
18
- /** Updates a cart item — attach billing plan / payment method. */
19
- export const UPDATE_CART_ITEM = `mutation UpdateCartItem($input: TwouCartItemInput!) {
20
- updateTwouCartItem(input: $input) { uid }
21
- }`;
22
- /** Persists auto-renewal consent fields on the TwouCart BI (SUBS-228). */
23
- export const UPDATE_CART = `mutation UpdateCart($input: TwouCartInput!) {
24
- updateTwouCart(input: $input) { uid }
25
- }`;
26
- /** Triggers the backend workflow to place the order. */
27
- export const PLACE_ORDER = `mutation PlaceOrder($input: StartBusinessProcessableTransitionInput!) {
28
- startBusinessProcessableTransition(input: $input) { uid bpStatus { code } }
4
+ /**
5
+ * tIsCurrentUserSubscriber is a JSON scalar — returns the full object;
6
+ * no subfield selection is allowed.
7
+ */
8
+ export const GET_IS_CURRENT_USER_SUBSCRIBER = `query IsCurrentUserSubscriber {
9
+ tIsCurrentUserSubscriber
29
10
  }`;
30
- // ─── Queries ──────────────────────────────────────────────────────────────────
31
- export const GET_CART_ITEM = `query GetCartItem($biId: String!) {
32
- getBusinessInteraction(biId: $biId) {
33
- uid
34
- hiConsistsOf { ... on TwouCartItem { uid } }
11
+ /**
12
+ * Enrollments for cancel confirmation.
13
+ * Build `_filter` client-side, e.g. tSubscriptionBiId IN ('BI…', 'BI…').
14
+ */
15
+ export const GET_SUBSCRIPTION_ENROLLMENTS = `query EnrollmentsForSubscriptions($filter: String!) {
16
+ filterTwouEnrollment(_first: 200, _filter: $filter) {
17
+ edges {
18
+ node {
19
+ biId
20
+ tSubscriptionBiId
21
+ bpStatus { code }
22
+ tCourseRunKey
23
+ tCourse {
24
+ maId
25
+ maName
26
+ imageUrl
27
+ tBrandText
28
+ tSchools {
29
+ tName
30
+ tSortValue
31
+ }
32
+ }
33
+ }
34
+ }
35
35
  }
36
36
  }`;
37
- export const GET_CART_STATUS = `query GetCartStatus($biId: String!) {
38
- getBusinessInteraction(biId: $biId) {
39
- bpStatus { code }
40
- hiConsistsOf { ... on TwouCartItem { tStripeSubscriptionId } }
41
- ... on TwouCart {
42
- cmComments { edges { node { comText } } }
37
+ /**
38
+ * Invoices for the learner's subscription (payment history).
39
+ * Filter is inlined client-side: biRelatesTo.biId = '<subscriptionBiId>'.
40
+ */
41
+ export const GET_PAYMENT_HISTORY = `query PaymentHistory($filter: String!, $first: Int!) {
42
+ filterTwouInvoice(_first: $first, _filter: $filter) {
43
+ edges {
44
+ node {
45
+ biId
46
+ tStripeInvoiceId
47
+ bpStatus { code name }
48
+ billDate
49
+ billBillingPeriod { start end }
50
+ billFinancialCharges {
51
+ fichAmount {
52
+ amount
53
+ units { code }
54
+ }
55
+ }
56
+ }
43
57
  }
44
58
  }
45
59
  }`;
46
- export const FIND_SUBSCRIPTION = `query FindSubscription($filter: String!) {
60
+ /**
61
+ * Cancel the learner's subscription (default: at period end).
62
+ * Pass `immediate: true` to end access immediately.
63
+ */
64
+ export const CANCEL_SUBSCRIPTION = `mutation CancelSubscription($biId: String!, $immediate: Boolean) {
65
+ tCancelSubscription(biId: $biId, immediate: $immediate)
66
+ }`;
67
+ /**
68
+ * Resume a cancelled subscription before the period end / cancellation date.
69
+ */
70
+ export const REACTIVATE_SUBSCRIPTION = `mutation ReactivateSubscription($biId: String!) {
71
+ tReactivateSubscription(biId: $biId)
72
+ }`;
73
+ /**
74
+ * Payment method on an existing subscription (for renew / manage display).
75
+ */
76
+ export const GET_SUBSCRIPTION_PAYMENT_METHOD = `query SubscriptionPaymentMethod($filter: String!) {
47
77
  filterTwouSubscription(_first: 1, _filter: $filter) {
48
78
  edges {
49
79
  node {
50
80
  biId
51
- tTrialStart
52
- tTrialEnd
53
- tRenewalType
54
81
  hiConsistsOf {
55
82
  ... on TwouSubscriptionItem {
56
- paybBillingPlan {
57
- tStripePriceId
58
- bipOwnershipModel { omName }
59
- }
60
83
  paybPayment {
61
84
  ... on TwouStripePayment {
62
85
  tStripePaymentMethodId
@@ -70,46 +93,10 @@ export const FIND_SUBSCRIPTION = `query FindSubscription($filter: String!) {
70
93
  }
71
94
  }
72
95
  }`;
73
- /** Fetch the viax customer uid by email using filterTwouCustomer. */
74
- export const GET_CUSTOMER = `query GetCustomer($filter: String!) {
75
- filterTwouCustomer(_first: 1, _filter: $filter) {
76
- edges {
77
- node {
78
- uid
79
- parId
80
- parParty {
81
- paName
82
- paContacts {
83
- edges {
84
- node {
85
- ... on EmailAddressContactMedium {
86
- email
87
- }
88
- }
89
- }
90
- }
91
- ... on Individual {
92
- indFirstName
93
- indLastName
94
- }
95
- }
96
- }
97
- }
98
- }
99
- }`;
100
- /** Fetch the TwouSubscriptionPlan uid to use as biiSalable in createTwouCart. */
101
- export const GET_PRODUCT = `query GetProduct($maId: String!) {
102
- getProduct(maId: $maId) {
103
- maName
104
- uid
105
- ... on TwouSubscriptionPlan {
106
- saOwnershipModels {
107
- uid
108
- omName
109
- }
110
- }
111
- }
112
- }`;
96
+ /**
97
+ * Available customer billing plans (monthly / annual template prices).
98
+ * Same query as frontend-app-subscription-checkout.
99
+ */
113
100
  export const GET_BILLING_PLANS = `query GetBillingPlans {
114
101
  filterCustomerBillingPlan(_first: 10) {
115
102
  edges {
@@ -126,43 +113,16 @@ export const GET_BILLING_PLANS = `query GetBillingPlans {
126
113
  }
127
114
  }
128
115
  }`;
129
- /** Fetch the number of active subscriptions — unauthenticated. */
130
- export const GET_ACTIVE_SUBSCRIPTIONS_STATE = `query activeSubscriptions {
131
- tActiveSubscriptionsState
132
- }`;
133
- /** Check whether the currently authenticated user already has an active subscription.
134
- * tIsCurrentUserSubscriber is a JSON scalar — returns the full object, no subfield selection allowed. */
135
- export const GET_IS_CURRENT_USER_SUBSCRIBER = `query IsCurrentUserSubscriber {
136
- tIsCurrentUserSubscriber
137
- }`;
138
- /** Fetch a course for the enrollment card when ?course_run_key= is present. */
139
- export const GET_COURSE_DETAIL = `query CourseDetail($filter: String!) {
140
- filterTwouCourse(_first: 1, _filter: $filter) {
141
- edges {
142
- node {
143
- maId
144
- maName
145
- maDescription
146
- tShortDescription
147
- imageUrl
148
- tCourseKey
149
- tBrandText
150
- tPrimarySubjectArea
151
- tLevelType
152
- tLanguage
153
- tPacingType { code }
154
- tDurationLow
155
- tDurationHigh
156
- tDurationUnit { code }
157
- tEffortLow
158
- tEffortHigh
159
- tEffortUnit { code }
160
- tUrlCourse
161
- tB2cSubscriptionInclusion
162
- tHasOfacRestrictions
163
- tCatalogActive
164
- }
165
- }
166
- }
116
+ /**
117
+ * Attach a new Stripe payment method (pm_…) as the subscription default.
118
+ */
119
+ export const UPDATE_SUBSCRIPTION_PAYMENT_METHOD = `mutation UpdateSubscriptionPaymentMethod(
120
+ $biId: String!
121
+ $tStripePaymentMethodId: String!
122
+ ) {
123
+ tUpdateSubscriptionPaymentMethod(
124
+ biId: $biId
125
+ tStripePaymentMethodId: $tStripePaymentMethodId
126
+ )
167
127
  }`;
168
128
  //# sourceMappingURL=queries.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/utils/queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,iFAAiF;AAEjF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG;;EAEzB,CAAC;AAEH,kEAAkE;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAG;;EAE9B,CAAC;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,WAAW,GAAG;;EAEzB,CAAC;AAEH,wDAAwD;AACxD,MAAM,CAAC,MAAM,WAAW,GAAG;;EAEzB,CAAC;AAEH,iFAAiF;AAEjF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;EAK3B,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;EAQ7B,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;EA0B/B,CAAC;AAEH,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;EAyB1B,CAAC;AAEH,iFAAiF;AACjF,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;EAWzB,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;EAe/B,CAAC;AAEH,kEAAkE;AAClE,MAAM,CAAC,MAAM,8BAA8B,GAAG;;EAE5C,CAAC;AAEH;0GAC0G;AAC1G,MAAM,CAAC,MAAM,8BAA8B,GAAG;;EAE5C,CAAC;AAEH,+EAA+E;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4B/B,CAAC","sourcesContent":["/**\n * api/queries.ts — GraphQL documents for the checkout flow.\n * Kept as plain strings so they can be reused, logged, or tested in isolation.\n *\n * Mutation reference (from API doc):\n * updateTwouCustomer — toggle Stripe test clock on/off\n * createTwouCart — user proceeds to payment\n * updateTwouCartItem — attach billing plan / payment method to cart\n * updateTwouCart — persist auto-renewal consent (SUBS-228)\n * startBusinessProcessableTransition — place order\n * updateTwouCartItem — retry: attach new payment method\n */\n\n// ─── Mutations ────────────────────────────────────────────────────────────────\n\n/** Creates a new cart during checkout. */\nexport const CREATE_CART = `mutation CreateCart($input: TwouCartInput!) {\n createTwouCart(input: $input) { biId uid }\n}`;\n\n/** Updates a cart item — attach billing plan / payment method. */\nexport const UPDATE_CART_ITEM = `mutation UpdateCartItem($input: TwouCartItemInput!) {\n updateTwouCartItem(input: $input) { uid }\n}`;\n\n/** Persists auto-renewal consent fields on the TwouCart BI (SUBS-228). */\nexport const UPDATE_CART = `mutation UpdateCart($input: TwouCartInput!) {\n updateTwouCart(input: $input) { uid }\n}`;\n\n/** Triggers the backend workflow to place the order. */\nexport const PLACE_ORDER = `mutation PlaceOrder($input: StartBusinessProcessableTransitionInput!) {\n startBusinessProcessableTransition(input: $input) { uid bpStatus { code } }\n}`;\n\n// ─── Queries ──────────────────────────────────────────────────────────────────\n\nexport const GET_CART_ITEM = `query GetCartItem($biId: String!) {\n getBusinessInteraction(biId: $biId) {\n uid\n hiConsistsOf { ... on TwouCartItem { uid } }\n }\n}`;\n\nexport const GET_CART_STATUS = `query GetCartStatus($biId: String!) {\n getBusinessInteraction(biId: $biId) {\n bpStatus { code }\n hiConsistsOf { ... on TwouCartItem { tStripeSubscriptionId } }\n ... on TwouCart {\n cmComments { edges { node { comText } } }\n }\n }\n}`;\n\nexport const FIND_SUBSCRIPTION = `query FindSubscription($filter: String!) {\n filterTwouSubscription(_first: 1, _filter: $filter) {\n edges {\n node {\n biId\n tTrialStart\n tTrialEnd\n tRenewalType\n hiConsistsOf {\n ... on TwouSubscriptionItem {\n paybBillingPlan {\n tStripePriceId\n bipOwnershipModel { omName }\n }\n paybPayment {\n ... on TwouStripePayment {\n tStripePaymentMethodId\n tPaymentMethodLast4\n tPaymentMethodBrand\n }\n }\n }\n }\n }\n }\n }\n}`;\n\n/** Fetch the viax customer uid by email using filterTwouCustomer. */\nexport const GET_CUSTOMER = `query GetCustomer($filter: String!) {\n filterTwouCustomer(_first: 1, _filter: $filter) {\n edges {\n node {\n uid\n parId\n parParty {\n paName\n paContacts {\n edges {\n node {\n ... on EmailAddressContactMedium {\n email\n }\n }\n }\n }\n ... on Individual {\n indFirstName\n indLastName\n }\n }\n }\n }\n }\n}`;\n\n/** Fetch the TwouSubscriptionPlan uid to use as biiSalable in createTwouCart. */\nexport const GET_PRODUCT = `query GetProduct($maId: String!) {\n getProduct(maId: $maId) {\n maName\n uid\n ... on TwouSubscriptionPlan {\n saOwnershipModels {\n uid\n omName\n }\n }\n }\n}`;\n\nexport const GET_BILLING_PLANS = `query GetBillingPlans {\n filterCustomerBillingPlan(_first: 10) {\n edges {\n node {\n uid\n tStripePriceId\n tStripeAmount {\n amount\n units { code }\n }\n bipIsTemplate\n bipOwnershipModel { uid omName }\n }\n }\n }\n}`;\n\n/** Fetch the number of active subscriptions — unauthenticated. */\nexport const GET_ACTIVE_SUBSCRIPTIONS_STATE = `query activeSubscriptions {\n tActiveSubscriptionsState\n}`;\n\n/** Check whether the currently authenticated user already has an active subscription.\n * tIsCurrentUserSubscriber is a JSON scalar — returns the full object, no subfield selection allowed. */\nexport const GET_IS_CURRENT_USER_SUBSCRIBER = `query IsCurrentUserSubscriber {\n tIsCurrentUserSubscriber\n}`;\n\n/** Fetch a course for the enrollment card when ?course_run_key= is present. */\nexport const GET_COURSE_DETAIL = `query CourseDetail($filter: String!) {\n filterTwouCourse(_first: 1, _filter: $filter) {\n edges {\n node {\n maId\n maName\n maDescription\n tShortDescription\n imageUrl\n tCourseKey\n tBrandText\n tPrimarySubjectArea\n tLevelType\n tLanguage\n tPacingType { code }\n tDurationLow\n tDurationHigh\n tDurationUnit { code }\n tEffortLow\n tEffortHigh\n tEffortUnit { code }\n tUrlCourse\n tB2cSubscriptionInclusion\n tHasOfacRestrictions\n tCatalogActive\n }\n }\n }\n}`;\n"]}
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/utils/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG;;EAE5C,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG;;;;;;;;;;;;;;;;;;;;;EAqB1C,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;EAkBjC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;EAEjC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;;EAErC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG;;;;;;;;;;;;;;;;;;;EAmB7C,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;EAe/B,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG;;;;;;;;EAQhD,CAAC","sourcesContent":["/**\n * GraphQL documents for the manage-subscription MFE.\n */\n\n/**\n * tIsCurrentUserSubscriber is a JSON scalar — returns the full object;\n * no subfield selection is allowed.\n */\nexport const GET_IS_CURRENT_USER_SUBSCRIBER = `query IsCurrentUserSubscriber {\n tIsCurrentUserSubscriber\n}`;\n\n/**\n * Enrollments for cancel confirmation.\n * Build `_filter` client-side, e.g. tSubscriptionBiId IN ('BI…', 'BI…').\n */\nexport const GET_SUBSCRIPTION_ENROLLMENTS = `query EnrollmentsForSubscriptions($filter: String!) {\n filterTwouEnrollment(_first: 200, _filter: $filter) {\n edges {\n node {\n biId\n tSubscriptionBiId\n bpStatus { code }\n tCourseRunKey\n tCourse {\n maId\n maName\n imageUrl\n tBrandText\n tSchools {\n tName\n tSortValue\n }\n }\n }\n }\n }\n}`;\n\n/**\n * Invoices for the learner's subscription (payment history).\n * Filter is inlined client-side: biRelatesTo.biId = '<subscriptionBiId>'.\n */\nexport const GET_PAYMENT_HISTORY = `query PaymentHistory($filter: String!, $first: Int!) {\n filterTwouInvoice(_first: $first, _filter: $filter) {\n edges {\n node {\n biId\n tStripeInvoiceId\n bpStatus { code name }\n billDate\n billBillingPeriod { start end }\n billFinancialCharges {\n fichAmount {\n amount\n units { code }\n }\n }\n }\n }\n }\n}`;\n\n/**\n * Cancel the learner's subscription (default: at period end).\n * Pass `immediate: true` to end access immediately.\n */\nexport const CANCEL_SUBSCRIPTION = `mutation CancelSubscription($biId: String!, $immediate: Boolean) {\n tCancelSubscription(biId: $biId, immediate: $immediate)\n}`;\n\n/**\n * Resume a cancelled subscription before the period end / cancellation date.\n */\nexport const REACTIVATE_SUBSCRIPTION = `mutation ReactivateSubscription($biId: String!) {\n tReactivateSubscription(biId: $biId)\n}`;\n\n/**\n * Payment method on an existing subscription (for renew / manage display).\n */\nexport const GET_SUBSCRIPTION_PAYMENT_METHOD = `query SubscriptionPaymentMethod($filter: String!) {\n filterTwouSubscription(_first: 1, _filter: $filter) {\n edges {\n node {\n biId\n hiConsistsOf {\n ... on TwouSubscriptionItem {\n paybPayment {\n ... on TwouStripePayment {\n tStripePaymentMethodId\n tPaymentMethodLast4\n tPaymentMethodBrand\n }\n }\n }\n }\n }\n }\n }\n}`;\n\n/**\n * Available customer billing plans (monthly / annual template prices).\n * Same query as frontend-app-subscription-checkout.\n */\nexport const GET_BILLING_PLANS = `query GetBillingPlans {\n filterCustomerBillingPlan(_first: 10) {\n edges {\n node {\n uid\n tStripePriceId\n tStripeAmount {\n amount\n units { code }\n }\n bipIsTemplate\n bipOwnershipModel { uid omName }\n }\n }\n }\n}`;\n\n/**\n * Attach a new Stripe payment method (pm_…) as the subscription default.\n */\nexport const UPDATE_SUBSCRIPTION_PAYMENT_METHOD = `mutation UpdateSubscriptionPaymentMethod(\n $biId: String!\n $tStripePaymentMethodId: String!\n) {\n tUpdateSubscriptionPaymentMethod(\n biId: $biId\n tStripePaymentMethodId: $tStripePaymentMethodId\n )\n}`;\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Derive which manage-subscription UI to show from subscriber API data.
3
+ */
4
+ import type { CurrentUserSubscriberResult, SubscriptionView } from '../types';
5
+ /**
6
+ * Map subscriber payload → UI view.
7
+ *
8
+ * - active: can enroll / ACTIVE / TRIAL / isSubscriber without cancel status
9
+ * - canceled_access: canceled but period end still in the future (or isSubscriber)
10
+ * - canceled_expired: previously subscribed, no current access
11
+ * - none: never subscribed / no useful subscription context
12
+ */
13
+ export declare function resolveSubscriptionView(subscriber: CurrentUserSubscriberResult | null | undefined): SubscriptionView;
14
+ /** Human-readable plan label from renewal type / status. */
15
+ export declare function resolvePlanLabel(subscriber: CurrentUserSubscriberResult | null | undefined): 'monthly' | 'annual';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Derive which manage-subscription UI to show from subscriber API data.
3
+ */
4
+ import { ACTIVE_SUBSCRIPTION_STATUSES, CANCELED_SUBSCRIPTION_STATUSES, } from '../constants';
5
+ import { isFutureDate } from './formatDate';
6
+ /**
7
+ * Map subscriber payload → UI view.
8
+ *
9
+ * - active: can enroll / ACTIVE / TRIAL / isSubscriber without cancel status
10
+ * - canceled_access: canceled but period end still in the future (or isSubscriber)
11
+ * - canceled_expired: previously subscribed, no current access
12
+ * - none: never subscribed / no useful subscription context
13
+ */
14
+ export function resolveSubscriptionView(subscriber) {
15
+ var _a;
16
+ if (!subscriber) {
17
+ return 'none';
18
+ }
19
+ const status = ((_a = subscriber.status) !== null && _a !== void 0 ? _a : '').toUpperCase();
20
+ const isCanceledStatus = (CANCELED_SUBSCRIPTION_STATUSES.has(status)
21
+ || status.includes('CANCEL'));
22
+ if (!isCanceledStatus
23
+ && (subscriber.canEnroll
24
+ || subscriber.isSubscriber
25
+ || ACTIVE_SUBSCRIPTION_STATUSES.has(status))) {
26
+ return 'active';
27
+ }
28
+ const periodStillOpen = isFutureDate(subscriber.currentPeriodEnd)
29
+ || isFutureDate(subscriber.subscriptionEndDate);
30
+ if (isCanceledStatus) {
31
+ if (subscriber.isSubscriber || periodStillOpen) {
32
+ return 'canceled_access';
33
+ }
34
+ return 'canceled_expired';
35
+ }
36
+ if (subscriber.subscriptionBiId || subscriber.canceledAt) {
37
+ return 'canceled_expired';
38
+ }
39
+ return 'none';
40
+ }
41
+ /** Human-readable plan label from renewal type / status. */
42
+ export function resolvePlanLabel(subscriber) {
43
+ var _a;
44
+ const raw = ((_a = subscriber === null || subscriber === void 0 ? void 0 : subscriber.renewalType) !== null && _a !== void 0 ? _a : '').toLowerCase();
45
+ if (raw.includes('annual') || raw.includes('year')) {
46
+ return 'annual';
47
+ }
48
+ return 'monthly';
49
+ }
50
+ //# sourceMappingURL=subscriptionView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriptionView.js","sourceRoot":"","sources":["../../src/utils/subscriptionView.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAA0D;;IAE1D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAA,UAAU,CAAC,MAAM,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACvD,MAAM,gBAAgB,GAAG,CACvB,8BAA8B,CAAC,GAAG,CAAC,MAAM,CAAC;WACvC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC7B,CAAC;IAEF,IACE,CAAC,gBAAgB;WACd,CACD,UAAU,CAAC,SAAS;eACjB,UAAU,CAAC,YAAY;eACvB,4BAA4B,CAAC,GAAG,CAAC,MAAM,CAAC,CAC5C,EACD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,eAAe,GAAG,YAAY,CAAC,UAAU,CAAC,gBAAgB,CAAC;WAC5D,YAAY,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;IAElD,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,UAAU,CAAC,YAAY,IAAI,eAAe,EAAE,CAAC;YAC/C,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QACD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,IAAI,UAAU,CAAC,gBAAgB,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAC9B,UAA0D;;IAE1D,MAAM,GAAG,GAAG,CAAC,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,WAAW,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1D,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["/**\n * Derive which manage-subscription UI to show from subscriber API data.\n */\n\nimport {\n ACTIVE_SUBSCRIPTION_STATUSES,\n CANCELED_SUBSCRIPTION_STATUSES,\n} from '../constants';\nimport type { CurrentUserSubscriberResult, SubscriptionView } from '../types';\nimport { isFutureDate } from './formatDate';\n\n/**\n * Map subscriber payload → UI view.\n *\n * - active: can enroll / ACTIVE / TRIAL / isSubscriber without cancel status\n * - canceled_access: canceled but period end still in the future (or isSubscriber)\n * - canceled_expired: previously subscribed, no current access\n * - none: never subscribed / no useful subscription context\n */\nexport function resolveSubscriptionView(\n subscriber: CurrentUserSubscriberResult | null | undefined,\n): SubscriptionView {\n if (!subscriber) {\n return 'none';\n }\n\n const status = (subscriber.status ?? '').toUpperCase();\n const isCanceledStatus = (\n CANCELED_SUBSCRIPTION_STATUSES.has(status)\n || status.includes('CANCEL')\n );\n\n if (\n !isCanceledStatus\n && (\n subscriber.canEnroll\n || subscriber.isSubscriber\n || ACTIVE_SUBSCRIPTION_STATUSES.has(status)\n )\n ) {\n return 'active';\n }\n\n const periodStillOpen = isFutureDate(subscriber.currentPeriodEnd)\n || isFutureDate(subscriber.subscriptionEndDate);\n\n if (isCanceledStatus) {\n if (subscriber.isSubscriber || periodStillOpen) {\n return 'canceled_access';\n }\n return 'canceled_expired';\n }\n\n if (subscriber.subscriptionBiId || subscriber.canceledAt) {\n return 'canceled_expired';\n }\n\n return 'none';\n}\n\n/** Human-readable plan label from renewal type / status. */\nexport function resolvePlanLabel(\n subscriber: CurrentUserSubscriberResult | null | undefined,\n): 'monthly' | 'annual' {\n const raw = (subscriber?.renewalType ?? '').toLowerCase();\n if (raw.includes('annual') || raw.includes('year')) {\n return 'annual';\n }\n return 'monthly';\n}\n"]}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * External / sibling-app URLs for manage-subscription CTAs.
3
+ */
4
+ /** Checkout / subscribe flow URL (renew + new subscribe). */
5
+ export declare function getCheckoutUrl(): string;
6
+ /** Marketing page for "Learn about edX Subscription". */
7
+ export declare function getLearnMoreUrl(): string;
8
+ /** Learner Help Center (footer link). */
9
+ export declare function getLearnerHelpCenterUrl(): string;
10
+ /** Learner dashboard URL for post-cancel return. */
11
+ export declare function getLearnerDashboardUrl(): string;
12
+ /** Optional change-to-annual checkout deep link. */
13
+ export declare function getChangeToAnnualUrl(): string;