@openedx/frontend-app-learner-dashboard 1.0.0-alpha.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 (351) hide show
  1. package/LICENSE +661 -0
  2. package/README.rst +86 -0
  3. package/package.json +84 -0
  4. package/src/Main.jsx +20 -0
  5. package/src/__mocks__/file.js +1 -0
  6. package/src/__mocks__/svg.js +1 -0
  7. package/src/__snapshots__/App.test.jsx.snap +83 -0
  8. package/src/__snapshots__/index.test.jsx.snap +43 -0
  9. package/src/app.scss +41 -0
  10. package/src/app.ts +23 -0
  11. package/src/assets/empty-course.svg +49 -0
  12. package/src/assets/more-courses-sidewidget.svg +52 -0
  13. package/src/assets/verified-ribbon.png +0 -0
  14. package/src/components/Banner.jsx +26 -0
  15. package/src/components/Banner.test.jsx +27 -0
  16. package/src/components/__snapshots__/Banner.test.jsx.snap +31 -0
  17. package/src/constants.ts +1 -0
  18. package/src/containers/CourseCard/CourseCard.scss +75 -0
  19. package/src/containers/CourseCard/__snapshots__/index.test.jsx.snap +111 -0
  20. package/src/containers/CourseCard/components/CourseCardActions/ActionButton/__snapshots__/index.test.jsx.snap +14 -0
  21. package/src/containers/CourseCard/components/CourseCardActions/ActionButton/hooks.js +8 -0
  22. package/src/containers/CourseCard/components/CourseCardActions/ActionButton/hooks.test.js +21 -0
  23. package/src/containers/CourseCard/components/CourseCardActions/ActionButton/index.jsx +16 -0
  24. package/src/containers/CourseCard/components/CourseCardActions/ActionButton/index.test.jsx +25 -0
  25. package/src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.jsx +38 -0
  26. package/src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.test.jsx +86 -0
  27. package/src/containers/CourseCard/components/CourseCardActions/ResumeButton.jsx +38 -0
  28. package/src/containers/CourseCard/components/CourseCardActions/ResumeButton.test.jsx +84 -0
  29. package/src/containers/CourseCard/components/CourseCardActions/SelectSessionButton.jsx +28 -0
  30. package/src/containers/CourseCard/components/CourseCardActions/SelectSessionButton.test.jsx +34 -0
  31. package/src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.jsx +37 -0
  32. package/src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.test.jsx +45 -0
  33. package/src/containers/CourseCard/components/CourseCardActions/__snapshots__/BeginCourseButton.test.jsx.snap +39 -0
  34. package/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ResumeButton.test.jsx.snap +39 -0
  35. package/src/containers/CourseCard/components/CourseCardActions/__snapshots__/SelectSessionButton.test.jsx.snap +19 -0
  36. package/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ViewCourseButton.test.jsx.snap +39 -0
  37. package/src/containers/CourseCard/components/CourseCardActions/index.jsx +42 -0
  38. package/src/containers/CourseCard/components/CourseCardActions/index.test.jsx +97 -0
  39. package/src/containers/CourseCard/components/CourseCardActions/messages.js +26 -0
  40. package/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.jsx +95 -0
  41. package/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.test.jsx +227 -0
  42. package/src/containers/CourseCard/components/CourseCardBanners/CourseBanner.jsx +57 -0
  43. package/src/containers/CourseCard/components/CourseCardBanners/CourseBanner.test.jsx +131 -0
  44. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/__snapshots__/index.test.jsx.snap +58 -0
  45. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/hooks.js +42 -0
  46. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/hooks.test.js +90 -0
  47. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/index.jsx +36 -0
  48. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/index.test.jsx +95 -0
  49. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/messages.js +16 -0
  50. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/ApprovedContent.jsx +35 -0
  51. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/ApprovedContent.test.jsx +64 -0
  52. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/EligibleContent.jsx +34 -0
  53. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/EligibleContent.test.jsx +82 -0
  54. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/MustRequestContent.jsx +36 -0
  55. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/MustRequestContent.test.jsx +74 -0
  56. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/PendingContent.jsx +30 -0
  57. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/PendingContent.test.jsx +63 -0
  58. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/RejectedContent.jsx +27 -0
  59. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/RejectedContent.test.jsx +54 -0
  60. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditContent.jsx +51 -0
  61. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditContent.test.jsx +60 -0
  62. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/__snapshots__/index.test.jsx.snap +32 -0
  63. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/hooks.js +13 -0
  64. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/hooks.test.js +45 -0
  65. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/index.jsx +43 -0
  66. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/index.test.jsx +65 -0
  67. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/ref.test.jsx +34 -0
  68. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/ProviderLink.jsx +24 -0
  69. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/ProviderLink.test.jsx +42 -0
  70. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/__snapshots__/CreditContent.test.jsx.snap +60 -0
  71. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/__snapshots__/ProviderLink.test.jsx.snap +11 -0
  72. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/hooks.js +27 -0
  73. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/hooks.test.js +56 -0
  74. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/messages.js +61 -0
  75. package/src/containers/CourseCard/components/CourseCardBanners/EntitlementBanner.jsx +66 -0
  76. package/src/containers/CourseCard/components/CourseCardBanners/EntitlementBanner.test.jsx +63 -0
  77. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/ProgramsList.jsx +23 -0
  78. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/ProgramsList.test.jsx +23 -0
  79. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/__snapshots__/ProgramsList.test.jsx.snap +28 -0
  80. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/__snapshots__/index.test.jsx.snap +29 -0
  81. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/index.jsx +38 -0
  82. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/index.test.jsx +42 -0
  83. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/messages.js +31 -0
  84. package/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/CertificateBanner.test.jsx.snap +205 -0
  85. package/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/CourseBanner.test.jsx.snap +38 -0
  86. package/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/EntitlementBanner.test.jsx.snap +53 -0
  87. package/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/index.test.jsx.snap +41 -0
  88. package/src/containers/CourseCard/components/CourseCardBanners/index.jsx +28 -0
  89. package/src/containers/CourseCard/components/CourseCardBanners/index.test.jsx +32 -0
  90. package/src/containers/CourseCard/components/CourseCardBanners/messages.js +106 -0
  91. package/src/containers/CourseCard/components/CourseCardDetails/__snapshots__/index.test.jsx.snap +56 -0
  92. package/src/containers/CourseCard/components/CourseCardDetails/hooks.js +67 -0
  93. package/src/containers/CourseCard/components/CourseCardDetails/hooks.test.js +186 -0
  94. package/src/containers/CourseCard/components/CourseCardDetails/index.jsx +45 -0
  95. package/src/containers/CourseCard/components/CourseCardDetails/index.scss +7 -0
  96. package/src/containers/CourseCard/components/CourseCardDetails/index.test.jsx +71 -0
  97. package/src/containers/CourseCard/components/CourseCardDetails/messages.js +41 -0
  98. package/src/containers/CourseCard/components/CourseCardImage.jsx +68 -0
  99. package/src/containers/CourseCard/components/CourseCardImage.test.jsx +66 -0
  100. package/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.jsx +83 -0
  101. package/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.test.jsx +236 -0
  102. package/src/containers/CourseCard/components/CourseCardMenu/__snapshots__/index.test.jsx.snap +81 -0
  103. package/src/containers/CourseCard/components/CourseCardMenu/hooks.js +58 -0
  104. package/src/containers/CourseCard/components/CourseCardMenu/hooks.test.js +153 -0
  105. package/src/containers/CourseCard/components/CourseCardMenu/index.jsx +85 -0
  106. package/src/containers/CourseCard/components/CourseCardMenu/index.test.jsx +214 -0
  107. package/src/containers/CourseCard/components/CourseCardMenu/messages.js +36 -0
  108. package/src/containers/CourseCard/components/CourseCardTitle.jsx +43 -0
  109. package/src/containers/CourseCard/components/CourseCardTitle.test.jsx +67 -0
  110. package/src/containers/CourseCard/components/RelatedProgramsBadge/__snapshots__/index.test.jsx.snap +25 -0
  111. package/src/containers/CourseCard/components/RelatedProgramsBadge/hooks.jsx +35 -0
  112. package/src/containers/CourseCard/components/RelatedProgramsBadge/hooks.test.js +76 -0
  113. package/src/containers/CourseCard/components/RelatedProgramsBadge/index.jsx +39 -0
  114. package/src/containers/CourseCard/components/RelatedProgramsBadge/index.test.jsx +30 -0
  115. package/src/containers/CourseCard/components/RelatedProgramsBadge/messages.js +13 -0
  116. package/src/containers/CourseCard/components/__snapshots__/CourseCardImage.test.jsx.snap +72 -0
  117. package/src/containers/CourseCard/components/__snapshots__/CourseCardTitle.test.jsx.snap +33 -0
  118. package/src/containers/CourseCard/components/hooks.js +33 -0
  119. package/src/containers/CourseCard/components/hooks.test.js +165 -0
  120. package/src/containers/CourseCard/hooks.js +23 -0
  121. package/src/containers/CourseCard/hooks.test.js +48 -0
  122. package/src/containers/CourseCard/index.jsx +50 -0
  123. package/src/containers/CourseCard/index.test.jsx +29 -0
  124. package/src/containers/CourseCard/messages.js +26 -0
  125. package/src/containers/CourseFilterControls/ActiveCourseFilters.jsx +40 -0
  126. package/src/containers/CourseFilterControls/ActiveCourseFilters.test.jsx +17 -0
  127. package/src/containers/CourseFilterControls/CourseFilterControls.jsx +115 -0
  128. package/src/containers/CourseFilterControls/CourseFilterControls.test.jsx +60 -0
  129. package/src/containers/CourseFilterControls/__snapshots__/ActiveCourseFilters.test.jsx.snap +39 -0
  130. package/src/containers/CourseFilterControls/__snapshots__/CourseFilterControls.test.jsx.snap +169 -0
  131. package/src/containers/CourseFilterControls/components/Checkbox.jsx +21 -0
  132. package/src/containers/CourseFilterControls/components/Checkbox.test.jsx +15 -0
  133. package/src/containers/CourseFilterControls/components/FilterForm.jsx +45 -0
  134. package/src/containers/CourseFilterControls/components/FilterForm.test.jsx +29 -0
  135. package/src/containers/CourseFilterControls/components/SortForm.jsx +39 -0
  136. package/src/containers/CourseFilterControls/components/SortForm.test.jsx +19 -0
  137. package/src/containers/CourseFilterControls/components/__snapshots__/Checkbox.test.jsx.snap +46 -0
  138. package/src/containers/CourseFilterControls/components/__snapshots__/FilterForm.test.jsx.snap +41 -0
  139. package/src/containers/CourseFilterControls/components/__snapshots__/SortForm.test.jsx.snap +29 -0
  140. package/src/containers/CourseFilterControls/hooks.js +60 -0
  141. package/src/containers/CourseFilterControls/hooks.test.js +113 -0
  142. package/src/containers/CourseFilterControls/index.jsx +6 -0
  143. package/src/containers/CourseFilterControls/index.scss +29 -0
  144. package/src/containers/CourseFilterControls/messages.js +61 -0
  145. package/src/containers/CoursesPanel/CourseList/__snapshots__/index.test.jsx.snap +70 -0
  146. package/src/containers/CoursesPanel/CourseList/hooks.js +8 -0
  147. package/src/containers/CoursesPanel/CourseList/index.jsx +54 -0
  148. package/src/containers/CoursesPanel/CourseList/index.test.jsx +64 -0
  149. package/src/containers/CoursesPanel/NoCoursesView/__snapshots__/index.test.jsx.snap +29 -0
  150. package/src/containers/CoursesPanel/NoCoursesView/index.jsx +40 -0
  151. package/src/containers/CoursesPanel/NoCoursesView/index.scss +15 -0
  152. package/src/containers/CoursesPanel/NoCoursesView/index.test.jsx +18 -0
  153. package/src/containers/CoursesPanel/NoCoursesView/messages.js +26 -0
  154. package/src/containers/CoursesPanel/__snapshots__/index.test.jsx.snap +55 -0
  155. package/src/containers/CoursesPanel/hooks.js +54 -0
  156. package/src/containers/CoursesPanel/hooks.test.js +115 -0
  157. package/src/containers/CoursesPanel/index.jsx +40 -0
  158. package/src/containers/CoursesPanel/index.scss +42 -0
  159. package/src/containers/CoursesPanel/index.test.jsx +58 -0
  160. package/src/containers/CoursesPanel/messages.js +11 -0
  161. package/src/containers/Dashboard/DashboardLayout.jsx +54 -0
  162. package/src/containers/Dashboard/DashboardLayout.test.jsx +115 -0
  163. package/src/containers/Dashboard/LoadingView.jsx +20 -0
  164. package/src/containers/Dashboard/LoadingView.test.jsx +23 -0
  165. package/src/containers/Dashboard/__snapshots__/DashboardLayout.test.jsx.snap +197 -0
  166. package/src/containers/Dashboard/__snapshots__/LoadingView.test.jsx.snap +13 -0
  167. package/src/containers/Dashboard/__snapshots__/index.test.jsx.snap +69 -0
  168. package/src/containers/Dashboard/hooks.js +34 -0
  169. package/src/containers/Dashboard/hooks.test.js +88 -0
  170. package/src/containers/Dashboard/index.jsx +43 -0
  171. package/src/containers/Dashboard/index.scss +29 -0
  172. package/src/containers/Dashboard/index.test.jsx +122 -0
  173. package/src/containers/EmailSettingsModal/__snapshots__/index.test.jsx.snap +133 -0
  174. package/src/containers/EmailSettingsModal/hooks.js +32 -0
  175. package/src/containers/EmailSettingsModal/hooks.test.js +71 -0
  176. package/src/containers/EmailSettingsModal/index.jsx +58 -0
  177. package/src/containers/EmailSettingsModal/index.test.jsx +57 -0
  178. package/src/containers/EmailSettingsModal/messages.js +37 -0
  179. package/src/containers/RelatedProgramsModal/__snapshots__/index.test.jsx.snap +169 -0
  180. package/src/containers/RelatedProgramsModal/components/ProgramCard.jsx +66 -0
  181. package/src/containers/RelatedProgramsModal/components/ProgramCard.test.jsx +23 -0
  182. package/src/containers/RelatedProgramsModal/components/__snapshots__/ProgramCard.test.jsx.snap +60 -0
  183. package/src/containers/RelatedProgramsModal/components/index.scss +23 -0
  184. package/src/containers/RelatedProgramsModal/components/messages.js +24 -0
  185. package/src/containers/RelatedProgramsModal/hooks.js +10 -0
  186. package/src/containers/RelatedProgramsModal/index.jsx +62 -0
  187. package/src/containers/RelatedProgramsModal/index.scss +5 -0
  188. package/src/containers/RelatedProgramsModal/index.test.jsx +60 -0
  189. package/src/containers/RelatedProgramsModal/messages.js +16 -0
  190. package/src/containers/SelectSessionModal/__snapshots__/index.test.jsx.snap +176 -0
  191. package/src/containers/SelectSessionModal/constants.js +2 -0
  192. package/src/containers/SelectSessionModal/hooks.js +77 -0
  193. package/src/containers/SelectSessionModal/hooks.test.js +194 -0
  194. package/src/containers/SelectSessionModal/index.jsx +75 -0
  195. package/src/containers/SelectSessionModal/index.test.jsx +53 -0
  196. package/src/containers/SelectSessionModal/messages.js +41 -0
  197. package/src/containers/UnenrollConfirmModal/__snapshots__/index.test.jsx.snap +101 -0
  198. package/src/containers/UnenrollConfirmModal/components/ConfirmPane.jsx +36 -0
  199. package/src/containers/UnenrollConfirmModal/components/ConfirmPane.test.jsx +14 -0
  200. package/src/containers/UnenrollConfirmModal/components/FinishedPane.jsx +35 -0
  201. package/src/containers/UnenrollConfirmModal/components/FinishedPane.test.jsx +21 -0
  202. package/src/containers/UnenrollConfirmModal/components/ReasonPane.jsx +65 -0
  203. package/src/containers/UnenrollConfirmModal/components/ReasonPane.test.jsx +26 -0
  204. package/src/containers/UnenrollConfirmModal/components/__snapshots__/ConfirmPane.test.jsx.snap +22 -0
  205. package/src/containers/UnenrollConfirmModal/components/__snapshots__/FinishedPane.test.jsx.snap +38 -0
  206. package/src/containers/UnenrollConfirmModal/components/__snapshots__/ReasonPane.test.jsx.snap +183 -0
  207. package/src/containers/UnenrollConfirmModal/components/messages.js +56 -0
  208. package/src/containers/UnenrollConfirmModal/constants.js +86 -0
  209. package/src/containers/UnenrollConfirmModal/hooks/index.js +55 -0
  210. package/src/containers/UnenrollConfirmModal/hooks/index.test.js +101 -0
  211. package/src/containers/UnenrollConfirmModal/hooks/reasons.js +79 -0
  212. package/src/containers/UnenrollConfirmModal/hooks/reasons.test.js +192 -0
  213. package/src/containers/UnenrollConfirmModal/index.jsx +59 -0
  214. package/src/containers/UnenrollConfirmModal/index.test.jsx +61 -0
  215. package/src/data/constants/app.js +20 -0
  216. package/src/data/constants/app.test.js +24 -0
  217. package/src/data/constants/course.js +17 -0
  218. package/src/data/constants/credit.js +9 -0
  219. package/src/data/constants/files.js +20 -0
  220. package/src/data/constants/htmlKeys.js +21 -0
  221. package/src/data/constants/requests.js +34 -0
  222. package/src/data/contexts/GlobalDataContext.jsx +15 -0
  223. package/src/data/contexts/GlobalDataProvider.jsx +23 -0
  224. package/src/data/contexts/MasqueradeUserContext.jsx +16 -0
  225. package/src/data/contexts/MasqueradeUserProvider.jsx +31 -0
  226. package/src/data/redux/app/index.js +2 -0
  227. package/src/data/redux/app/reducer.js +81 -0
  228. package/src/data/redux/app/reducer.test.js +124 -0
  229. package/src/data/redux/app/selectors/appSelectors.js +23 -0
  230. package/src/data/redux/app/selectors/appSelectors.test.js +28 -0
  231. package/src/data/redux/app/selectors/courseCard.js +155 -0
  232. package/src/data/redux/app/selectors/courseCard.test.js +398 -0
  233. package/src/data/redux/app/selectors/currentList.js +60 -0
  234. package/src/data/redux/app/selectors/currentList.test.js +185 -0
  235. package/src/data/redux/app/selectors/index.js +13 -0
  236. package/src/data/redux/app/selectors/simpleSelectors.js +38 -0
  237. package/src/data/redux/app/selectors/simpleSelectors.test.js +75 -0
  238. package/src/data/redux/hooks/app.js +106 -0
  239. package/src/data/redux/hooks/index.js +2 -0
  240. package/src/data/redux/hooks/requests.js +47 -0
  241. package/src/data/redux/index.js +37 -0
  242. package/src/data/redux/requests/index.js +2 -0
  243. package/src/data/redux/requests/reducer.js +53 -0
  244. package/src/data/redux/requests/reducer.test.js +62 -0
  245. package/src/data/redux/requests/selectors.js +29 -0
  246. package/src/data/redux/requests/selectors.test.js +110 -0
  247. package/src/data/services/lms/api.js +77 -0
  248. package/src/data/services/lms/api.test.js +156 -0
  249. package/src/data/services/lms/constants.js +18 -0
  250. package/src/data/services/lms/fakeData/courses.js +828 -0
  251. package/src/data/services/lms/fakeData/testUtils.js +40 -0
  252. package/src/data/services/lms/index.js +8 -0
  253. package/src/data/services/lms/urls.js +43 -0
  254. package/src/data/services/lms/urls.test.js +51 -0
  255. package/src/data/services/lms/utils.js +60 -0
  256. package/src/data/services/lms/utils.test.js +40 -0
  257. package/src/data/services/segment/utils.js +17 -0
  258. package/src/data/services/segment/utils.test.js +36 -0
  259. package/src/data/store.js +25 -0
  260. package/src/data/store.test.js +47 -0
  261. package/src/data/utils.js +19 -0
  262. package/src/data/utils.test.js +29 -0
  263. package/src/hooks/api.js +123 -0
  264. package/src/hooks/api.test.js +273 -0
  265. package/src/hooks/index.js +7 -0
  266. package/src/hooks/utils.js +17 -0
  267. package/src/hooks/utils.test.js +16 -0
  268. package/src/i18n/index.js +25 -0
  269. package/src/index.ts +3 -0
  270. package/src/messages.js +16 -0
  271. package/src/providers.ts +11 -0
  272. package/src/routes.jsx +14 -0
  273. package/src/segment.js +85 -0
  274. package/src/setupTest.jsx +251 -0
  275. package/src/slots/CourseBannerSlot/README.md +44 -0
  276. package/src/slots/CourseBannerSlot/images/course_banner_slot_default.png +0 -0
  277. package/src/slots/CourseBannerSlot/images/custom_course_banner.png +0 -0
  278. package/src/slots/CourseBannerSlot/index.jsx +18 -0
  279. package/src/slots/CourseCardActionSlot/README.md +53 -0
  280. package/src/slots/CourseCardActionSlot/images/post_course_card_action.png +0 -0
  281. package/src/slots/CourseCardActionSlot/index.jsx +15 -0
  282. package/src/slots/CourseListSlot/README.md +54 -0
  283. package/src/slots/CourseListSlot/images/course_list_slot.png +0 -0
  284. package/src/slots/CourseListSlot/images/readme_custom_course_list.png +0 -0
  285. package/src/slots/CourseListSlot/index.jsx +17 -0
  286. package/src/slots/DashboardModalSlot/README.md +30 -0
  287. package/src/slots/DashboardModalSlot/images/dashboard_modal_slot.png +0 -0
  288. package/src/slots/DashboardModalSlot/index.jsx +7 -0
  289. package/src/slots/NoCoursesViewSlot/README.md +34 -0
  290. package/src/slots/NoCoursesViewSlot/images/no_course_view_slot.png +0 -0
  291. package/src/slots/NoCoursesViewSlot/images/readme_custom_no_courses.png +0 -0
  292. package/src/slots/NoCoursesViewSlot/index.jsx +11 -0
  293. package/src/slots/README.md +8 -0
  294. package/src/slots/WidgetSidebarSlot/README.md +51 -0
  295. package/src/slots/WidgetSidebarSlot/__snapshots__/index.test.jsx.snap +14 -0
  296. package/src/slots/WidgetSidebarSlot/images/readme_custom_sidebar.png +0 -0
  297. package/src/slots/WidgetSidebarSlot/images/widget_sidebar_slot.png +0 -0
  298. package/src/slots/WidgetSidebarSlot/index.jsx +10 -0
  299. package/src/slots/WidgetSidebarSlot/index.test.jsx +18 -0
  300. package/src/slots.tsx +9 -0
  301. package/src/test/app.test.jsx +255 -0
  302. package/src/test/inspector.js +50 -0
  303. package/src/test/messages.js +29 -0
  304. package/src/test/utils.js +3 -0
  305. package/src/testUtils.js +211 -0
  306. package/src/tracking/constants.js +50 -0
  307. package/src/tracking/index.js +17 -0
  308. package/src/tracking/trackers/course.js +44 -0
  309. package/src/tracking/trackers/course.test.js +80 -0
  310. package/src/tracking/trackers/credit.js +20 -0
  311. package/src/tracking/trackers/credit.test.js +38 -0
  312. package/src/tracking/trackers/engagement.js +23 -0
  313. package/src/tracking/trackers/engagement.test.js +31 -0
  314. package/src/tracking/trackers/entitlements.js +34 -0
  315. package/src/tracking/trackers/entitlements.test.js +34 -0
  316. package/src/tracking/trackers/filter.js +21 -0
  317. package/src/tracking/trackers/filter.test.js +45 -0
  318. package/src/tracking/trackers/findCourses.js +16 -0
  319. package/src/tracking/trackers/findCourses.test.js +45 -0
  320. package/src/tracking/trackers/socialShare.js +11 -0
  321. package/src/tracking/trackers/socialShare.test.js +17 -0
  322. package/src/utils/StrictDict.js +19 -0
  323. package/src/utils/StrictDict.test.js +66 -0
  324. package/src/utils/dateFormatter.js +9 -0
  325. package/src/utils/hooks.js +12 -0
  326. package/src/utils/index.js +5 -0
  327. package/src/utils/keyStore.js +10 -0
  328. package/src/widgets/LearnerDashboardHeader/ConfirmEmailBanner/ConfirmEmailBanner.scss +3 -0
  329. package/src/widgets/LearnerDashboardHeader/ConfirmEmailBanner/assets/confirm-email.svg +76 -0
  330. package/src/widgets/LearnerDashboardHeader/ConfirmEmailBanner/hooks.js +45 -0
  331. package/src/widgets/LearnerDashboardHeader/ConfirmEmailBanner/index.jsx +66 -0
  332. package/src/widgets/LearnerDashboardHeader/ConfirmEmailBanner/messages.js +36 -0
  333. package/src/widgets/LearnerDashboardHeader/CoursesLink.jsx +14 -0
  334. package/src/widgets/LearnerDashboardHeader/DiscoverLinkMenuItem.jsx +30 -0
  335. package/src/widgets/LearnerDashboardHeader/MasqueradeBar/hooks.js +69 -0
  336. package/src/widgets/LearnerDashboardHeader/MasqueradeBar/index.jsx +92 -0
  337. package/src/widgets/LearnerDashboardHeader/MasqueradeBar/index.scss +38 -0
  338. package/src/widgets/LearnerDashboardHeader/MasqueradeBar/messages.js +36 -0
  339. package/src/widgets/LearnerDashboardHeader/OrderHistoryLinkMenuItem.jsx +29 -0
  340. package/src/widgets/LearnerDashboardHeader/ProgramsLinkMenuItem.jsx +26 -0
  341. package/src/widgets/LearnerDashboardHeader/SupportLinkMenuItem.jsx +29 -0
  342. package/src/widgets/LearnerDashboardHeader/app.tsx +93 -0
  343. package/src/widgets/LearnerDashboardHeader/hooks.js +20 -0
  344. package/src/widgets/LearnerDashboardHeader/index.ts +1 -0
  345. package/src/widgets/LearnerDashboardHeader/messages.js +91 -0
  346. package/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap +45 -0
  347. package/src/widgets/LookingForChallengeWidget/index.jsx +47 -0
  348. package/src/widgets/LookingForChallengeWidget/index.scss +6 -0
  349. package/src/widgets/LookingForChallengeWidget/index.test.jsx +24 -0
  350. package/src/widgets/LookingForChallengeWidget/messages.js +16 -0
  351. package/src/widgets/LookingForChallengeWidget/track.js +15 -0
@@ -0,0 +1,205 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`CertificateBanner snapshot is passing and is downloadable 1`] = `
4
+ <Banner
5
+ icon={[MockFunction icons.CheckCircle]}
6
+ variant="success"
7
+ >
8
+ Congratulations. Your certificate is ready.
9
+ </Banner>
10
+ `;
11
+
12
+ exports[`CertificateBanner snapshot is passing and is earned but unavailable 1`] = `
13
+ <Banner>
14
+ Your grade and certificate will be ready after 10/20/3030.
15
+ </Banner>
16
+ `;
17
+
18
+ exports[`CertificateBanner snapshot is passing and not downloadable render empty 1`] = `null`;
19
+
20
+ exports[`CertificateBanner snapshot is restricted 1`] = `
21
+ <Banner
22
+ variant="danger"
23
+ >
24
+ Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know.
25
+ </Banner>
26
+ `;
27
+
28
+ exports[`CertificateBanner snapshot is restricted and verified 1`] = `
29
+ <Banner
30
+ variant="danger"
31
+ >
32
+ Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know.
33
+
34
+ If you would like a refund on your Certificate of Achievement, please contact us.
35
+ </Banner>
36
+ `;
37
+
38
+ exports[`CertificateBanner snapshot is restricted and verified with billing email 1`] = `
39
+ <Banner
40
+ variant="danger"
41
+ >
42
+ Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know.
43
+
44
+ <format-message-function
45
+ message={
46
+ {
47
+ "defaultMessage": "If you would like a refund on your Certificate of Achievement, please contact our billing address {billingEmail}",
48
+ "description": "Message to learners to contact billing for certificate refunds",
49
+ "id": "learner-dash.courseCard.banners.certificateRefundContactBilling",
50
+ }
51
+ }
52
+ values={
53
+ {
54
+ "billingEmail": <MailtoLink
55
+ to="billing@email"
56
+ >
57
+ billing@email
58
+ </MailtoLink>,
59
+ }
60
+ }
61
+ />
62
+ </Banner>
63
+ `;
64
+
65
+ exports[`CertificateBanner snapshot is restricted and verified with support and billing email 1`] = `
66
+ <Banner
67
+ variant="danger"
68
+ >
69
+ <format-message-function
70
+ message={
71
+ {
72
+ "defaultMessage": "Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know by contacting {supportEmail}.",
73
+ "description": "Restricted certificate warning message",
74
+ "id": "learner-dash.courseCard.banners.certificateRestricted",
75
+ }
76
+ }
77
+ values={
78
+ {
79
+ "supportEmail": <MailtoLink
80
+ to="suport@email"
81
+ >
82
+ suport@email
83
+ </MailtoLink>,
84
+ }
85
+ }
86
+ />
87
+
88
+ <format-message-function
89
+ message={
90
+ {
91
+ "defaultMessage": "If you would like a refund on your Certificate of Achievement, please contact our billing address {billingEmail}",
92
+ "description": "Message to learners to contact billing for certificate refunds",
93
+ "id": "learner-dash.courseCard.banners.certificateRefundContactBilling",
94
+ }
95
+ }
96
+ values={
97
+ {
98
+ "billingEmail": <MailtoLink
99
+ to="billing@email"
100
+ >
101
+ billing@email
102
+ </MailtoLink>,
103
+ }
104
+ }
105
+ />
106
+ </Banner>
107
+ `;
108
+
109
+ exports[`CertificateBanner snapshot is restricted and verified with support email 1`] = `
110
+ <Banner
111
+ variant="danger"
112
+ >
113
+ <format-message-function
114
+ message={
115
+ {
116
+ "defaultMessage": "Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know by contacting {supportEmail}.",
117
+ "description": "Restricted certificate warning message",
118
+ "id": "learner-dash.courseCard.banners.certificateRestricted",
119
+ }
120
+ }
121
+ values={
122
+ {
123
+ "supportEmail": <MailtoLink
124
+ to="suport@email"
125
+ >
126
+ suport@email
127
+ </MailtoLink>,
128
+ }
129
+ }
130
+ />
131
+
132
+ If you would like a refund on your Certificate of Achievement, please contact us.
133
+ </Banner>
134
+ `;
135
+
136
+ exports[`CertificateBanner snapshot is restricted with billing email 1`] = `
137
+ <Banner
138
+ variant="danger"
139
+ >
140
+ Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know.
141
+ </Banner>
142
+ `;
143
+
144
+ exports[`CertificateBanner snapshot is restricted with support email 1`] = `
145
+ <Banner
146
+ variant="danger"
147
+ >
148
+ <format-message-function
149
+ message={
150
+ {
151
+ "defaultMessage": "Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know by contacting {supportEmail}.",
152
+ "description": "Restricted certificate warning message",
153
+ "id": "learner-dash.courseCard.banners.certificateRestricted",
154
+ }
155
+ }
156
+ values={
157
+ {
158
+ "supportEmail": <MailtoLink
159
+ to="suport@email"
160
+ >
161
+ suport@email
162
+ </MailtoLink>,
163
+ }
164
+ }
165
+ />
166
+ </Banner>
167
+ `;
168
+
169
+ exports[`CertificateBanner snapshot not passing and audit 1`] = `
170
+ <Banner>
171
+ Grade required to pass the course: 0.8‏%
172
+ </Banner>
173
+ `;
174
+
175
+ exports[`CertificateBanner snapshot not passing and has finished 1`] = `
176
+ <Banner
177
+ variant="warning"
178
+ >
179
+ You are not eligible for a certificate.
180
+
181
+ <Hyperlink
182
+ destination="progressUrl"
183
+ isInline={true}
184
+ >
185
+ View grades.
186
+ </Hyperlink>
187
+ </Banner>
188
+ `;
189
+
190
+ exports[`CertificateBanner snapshot not passing and is downloadable 1`] = `
191
+ <Banner
192
+ icon={[MockFunction icons.CheckCircle]}
193
+ variant="success"
194
+ >
195
+ Congratulations. Your certificate is ready.
196
+ </Banner>
197
+ `;
198
+
199
+ exports[`CertificateBanner snapshot not passing and not audit and not finished 1`] = `
200
+ <Banner
201
+ variant="warning"
202
+ >
203
+ Grade required for a certificate: 0.8‏%
204
+ </Banner>
205
+ `;
@@ -0,0 +1,38 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`CourseBanner audit access expired snapshot: (auditAccessExpired, findAnotherCourse hyperlink) 1`] = `
4
+ <Fragment>
5
+ <Banner>
6
+ Your audit access to this course has expired.
7
+
8
+ <Hyperlink
9
+ destination=""
10
+ isInline={true}
11
+ >
12
+ Find another course
13
+ </Hyperlink>
14
+ </Banner>
15
+ </Fragment>
16
+ `;
17
+
18
+ exports[`CourseBanner snapshot: stacking banners 1`] = `<Fragment />`;
19
+
20
+ exports[`CourseBanner staff snapshot: isStaff 1`] = `<Fragment />`;
21
+
22
+ exports[`CourseBanner too early has start date snapshot 1`] = `
23
+ <Fragment>
24
+ <Banner>
25
+ You can't access this course just yet because the course hasn't started yet. The course will start on 11/11/3030.
26
+ </Banner>
27
+ </Fragment>
28
+ `;
29
+
30
+ exports[`CourseBanner too early no start date snapshot 1`] = `<Fragment />`;
31
+
32
+ exports[`CourseBanner unmet prerequisites snapshot: unmetPrerequisites 1`] = `
33
+ <Fragment>
34
+ <Banner>
35
+ You can't access this course just yet because you have not met the pre-requisites.
36
+ </Banner>
37
+ </Fragment>
38
+ `;
@@ -0,0 +1,53 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`EntitlementBanner snapshot: expiration warning 1`] = `
4
+ <Banner>
5
+ <format-message-function
6
+ message={
7
+ {
8
+ "defaultMessage": "You must {selectSessionButton} by {changeDeadline} to access the course.",
9
+ "description": "Entitlement course message when the entitlement is expiring soon.",
10
+ "id": "learner-dash.courseCard.banners.entitlementExpiringSoon",
11
+ }
12
+ }
13
+ values={
14
+ {
15
+ "changeDeadline": "11/11/2022",
16
+ "selectSessionButton": <Button
17
+ className="m-0 p-0"
18
+ onClick={[MockFunction updateSelectSessionModalCallback(my-test-course-number)]}
19
+ size="inline"
20
+ variant="link"
21
+ >
22
+ select a session
23
+ </Button>,
24
+ }
25
+ }
26
+ />
27
+ </Banner>
28
+ `;
29
+
30
+ exports[`EntitlementBanner snapshot: no sessions available 1`] = `
31
+ <Banner
32
+ variant="warning"
33
+ >
34
+ <format-message-function
35
+ message={
36
+ {
37
+ "defaultMessage": "There are no sessions available at the moment. The course team will create new sessions soon. If no sessions appear, please contact {emailLink} for information.",
38
+ "description": "Entitlement course message when no sessions are available",
39
+ "id": "learner-dash.courseCard.banners.entitlementUnavailable",
40
+ }
41
+ }
42
+ values={
43
+ {
44
+ "emailLink": <MailtoLink
45
+ to="test-support-email"
46
+ >
47
+ test-support-email
48
+ </MailtoLink>,
49
+ }
50
+ }
51
+ />
52
+ </Banner>
53
+ `;
@@ -0,0 +1,41 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`CourseCardBanners render with isEnrolled false 1`] = `
4
+ <div
5
+ className="course-card-banners"
6
+ data-testid="CourseCardBanners"
7
+ >
8
+ <RelatedProgramsBanner
9
+ cardId="test-card-id"
10
+ />
11
+ <CourseBannerSlot
12
+ cardId="test-card-id"
13
+ />
14
+ <EntitlementBanner
15
+ cardId="test-card-id"
16
+ />
17
+ </div>
18
+ `;
19
+
20
+ exports[`CourseCardBanners renders default CourseCardBanners 1`] = `
21
+ <div
22
+ className="course-card-banners"
23
+ data-testid="CourseCardBanners"
24
+ >
25
+ <RelatedProgramsBanner
26
+ cardId="test-card-id"
27
+ />
28
+ <CourseBannerSlot
29
+ cardId="test-card-id"
30
+ />
31
+ <EntitlementBanner
32
+ cardId="test-card-id"
33
+ />
34
+ <CertificateBanner
35
+ cardId="test-card-id"
36
+ />
37
+ <CreditBanner
38
+ cardId="test-card-id"
39
+ />
40
+ </div>
41
+ `;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { reduxHooks } from '../../../../hooks';
5
+ import CourseBannerSlot from '../../../../slots/CourseBannerSlot';
6
+
7
+ import CertificateBanner from './CertificateBanner';
8
+ import CreditBanner from './CreditBanner';
9
+ import EntitlementBanner from './EntitlementBanner';
10
+ import RelatedProgramsBanner from './RelatedProgramsBanner';
11
+
12
+ export const CourseCardBanners = ({ cardId }) => {
13
+ const { isEnrolled } = reduxHooks.useCardEnrollmentData(cardId);
14
+ return (
15
+ <div className="course-card-banners" data-testid="CourseCardBanners">
16
+ <RelatedProgramsBanner cardId={cardId} />
17
+ <CourseBannerSlot cardId={cardId} />
18
+ <EntitlementBanner cardId={cardId} />
19
+ {isEnrolled && <CertificateBanner cardId={cardId} />}
20
+ {isEnrolled && <CreditBanner cardId={cardId} />}
21
+ </div>
22
+ );
23
+ };
24
+ CourseCardBanners.propTypes = {
25
+ cardId: PropTypes.string.isRequired,
26
+ };
27
+
28
+ export default CourseCardBanners;
@@ -0,0 +1,32 @@
1
+ import { shallow } from '@edx/react-unit-test-utils';
2
+
3
+ import { reduxHooks } from 'hooks';
4
+
5
+ import CourseCardBanners from '.';
6
+
7
+ jest.mock('./CourseBanner', () => 'CourseBanner');
8
+ jest.mock('./CertificateBanner', () => 'CertificateBanner');
9
+ jest.mock('./CreditBanner', () => 'CreditBanner');
10
+ jest.mock('./EntitlementBanner', () => 'EntitlementBanner');
11
+ jest.mock('./RelatedProgramsBanner', () => 'RelatedProgramsBanner');
12
+
13
+ jest.mock('hooks', () => ({
14
+ reduxHooks: {
15
+ useCardEnrollmentData: jest.fn(() => ({ isEnrolled: true })),
16
+ },
17
+ }));
18
+
19
+ describe('CourseCardBanners', () => {
20
+ const props = {
21
+ cardId: 'test-card-id',
22
+ };
23
+ test('renders default CourseCardBanners', () => {
24
+ const wrapper = shallow(<CourseCardBanners {...props} />);
25
+ expect(wrapper.snapshot).toMatchSnapshot();
26
+ });
27
+ test('render with isEnrolled false', () => {
28
+ reduxHooks.useCardEnrollmentData.mockReturnValueOnce({ isEnrolled: false });
29
+ const wrapper = shallow(<CourseCardBanners {...props} />);
30
+ expect(wrapper.snapshot).toMatchSnapshot();
31
+ });
32
+ });
@@ -0,0 +1,106 @@
1
+ import { defineMessages } from '@openedx/frontend-base';
2
+
3
+ const messages = defineMessages({
4
+ auditAccessExpired: {
5
+ id: 'learner-dash.courseCard.banners.auditAccessExpired',
6
+ description: 'Audit access expiration banner message',
7
+ defaultMessage: 'Your audit access to this course has expired.',
8
+ },
9
+ findAnotherCourse: {
10
+ id: 'learner-dash.courseCard.banners.findAnotherCourse',
11
+ description: 'Action prompt taking learners to course exploration',
12
+ defaultMessage: 'Find another course',
13
+ },
14
+ certRestricted: {
15
+ id: 'learner-dash.courseCard.banners.certificateRestricted',
16
+ description: 'Restricted certificate warning message',
17
+ defaultMessage: 'Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know by contacting {supportEmail}.',
18
+ },
19
+ certRestrictedNoEmail: {
20
+ id: 'learner-dash.courseCard.banners.certificateRestrictedNoEmail',
21
+ description: 'Restricted certificate warning message',
22
+ defaultMessage: 'Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know.',
23
+ },
24
+ certRefundContactBilling: {
25
+ id: 'learner-dash.courseCard.banners.certificateRefundContactBilling',
26
+ description: 'Message to learners to contact billing for certificate refunds',
27
+ defaultMessage: 'If you would like a refund on your Certificate of Achievement, please contact our billing address {billingEmail}',
28
+ },
29
+ certRefundContactBillingNoEmail: {
30
+ id: 'learner-dash.courseCard.banners.certificateRefundContactBillingNoEmail',
31
+ description: 'Message to learners to contact billing for certificate refunds',
32
+ defaultMessage: 'If you would like a refund on your Certificate of Achievement, please contact us.',
33
+ },
34
+ passingGrade: {
35
+ id: 'learner-dash.courseCard.banners.passingGrade',
36
+ description: 'Message to learners with minimum passing grade for the course',
37
+ defaultMessage: 'Grade required to pass the course: {minPassingGrade}\u200f%',
38
+ },
39
+ notEligibleForCert: {
40
+ id: 'learner-dash.courseCard.banners.notEligibleForCert',
41
+ description: 'Certificate inelligibility message',
42
+ defaultMessage: 'You are not eligible for a certificate.',
43
+ },
44
+ viewGrades: {
45
+ id: 'learner-dash.courseCard.banners.viewGrades',
46
+ description: 'Gradses link text',
47
+ defaultMessage: 'View grades.',
48
+ },
49
+ certReady: {
50
+ id: 'learner-dash.courseCard.banners.certReady',
51
+ description: 'Certificate ready message',
52
+ defaultMessage: 'Congratulations. Your certificate is ready.',
53
+ },
54
+ viewCertificate: {
55
+ id: 'learner-dash.courseCard.banners.viewCertificate',
56
+ description: 'Certificate link text',
57
+ defaultMessage: 'View Certificate.',
58
+ },
59
+ certMinGrade: {
60
+ id: 'learner-dash.courseCard.banners.certMinGrade',
61
+ description: 'Passing grade requirement message',
62
+ defaultMessage: 'Grade required for a certificate: {minPassingGrade}\u200f%',
63
+ },
64
+ downloadCertificate: {
65
+ id: 'learner-dash.courseCard.banners.downloadCertificate',
66
+ description: 'Certificate download link text',
67
+ defaultMessage: 'Download Certificate.',
68
+ },
69
+ gradeAndCertReadyAfter: {
70
+ id: 'learner-dash.courseCard.banners.gradseAndCertReadyAfter',
71
+ description: 'Grade and certificate availability date message',
72
+ defaultMessage: 'Your grade and certificate will be ready after {availableDate}.',
73
+ },
74
+ entitlementUnavailable: {
75
+ id: 'learner-dash.courseCard.banners.entitlementUnavailable',
76
+ description: 'Entitlement course message when no sessions are available',
77
+ defaultMessage: 'There are no sessions available at the moment. The course team will create new sessions soon. If no sessions appear, please contact {emailLink} for information.',
78
+ },
79
+ entitlementExpiringSoon: {
80
+ id: 'learner-dash.courseCard.banners.entitlementExpiringSoon',
81
+ description: 'Entitlement course message when the entitlement is expiring soon.',
82
+ defaultMessage: 'You must {selectSessionButton} by {changeDeadline} to access the course.',
83
+ },
84
+ entitlementExpired: {
85
+ id: 'learner-dash.courseCard.banners.entitlementExpired',
86
+ description: 'Entitlement course message when the entitlement is expired.',
87
+ defaultMessage: 'You can no longer change sessions.',
88
+ },
89
+ selectSession: {
90
+ id: 'learner-dash.courseCard.banners.selectSession',
91
+ description: 'Entitlement session selection link text',
92
+ defaultMessage: 'select a session',
93
+ },
94
+ prerequisitesNotMet: {
95
+ id: 'learner-dash.courseCard.banners.prerequisitesNotMet',
96
+ description: 'Message to learners with unmet prerequisites',
97
+ defaultMessage: 'You can\'t access this course just yet because you have not met the pre-requisites.',
98
+ },
99
+ courseHasNotStarted: {
100
+ id: 'learner-dash.courseCard.banners.courseHasNotStarted',
101
+ description: 'Course has not started message',
102
+ defaultMessage: 'You can\'t access this course just yet because the course hasn\'t started yet. The course will start on {startDate}.',
103
+ },
104
+ });
105
+
106
+ export default messages;
@@ -0,0 +1,56 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`CourseCard Details component does not have change session button on regular course 1`] = `
4
+ <div>
5
+ <span
6
+ class="small"
7
+ data-testid="CourseCardDetails"
8
+ >
9
+ provider-name
10
+
11
+ test-course-number
12
+ • access-message
13
+ </span>
14
+ </div>
15
+ `;
16
+
17
+ exports[`CourseCard Details component has change session button on entitlement course 1`] = `
18
+ <div>
19
+ <span
20
+ class="small"
21
+ data-testid="CourseCardDetails"
22
+ >
23
+ provider-name
24
+
25
+ test-course-number
26
+ • access-message
27
+
28
+ <button
29
+ class="m-0 p-0"
30
+ variant="link"
31
+ >
32
+ change-or-leave-session-message
33
+ </button>
34
+ </span>
35
+ </div>
36
+ `;
37
+
38
+ exports[`CourseCard Details component has change session button on entitlement course but no access message 1`] = `
39
+ <div>
40
+ <span
41
+ class="small"
42
+ data-testid="CourseCardDetails"
43
+ >
44
+ provider-name
45
+
46
+ test-course-number
47
+
48
+ <button
49
+ class="m-0 p-0"
50
+ variant="link"
51
+ >
52
+ change-or-leave-session-message
53
+ </button>
54
+ </span>
55
+ </div>
56
+ `;
@@ -0,0 +1,67 @@
1
+ import { useIntl } from '@openedx/frontend-base';
2
+ import { utilHooks, reduxHooks } from '../../../../hooks';
3
+
4
+ import * as hooks from './hooks';
5
+ import messages from './messages';
6
+
7
+ export const useAccessMessage = ({ cardId }) => {
8
+ const { formatMessage } = useIntl();
9
+ const enrollment = reduxHooks.useCardEnrollmentData(cardId);
10
+ const courseRun = reduxHooks.useCardCourseRunData(cardId);
11
+ const formatDate = utilHooks.useFormatDate();
12
+ if (!courseRun.isStarted) {
13
+ if (!courseRun.startDate && !courseRun.advertisedStart) {
14
+ return null;
15
+ }
16
+ const startDate = courseRun.advertisedStart ?? formatDate(courseRun.startDate);
17
+ return formatMessage(messages.courseStarts, { startDate });
18
+ }
19
+ if (enrollment.isEnrolled) {
20
+ const { isArchived, endDate } = courseRun;
21
+ const {
22
+ accessExpirationDate,
23
+ isAuditAccessExpired,
24
+ } = enrollment;
25
+
26
+ if (enrollment.isAudit && accessExpirationDate) {
27
+ return formatMessage(
28
+ isAuditAccessExpired ? messages.accessExpired : messages.accessExpires,
29
+ { accessExpirationDate: formatDate(accessExpirationDate) },
30
+ );
31
+ }
32
+ if (!endDate) {
33
+ return null;
34
+ }
35
+ return formatMessage(
36
+ isArchived ? messages.courseEnded : messages.courseEnds,
37
+ { endDate: formatDate(endDate) },
38
+ );
39
+ }
40
+ return null;
41
+ };
42
+
43
+ export const useCardDetailsData = ({ cardId }) => {
44
+ const { formatMessage } = useIntl();
45
+ const providerName = reduxHooks.useCardProviderData(cardId).name;
46
+ const { courseNumber } = reduxHooks.useCardCourseData(cardId);
47
+ const {
48
+ isEntitlement,
49
+ isFulfilled,
50
+ canChange,
51
+ } = reduxHooks.useCardEntitlementData(cardId);
52
+
53
+ const openSessionModal = reduxHooks.useUpdateSelectSessionModalCallback(cardId);
54
+
55
+ return {
56
+ providerName: providerName ?? formatMessage(messages.unknownProviderName),
57
+ accessMessage: hooks.useAccessMessage({ cardId }),
58
+ isEntitlement,
59
+ isFulfilled,
60
+ canChange,
61
+ openSessionModal,
62
+ courseNumber,
63
+ changeOrLeaveSessionMessage: formatMessage(messages.changeOrLeaveSessionButton),
64
+ };
65
+ };
66
+
67
+ export default useCardDetailsData;