richie-education 2.24.0 → 2.25.0-b2.dev101

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 (492) hide show
  1. package/.eslintignore +2 -0
  2. package/.nvmrc +1 -1
  3. package/.prettierignore +2 -0
  4. package/.storybook/preview-body.html +1 -1
  5. package/.storybook/preview.tsx +5 -2
  6. package/cunningham.cjs +52 -43
  7. package/i18n/locales/ar-SA.json +500 -100
  8. package/i18n/locales/es-ES.json +500 -100
  9. package/i18n/locales/fa-IR.json +500 -100
  10. package/i18n/locales/fr-CA.json +564 -164
  11. package/i18n/locales/fr-FR.json +517 -117
  12. package/i18n/locales/ko-KR.json +500 -100
  13. package/i18n/locales/pt-PT.json +526 -126
  14. package/i18n/locales/ru-RU.json +500 -100
  15. package/i18n/locales/vi-VN.json +1734 -0
  16. package/jest/setup.ts +11 -1
  17. package/js/api/enrollment.ts +1 -1
  18. package/js/api/joanie.spec.ts +63 -2
  19. package/js/api/joanie.ts +218 -141
  20. package/js/api/lms/dummy.spec.ts +9 -1
  21. package/js/api/lms/dummy.ts +63 -10
  22. package/js/api/lms/joanie.spec.ts +49 -31
  23. package/js/api/lms/joanie.ts +53 -35
  24. package/js/api/lms/openedx-hawthorn.spec.ts +27 -11
  25. package/js/api/lms/openedx-hawthorn.ts +7 -6
  26. package/js/components/AddressesManagement/AddressForm/index.spec.tsx +157 -0
  27. package/js/components/AddressesManagement/AddressForm/index.stories.tsx +36 -0
  28. package/js/components/AddressesManagement/AddressForm/index.tsx +163 -0
  29. package/js/components/AddressesManagement/{validationSchema.ts → AddressForm/validationSchema.ts} +1 -23
  30. package/js/components/AddressesManagement/_styles.scss +1 -1
  31. package/js/components/AddressesManagement/index.spec.tsx +171 -202
  32. package/js/components/AddressesManagement/index.stories.tsx +29 -0
  33. package/js/components/AddressesManagement/index.tsx +11 -3
  34. package/js/components/Badge/index.spec.tsx +17 -0
  35. package/js/components/Badge/index.stories.tsx +22 -0
  36. package/js/components/Badge/index.tsx +18 -0
  37. package/js/components/Banner/index.tsx +6 -1
  38. package/js/components/ContractFrame/AbstractContractFrame.spec.tsx +332 -0
  39. package/js/components/ContractFrame/AbstractContractFrame.tsx +289 -0
  40. package/js/components/ContractFrame/LearnerContractFrame.spec.tsx +125 -0
  41. package/js/components/ContractFrame/LearnerContractFrame.tsx +42 -0
  42. package/js/components/ContractFrame/OrganizationContractFrame.spec.tsx +167 -0
  43. package/js/components/ContractFrame/OrganizationContractFrame.tsx +70 -0
  44. package/js/components/ContractFrame/_styles.scss +62 -0
  45. package/js/components/ContractFrame/iframe-manager.js +158 -0
  46. package/js/components/ContractFrame/index.ts +5 -0
  47. package/js/components/ContractStatus/index.spec.tsx +120 -0
  48. package/js/components/ContractStatus/index.tsx +67 -0
  49. package/js/components/CourseGlimpse/CourseGlimpseFooter.tsx +7 -7
  50. package/js/components/CourseGlimpse/index.tsx +5 -1
  51. package/js/components/CourseGlimpse/utils.ts +24 -16
  52. package/js/components/CourseGlimpseList/index.spec.tsx +1 -1
  53. package/js/components/CourseGlimpseList/index.tsx +1 -1
  54. package/js/components/CourseGlimpseList/utils.ts +3 -2
  55. package/js/components/DjangoCMSTemplate/index.spec.tsx +2 -2
  56. package/js/components/DownloadCertificateButton/index.tsx +58 -0
  57. package/js/components/DownloadContractButton/index.spec.tsx +155 -0
  58. package/js/components/DownloadContractButton/index.tsx +48 -0
  59. package/js/components/Form/CountrySelectField.tsx +28 -16
  60. package/js/components/Form/Input/index.spec.tsx +76 -0
  61. package/js/components/Form/Input/index.tsx +47 -0
  62. package/js/components/Form/Select/index.spec.tsx +99 -0
  63. package/js/components/Form/Select/index.tsx +43 -0
  64. package/js/components/{AddressesManagement → Form}/ValidationErrors.ts +10 -5
  65. package/js/components/Form/index.ts +5 -1
  66. package/js/components/Form/messages.ts +14 -0
  67. package/js/components/Form/test-utils.ts +19 -0
  68. package/js/components/Form/utils.spec.ts +72 -0
  69. package/js/components/Form/utils.ts +37 -0
  70. package/js/components/Icon/index.stories.tsx +2 -1
  71. package/js/components/Modal/_styles.scss +0 -8
  72. package/js/components/Modal/index.spec.tsx +0 -6
  73. package/js/components/Modal/index.tsx +23 -17
  74. package/js/components/PaymentButton/_styles.scss +26 -0
  75. package/js/{widgets/CourseProductItem → components/PaymentButton}/components/PaymentInterfaces/Dummy.tsx +1 -1
  76. package/js/{widgets/CourseProductItem → components/PaymentButton}/components/PaymentInterfaces/PayplugLightbox.tsx +30 -7
  77. package/js/{widgets/CourseProductItem → components/PaymentButton}/components/PaymentInterfaces/__mocks__/index.tsx +1 -1
  78. package/js/{widgets/CourseProductItem → components/PaymentButton}/components/PaymentInterfaces/index.spec.tsx +5 -3
  79. package/js/{widgets/CourseProductItem → components/PaymentButton}/components/PaymentInterfaces/index.tsx +7 -5
  80. package/js/components/PaymentButton/hooks/useTerms.tsx +74 -0
  81. package/js/components/PaymentButton/index.spec.tsx +1038 -0
  82. package/js/{widgets/CourseProductItem/components → components}/PaymentButton/index.tsx +94 -41
  83. package/js/components/PurchaseButton/index.spec.tsx +377 -0
  84. package/js/components/PurchaseButton/index.stories.tsx +15 -0
  85. package/js/{widgets/CourseProductItem/components → components}/PurchaseButton/index.tsx +72 -23
  86. package/js/components/PurchaseButton/styles.scss +7 -0
  87. package/js/components/RegisteredAddress/_styles.scss +1 -3
  88. package/js/components/RegisteredAddress/index.spec.tsx +1 -1
  89. package/js/components/RegisteredAddress/index.stories.tsx +40 -0
  90. package/js/components/RegisteredAddress/index.tsx +17 -19
  91. package/js/components/SaleTunnel/_styles.scss +11 -0
  92. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/RegisteredCreditCard/index.tsx +4 -10
  93. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/SaleTunnelStepPayment/_styles.scss +7 -0
  94. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/SaleTunnelStepPayment/index.spec.tsx +85 -61
  95. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/SaleTunnelStepPayment/index.tsx +55 -57
  96. package/js/components/SaleTunnel/components/SaleTunnelStepResume/_styles.scss +63 -0
  97. package/js/components/SaleTunnel/components/SaleTunnelStepResume/index.spec.tsx +80 -0
  98. package/js/components/SaleTunnel/components/SaleTunnelStepResume/index.tsx +88 -0
  99. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/SaleTunnelStepValidation/CourseRunsList.tsx +6 -2
  100. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/SaleTunnelStepValidation/_styles.scss +5 -0
  101. package/js/components/SaleTunnel/components/SaleTunnelStepValidation/index.spec.tsx +170 -0
  102. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/SaleTunnelStepValidation/index.tsx +41 -10
  103. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/StepBreadcrumb/index.spec.tsx +1 -1
  104. package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/StepBreadcrumb/index.tsx +1 -1
  105. package/js/components/SaleTunnel/context.tsx +44 -0
  106. package/js/{widgets/CourseProductItem/components → components}/SaleTunnel/index.spec.tsx +27 -22
  107. package/js/{widgets/CourseProductItem/components → components}/SaleTunnel/index.tsx +96 -24
  108. package/js/components/SignContractButton/index.omniscientOrders.spec.tsx +135 -0
  109. package/js/components/SignContractButton/index.spec.tsx +213 -0
  110. package/js/components/SignContractButton/index.tsx +97 -0
  111. package/js/components/SuccessIcon/_styles.scss +66 -0
  112. package/js/components/SuccessIcon/index.tsx +10 -0
  113. package/js/components/TeacherDashboardCourseList/_styles.scss +0 -1
  114. package/js/components/TeacherDashboardCourseList/index.spec.tsx +9 -9
  115. package/js/components/TeacherDashboardCourseList/index.tsx +25 -31
  116. package/js/contexts/JoanieApiContext/index.spec.tsx +1 -1
  117. package/js/contexts/SessionContext/BaseSessionProvider.tsx +12 -22
  118. package/js/contexts/SessionContext/JoanieSessionProvider.spec.tsx +14 -0
  119. package/js/contexts/SessionContext/JoanieSessionProvider.tsx +33 -34
  120. package/js/contexts/SessionContext/index.spec.tsx +6 -7
  121. package/js/hooks/useBreadcrumbsPlaceholders.tsx +1 -1
  122. package/js/hooks/useContractAbilities/index.spec.ts +27 -0
  123. package/js/hooks/useContractAbilities/index.ts +8 -0
  124. package/js/hooks/useContractArchive/index.download.spec.tsx +126 -0
  125. package/js/hooks/useContractArchive/index.spec.tsx +91 -0
  126. package/js/hooks/useContractArchive/index.ts +64 -0
  127. package/js/hooks/useContracts/index.tsx +68 -0
  128. package/js/hooks/useCourseProductRelation/index.ts +8 -5
  129. package/js/hooks/useCourseProductUnion/index.spec.tsx +14 -10
  130. package/js/hooks/useCourseProductUnion/index.ts +6 -2
  131. package/js/hooks/useCourseProducts.ts +45 -0
  132. package/js/hooks/useCourseSearchParams/computeNewFilterValue.ts +3 -3
  133. package/js/hooks/useCourses/index.spec.tsx +2 -2
  134. package/js/hooks/useCourses/index.ts +4 -4
  135. package/js/hooks/useCreditCards/index.spec.tsx +4 -4
  136. package/js/hooks/useDashboardAddressForm.tsx +85 -87
  137. package/js/hooks/useDownloadCertificate/index.spec.tsx +19 -6
  138. package/js/hooks/useDownloadCertificate/index.tsx +2 -20
  139. package/js/hooks/useEnrollments.ts +1 -1
  140. package/js/hooks/useJoanieUserAbilities/index.not.isJoanieEnabled.spec.tsx +17 -0
  141. package/js/hooks/useJoanieUserAbilities/index.spec.tsx +68 -0
  142. package/js/hooks/useJoanieUserAbilities/index.tsx +11 -0
  143. package/js/hooks/useJoanieUserProfile.tsx +34 -0
  144. package/js/hooks/useOrders.ts +69 -26
  145. package/js/hooks/useOrganizations/index.ts +1 -1
  146. package/js/hooks/useProductOrder/index.spec.tsx +113 -0
  147. package/js/hooks/useProductOrder/index.tsx +33 -0
  148. package/js/hooks/useQueryKeyInvalidateListener.tsx +16 -0
  149. package/js/hooks/useResources/index.spec.tsx +30 -29
  150. package/js/hooks/useResources/index.tsx +11 -4
  151. package/js/hooks/useResources/useResourcesOmniscient.ts +2 -2
  152. package/js/hooks/useResources/useResourcesRoot.ts +21 -17
  153. package/js/hooks/useTeacherPendingContractsCount/index.ts +34 -0
  154. package/js/hooks/useUnionResource/index.spec.tsx +5 -2
  155. package/js/hooks/useUnionResource/index.ts +20 -3
  156. package/js/hooks/useUnionResource/utils/fetchEntity.ts +5 -4
  157. package/js/index.tsx +2 -2
  158. package/js/pages/DashboardAddressesManagement/DashboardAddressBox.tsx +1 -1
  159. package/js/pages/DashboardAddressesManagement/DashboardCreateAddress.spec.tsx +79 -72
  160. package/js/pages/DashboardAddressesManagement/DashboardCreateAddress.tsx +4 -4
  161. package/js/pages/DashboardAddressesManagement/DashboardEditAddress.spec.tsx +32 -23
  162. package/js/pages/DashboardAddressesManagement/DashboardEditAddress.tsx +6 -6
  163. package/js/pages/DashboardAddressesManagement/DashboardEditAddressLoader.tsx +2 -2
  164. package/js/pages/DashboardAddressesManagement/index.spec.tsx +4 -3
  165. package/js/pages/DashboardAddressesManagement/index.tsx +5 -5
  166. package/js/pages/DashboardCertificates/index.spec.tsx +3 -2
  167. package/js/pages/DashboardCertificates/index.tsx +2 -1
  168. package/js/pages/DashboardContracts/_styles.scss +8 -0
  169. package/js/pages/DashboardContracts/index.spec.tsx +147 -0
  170. package/js/pages/DashboardContracts/index.tsx +76 -0
  171. package/js/pages/DashboardCourses/index.spec.tsx +81 -61
  172. package/js/pages/DashboardCourses/index.tsx +15 -12
  173. package/js/pages/DashboardCourses/useOrdersEnrollments.tsx +34 -8
  174. package/js/pages/DashboardCreditCardsManagement/DashboardCreditCardBox.tsx +1 -1
  175. package/js/pages/DashboardCreditCardsManagement/DashboardEditCreditCard.spec.tsx +7 -6
  176. package/js/pages/DashboardCreditCardsManagement/DashboardEditCreditCard.tsx +43 -45
  177. package/js/pages/DashboardCreditCardsManagement/DashboardEditCreditCardLoader.tsx +2 -2
  178. package/js/pages/DashboardCreditCardsManagement/index.spec.tsx +13 -12
  179. package/js/pages/DashboardCreditCardsManagement/index.tsx +3 -3
  180. package/js/pages/DashboardOrderLayout/_styles.scss +5 -0
  181. package/js/pages/DashboardOrderLayout/index.spec.tsx +8 -8
  182. package/js/pages/DashboardOrderLayout/index.tsx +11 -6
  183. package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardContracts/index.spec.tsx +358 -0
  184. package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardContracts/index.tsx +129 -0
  185. package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardCourseContractsLayout/index.tsx +26 -0
  186. package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardOrganizationContractsLayout/index.tsx +26 -0
  187. package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.spec.tsx +136 -0
  188. package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.timer.spec.tsx +144 -0
  189. package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.tsx +73 -0
  190. package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.spec.tsx +185 -0
  191. package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.tsx +47 -0
  192. package/js/pages/TeacherDashboardContractsLayout/components/ContractFiltersBar/index.spec.tsx +179 -0
  193. package/js/pages/TeacherDashboardContractsLayout/components/ContractFiltersBar/index.tsx +86 -0
  194. package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.spec.tsx +109 -0
  195. package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.tsx +60 -0
  196. package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.spec.tsx +124 -0
  197. package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.tsx +73 -0
  198. package/js/pages/TeacherDashboardContractsLayout/hooks/useDefaultOrganizationId/index.spec.tsx +134 -0
  199. package/js/pages/TeacherDashboardContractsLayout/hooks/useDefaultOrganizationId/index.tsx +28 -0
  200. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/contractArchiveLocalStorage.spec.ts +85 -0
  201. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/contractArchiveLocalStorage.ts +50 -0
  202. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.spec.tsx +266 -0
  203. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.tsx +153 -0
  204. package/js/pages/TeacherDashboardContractsLayout/hooks/useHasContractToDownload/index.spec.tsx +100 -0
  205. package/js/pages/TeacherDashboardContractsLayout/hooks/useHasContractToDownload/index.tsx +27 -0
  206. package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractFilters/index.spec.tsx +193 -0
  207. package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractFilters/index.tsx +44 -0
  208. package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractsToSign.tsx +32 -0
  209. package/js/pages/TeacherDashboardContractsLayout/index.ts +2 -0
  210. package/js/pages/TeacherDashboardContractsLayout/styles.scss +15 -0
  211. package/js/pages/{TeacherCourseDashboardLoader → TeacherDashboardCourseLoader}/CourseRunList/CourseRunListCell/index.spec.tsx +1 -1
  212. package/js/pages/{TeacherCourseDashboardLoader → TeacherDashboardCourseLoader}/CourseRunList/_styles.scss +1 -2
  213. package/js/pages/{TeacherCourseDashboardLoader → TeacherDashboardCourseLoader}/CourseRunList/index.spec.tsx +2 -2
  214. package/js/pages/{TeacherCourseDashboardLoader → TeacherDashboardCourseLoader}/CourseRunList/utils.spec.tsx +1 -1
  215. package/js/pages/{TeacherCourseDashboardLoader → TeacherDashboardCourseLoader}/CourseRunList/utils.tsx +11 -10
  216. package/js/pages/{TeacherCourseDashboardLoader → TeacherDashboardCourseLoader}/index.tsx +9 -8
  217. package/js/pages/{TeacherCoursesDashboardLoader → TeacherDashboardCoursesLoader}/index.spec.tsx +17 -17
  218. package/js/pages/{TeacherCoursesDashboardLoader → TeacherDashboardCoursesLoader}/index.tsx +7 -7
  219. package/js/pages/{TeacherOrganizationCourseDashboardLoader → TeacherDashboardOrganizationCourseLoader}/index.tsx +5 -5
  220. package/js/pages/{TeacherTrainingDashboard/TeacherTrainingDashboardLoader.tsx → TeacherDashboardTraining/TeacherDashboardTrainingLoader.tsx} +10 -9
  221. package/js/pages/{TeacherTrainingDashboard → TeacherDashboardTraining}/index.spec.tsx +76 -6
  222. package/js/pages/{TeacherTrainingDashboard → TeacherDashboardTraining}/index.tsx +6 -6
  223. package/js/settings.dev.dist.ts +3 -0
  224. package/js/settings.ts +29 -1
  225. package/js/translations/ar-SA.json +1 -1
  226. package/js/translations/es-ES.json +1 -1
  227. package/js/translations/fa-IR.json +1 -1
  228. package/js/translations/fr-CA.json +1 -1
  229. package/js/translations/fr-FR.json +1 -1
  230. package/js/translations/ko-KR.json +1 -1
  231. package/js/translations/pt-PT.json +1 -1
  232. package/js/translations/ru-RU.json +1 -1
  233. package/js/translations/vi-VN.json +1 -0
  234. package/js/types/Joanie.ts +263 -80
  235. package/js/types/Suggestion.ts +2 -2
  236. package/js/types/User.ts +19 -1
  237. package/js/types/commonDataProps.ts +3 -0
  238. package/js/types/index.ts +1 -1
  239. package/js/utils/AbilitiesHelper/contractAbilities.spec.ts +35 -0
  240. package/js/utils/AbilitiesHelper/contractAbilities.ts +14 -0
  241. package/js/utils/AbilitiesHelper/index.ts +71 -0
  242. package/js/utils/AbilitiesHelper/joanieUserProfileAbilities.spec.ts +55 -0
  243. package/js/utils/AbilitiesHelper/joanieUserProfileAbilities.ts +16 -0
  244. package/js/utils/AbilitiesHelper/types.ts +36 -0
  245. package/js/utils/ContractHelper/index.spec.ts +73 -0
  246. package/js/utils/ContractHelper/index.ts +72 -0
  247. package/js/utils/CourseRuns/index.spec.tsx +20 -1
  248. package/js/utils/CourseRuns/index.ts +14 -2
  249. package/js/utils/CoursesHelper/index.spec.ts +45 -55
  250. package/js/utils/CoursesHelper/index.ts +6 -7
  251. package/js/utils/CreditCardHelper/index.spec.tsx +26 -22
  252. package/js/utils/CreditCardHelper/index.tsx +19 -6
  253. package/js/utils/ObjectHelper/index.spec.ts +18 -10
  254. package/js/utils/ObjectHelper/index.ts +9 -0
  255. package/js/utils/OrderHelper/index.ts +32 -0
  256. package/js/utils/ProductHelper/index.ts +5 -1
  257. package/js/utils/StringHelper/index.spec.tsx +11 -0
  258. package/js/utils/StringHelper/index.ts +8 -0
  259. package/js/utils/UserHelper/index.spec.ts +18 -0
  260. package/js/utils/UserHelper/index.ts +8 -0
  261. package/js/utils/download.ts +43 -0
  262. package/js/utils/errors/HttpError.ts +10 -0
  263. package/js/utils/indirection/window.ts +1 -1
  264. package/js/utils/react-query/createQueryClient.ts +12 -21
  265. package/js/utils/react-query/useLocalizedQueryKey.ts +1 -1
  266. package/js/utils/react-query/useSessionMutation/index.spec.tsx +8 -8
  267. package/js/utils/react-query/useSessionMutation/index.ts +6 -11
  268. package/js/utils/react-query/useSessionQuery/index.spec.tsx +36 -8
  269. package/js/utils/react-query/useSessionQuery/index.ts +14 -21
  270. package/js/utils/search/getSuggestionsSection/index.spec.ts +4 -3
  271. package/js/utils/search/getSuggestionsSection/index.ts +4 -1
  272. package/js/utils/search/index.tsx +8 -3
  273. package/js/utils/test/createTestQueryClient.ts +7 -7
  274. package/js/utils/test/expectBanner.ts +16 -3
  275. package/js/utils/test/factories/factories.ts +4 -4
  276. package/js/utils/test/factories/joanie.spec.ts +7 -0
  277. package/js/utils/test/factories/joanie.ts +214 -63
  278. package/js/utils/test/factories/reactQuery.ts +1 -1
  279. package/js/utils/test/factories/richie.ts +4 -2
  280. package/js/utils/test/mockCourseProductWithOrder.ts +28 -0
  281. package/js/utils/test/mockPaginatedResponse.ts +1 -1
  282. package/js/utils/test/render.tsx +72 -0
  283. package/js/utils/test/wrappers/IntlWrapper.tsx +23 -0
  284. package/js/utils/test/wrappers/JoanieAppWrapper.tsx +42 -0
  285. package/js/utils/test/wrappers/PresentationalAppWrapper.tsx +18 -0
  286. package/js/utils/test/wrappers/ReactQueryWrapper.tsx +16 -0
  287. package/js/utils/test/wrappers/RouterWrapper.tsx +29 -0
  288. package/js/utils/test/wrappers/types.ts +26 -0
  289. package/js/widgets/Dashboard/components/DashboardAvatar/_styles.scss +17 -5
  290. package/js/widgets/Dashboard/components/DashboardAvatar/index.spec.tsx +9 -2
  291. package/js/widgets/Dashboard/components/DashboardAvatar/index.tsx +16 -5
  292. package/js/widgets/Dashboard/components/DashboardBox/index.stories.tsx +1 -1
  293. package/js/widgets/Dashboard/components/DashboardBreadcrumbs/_styles.scss +1 -0
  294. package/js/widgets/Dashboard/components/DashboardBreadcrumbs/index.tsx +7 -4
  295. package/js/widgets/Dashboard/components/DashboardCard/index.spec.tsx +1 -1
  296. package/js/widgets/Dashboard/components/DashboardCard/index.stories.tsx +3 -3
  297. package/js/widgets/Dashboard/components/DashboardCard/index.tsx +2 -2
  298. package/js/widgets/Dashboard/components/DashboardItem/Certificate/index.spec.tsx +49 -9
  299. package/js/widgets/Dashboard/components/DashboardItem/Certificate/index.tsx +27 -73
  300. package/js/widgets/Dashboard/components/DashboardItem/CertificateStatus/index.spec.tsx +65 -0
  301. package/js/widgets/Dashboard/components/DashboardItem/CertificateStatus/index.tsx +59 -0
  302. package/js/widgets/Dashboard/components/DashboardItem/Contract/_styles.scss +29 -0
  303. package/js/widgets/Dashboard/components/DashboardItem/Contract/index.spec.tsx +197 -0
  304. package/js/widgets/Dashboard/components/DashboardItem/Contract/index.stories.tsx +34 -0
  305. package/js/widgets/Dashboard/components/DashboardItem/Contract/index.tsx +53 -0
  306. package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/hooks/useCourseRunPeriodMessage.ts +76 -0
  307. package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.spec.tsx +158 -0
  308. package/js/widgets/Dashboard/components/DashboardItem/{DashboardItemCourseEnrolling.stories.tsx → CourseEnrolling/index.stories.tsx} +6 -6
  309. package/js/widgets/Dashboard/components/DashboardItem/{DashboardItemCourseEnrolling.tsx → CourseEnrolling/index.tsx} +141 -84
  310. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.spec.tsx +40 -37
  311. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.tsx +29 -11
  312. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +248 -0
  313. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.tsx +89 -0
  314. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.spec.tsx +188 -117
  315. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +124 -78
  316. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.spec.tsx +299 -0
  317. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.useUnionResource.cache.spec.tsx +286 -0
  318. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderReadonly.stories.tsx +9 -5
  319. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderWritable.stories.tsx +10 -6
  320. package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateMessage/index.spec.tsx +121 -0
  321. package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateMessage/index.tsx +98 -0
  322. package/js/widgets/Dashboard/components/DashboardItem/Order/_styles.scss +43 -0
  323. package/js/widgets/Dashboard/components/DashboardItem/_styles.scss +34 -37
  324. package/js/widgets/Dashboard/components/DashboardItem/index.spec.tsx +74 -4
  325. package/js/widgets/Dashboard/components/DashboardItem/index.stories.tsx +18 -0
  326. package/js/widgets/Dashboard/components/DashboardItem/index.tsx +91 -26
  327. package/js/widgets/Dashboard/components/DashboardItem/stories.mock.ts +4 -8
  328. package/js/widgets/Dashboard/components/DashboardLayout/_styles.scss +14 -5
  329. package/js/widgets/Dashboard/components/DashboardLayout/index.tsx +10 -3
  330. package/js/widgets/Dashboard/components/DashboardListAvatar/_styles.scss +8 -0
  331. package/js/widgets/Dashboard/components/DashboardListAvatar/index.tsx +11 -0
  332. package/js/widgets/Dashboard/components/DashboardOrderLoader/_styles.scss +5 -0
  333. package/js/widgets/Dashboard/components/DashboardOrderLoader/index.tsx +50 -14
  334. package/js/widgets/Dashboard/components/DashboardSidebar/_styles.scss +37 -24
  335. package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.spec.tsx +244 -0
  336. package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.tsx +49 -0
  337. package/js/widgets/Dashboard/components/DashboardSidebar/components/MenuNavLink/index.spec.tsx +40 -0
  338. package/js/widgets/Dashboard/components/DashboardSidebar/components/MenuNavLink/index.tsx +28 -0
  339. package/js/widgets/Dashboard/components/DashboardSidebar/components/NavigationSelect.tsx +58 -0
  340. package/js/widgets/Dashboard/components/DashboardSidebar/index.stories.tsx +11 -1
  341. package/js/widgets/Dashboard/components/DashboardSidebar/index.tsx +18 -69
  342. package/js/widgets/Dashboard/components/DashboardSidebar/utils.ts +6 -0
  343. package/js/widgets/Dashboard/components/FilterOrganization/index.tsx +58 -0
  344. package/js/widgets/Dashboard/components/FiltersBar/index.tsx +9 -0
  345. package/js/widgets/Dashboard/components/LearnerDashboardSidebar/index.tsx +4 -2
  346. package/js/widgets/Dashboard/components/NavigateWithParams/index.spec.tsx +31 -40
  347. package/js/widgets/Dashboard/components/RouterButton/index.tsx +2 -1
  348. package/js/widgets/Dashboard/components/Signature/DummyContractPlaceholder.tsx +25 -0
  349. package/js/widgets/Dashboard/components/Signature/SignatureDummy.tsx +58 -0
  350. package/js/widgets/Dashboard/components/Signature/SignatureLexPersona.tsx +72 -0
  351. package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/index.spec.tsx +215 -0
  352. package/js/widgets/Dashboard/components/{TeacherCourseDashboardSidebar → TeacherDashboardCourseSidebar}/index.tsx +75 -31
  353. package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/utils.ts +23 -0
  354. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.spec.tsx +154 -0
  355. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.stories.tsx +42 -0
  356. package/js/widgets/Dashboard/components/{TeacherOrganizationDashboardSidebar → TeacherDashboardOrganizationSidebar}/index.tsx +40 -29
  357. package/js/widgets/Dashboard/components/{TeacherProfileDashboardSidebar → TeacherDashboardProfileSidebar}/components/OrganizationLinks/_styles.scss +27 -10
  358. package/js/widgets/Dashboard/components/TeacherDashboardProfileSidebar/components/OrganizationLinks/index.spec.tsx +49 -0
  359. package/js/widgets/Dashboard/components/{TeacherProfileDashboardSidebar → TeacherDashboardProfileSidebar}/components/OrganizationLinks/index.tsx +18 -7
  360. package/js/widgets/Dashboard/components/{TeacherProfileDashboardSidebar → TeacherDashboardProfileSidebar}/index.spec.tsx +13 -39
  361. package/js/widgets/Dashboard/components/{TeacherProfileDashboardSidebar → TeacherDashboardProfileSidebar}/index.stories.tsx +5 -5
  362. package/js/widgets/Dashboard/components/{TeacherProfileDashboardSidebar → TeacherDashboardProfileSidebar}/index.tsx +4 -3
  363. package/js/widgets/Dashboard/hooks/useEnroll/index.ts +8 -8
  364. package/js/widgets/Dashboard/index.spec.tsx +22 -12
  365. package/js/widgets/Dashboard/utils/learnerRouteMessages.tsx +12 -1
  366. package/js/widgets/Dashboard/utils/learnerRoutes.tsx +6 -0
  367. package/js/widgets/Dashboard/utils/teacherRouteMessages.tsx +60 -4
  368. package/js/widgets/Dashboard/utils/teacherRoutes.tsx +87 -13
  369. package/js/widgets/LtiConsumer/index.spec.tsx +44 -33
  370. package/js/widgets/LtiConsumer/index.tsx +11 -15
  371. package/js/widgets/Search/components/SearchFilterGroup/index.spec.tsx +0 -5
  372. package/js/widgets/Search/components/SearchFilterGroupModal/_styles.scss +0 -9
  373. package/js/widgets/Search/components/SearchFilterGroupModal/index.spec.tsx +0 -5
  374. package/js/widgets/Search/components/SearchFilterGroupModal/index.tsx +86 -60
  375. package/js/widgets/Search/components/SearchFilterValueParent/index.stories.tsx +51 -0
  376. package/js/widgets/Search/components/SearchFilterValueParent/index.tsx +7 -7
  377. package/js/widgets/Search/components/SearchFiltersPane/_styles.scss +2 -16
  378. package/js/widgets/Search/components/SearchFiltersPane/index.tsx +9 -6
  379. package/js/widgets/Search/hooks/useCourseSearch/index.ts +13 -7
  380. package/js/widgets/Search/index.spec.tsx +3 -2
  381. package/js/widgets/Search/utils/getResourceList/index.spec.ts +12 -5
  382. package/js/widgets/Search/utils/getResourceList/index.ts +6 -2
  383. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/CourseProductItemFooter/index.tsx +74 -0
  384. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/_styles.scss +11 -14
  385. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCertificateItem/_styles.scss +1 -1
  386. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCertificateItem/index.spec.tsx +13 -2
  387. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCertificateItem/index.stories.tsx +33 -0
  388. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCertificateItem/index.tsx +5 -8
  389. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCourseRuns/CourseRunList.tsx +1 -1
  390. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCourseRuns/EnrollableCourseRunList.tsx +16 -8
  391. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCourseRuns/EnrolledCourseRun.tsx +5 -3
  392. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCourseRuns/_styles.scss +1 -0
  393. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCourseRuns/index.spec.tsx +100 -35
  394. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseRunItem/index.spec.tsx +7 -4
  395. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.stories.tsx +36 -0
  396. package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseRunItem/index.tsx +5 -3
  397. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/ProductSignatureHeader/index.tsx +40 -0
  398. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +898 -0
  399. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +83 -0
  400. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.tsx +253 -0
  401. package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/CourseRunUnenrollmentButton/index.tsx +3 -2
  402. package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/_styles.scss +0 -25
  403. package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.joanie.spec.tsx +73 -30
  404. package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.openedx.spec.tsx +10 -5
  405. package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.tsx +54 -26
  406. package/js/widgets/SyllabusCourseRunsList/components/CourseRunItemWithEnrollment/index.tsx +1 -0
  407. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/_styles.scss +0 -3
  408. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/hooks/useCourseWish/index.spec.tsx +12 -9
  409. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.login.spec.tsx +14 -12
  410. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.logout.spec.tsx +4 -6
  411. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.tsx +5 -5
  412. package/js/widgets/SyllabusCourseRunsList/components/SyllabusAsideList/index.tsx +2 -2
  413. package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRun/index.tsx +19 -13
  414. package/js/widgets/SyllabusCourseRunsList/components/SyllabusSimpleCourseRunsList/index.tsx +1 -0
  415. package/js/widgets/SyllabusCourseRunsList/hooks/useCourseEnrollment/index.spec.tsx +2 -1
  416. package/js/widgets/SyllabusCourseRunsList/hooks/useCourseEnrollment/index.ts +14 -19
  417. package/js/widgets/SyllabusCourseRunsList/index.spec.tsx +54 -14
  418. package/js/widgets/SyllabusCourseRunsList/index.tsx +5 -8
  419. package/js/widgets/UserLogin/components/UserMenu/DesktopUserMenu.tsx +2 -1
  420. package/js/widgets/UserLogin/components/UserMenu/MobileUserMenu.tsx +2 -1
  421. package/js/widgets/UserLogin/components/UserMenu/index.tsx +6 -5
  422. package/js/widgets/UserLogin/index.not.isJoanieEnabled.spec.tsx +120 -0
  423. package/js/widgets/UserLogin/index.spec.tsx +108 -43
  424. package/js/widgets/UserLogin/index.stories.tsx +29 -0
  425. package/js/widgets/UserLogin/index.tsx +33 -15
  426. package/js/widgets/index.tsx +3 -6
  427. package/mocks/browser.ts +1 -1
  428. package/mocks/handlers/contracts.ts +16 -0
  429. package/mocks/handlers.ts +3 -1
  430. package/package.json +82 -78
  431. package/scss/_main.scss +2 -0
  432. package/scss/colors/_palette.scss +2 -2
  433. package/scss/colors/_theme.scss +6 -16
  434. package/scss/components/_content.scss +1 -1
  435. package/scss/components/_index.scss +24 -14
  436. package/scss/generic/_type.scss +1 -1
  437. package/scss/objects/_characteristics.scss +7 -14
  438. package/scss/objects/_course_glimpses.scss +3 -7
  439. package/scss/objects/_dashboard.scss +28 -0
  440. package/scss/objects/_form.scss +14 -355
  441. package/scss/objects/_index.scss +1 -0
  442. package/scss/objects/_list.scss +8 -0
  443. package/scss/objects/_organization_glimpses.scss +2 -8
  444. package/scss/objects/_selector.scss +1 -0
  445. package/scss/trumps/_bootstrap.scss +4 -0
  446. package/scss/vendors/css/cunningham-tokens.css +89 -25
  447. package/scss/vendors/cunningham-tokens.scss +208 -128
  448. package/js/components/AddressesManagement/AddressForm.spec.tsx +0 -206
  449. package/js/components/AddressesManagement/AddressForm.tsx +0 -169
  450. package/js/components/Button/index.spec.tsx +0 -36
  451. package/js/components/Button/index.stories.tsx +0 -26
  452. package/js/components/Button/index.tsx +0 -38
  453. package/js/components/Form/CheckboxField.stories.tsx +0 -12
  454. package/js/components/Form/Field.stories.config.tsx +0 -24
  455. package/js/components/Form/Inputs.tsx +0 -295
  456. package/js/components/Form/RadioField.stories.tsx +0 -18
  457. package/js/components/Form/SelectField.stories.tsx +0 -27
  458. package/js/components/Form/TextAreaField.stories.tsx +0 -12
  459. package/js/components/Form/TextField.stories.tsx +0 -12
  460. package/js/components/Form/index.spec.tsx +0 -297
  461. package/js/hooks/useProduct.ts +0 -28
  462. package/js/utils/test/mockProductWithOrder.ts +0 -17
  463. package/js/widgets/CourseProductItem/components/PaymentButton/_styles.scss +0 -12
  464. package/js/widgets/CourseProductItem/components/PaymentButton/index.spec.tsx +0 -473
  465. package/js/widgets/CourseProductItem/components/PurchaseButton/index.spec.tsx +0 -259
  466. package/js/widgets/CourseProductItem/components/SaleTunnel/_styles.scss +0 -41
  467. package/js/widgets/CourseProductItem/components/SaleTunnelStepResume/_styles.scss +0 -130
  468. package/js/widgets/CourseProductItem/components/SaleTunnelStepResume/index.spec.tsx +0 -29
  469. package/js/widgets/CourseProductItem/components/SaleTunnelStepResume/index.tsx +0 -59
  470. package/js/widgets/CourseProductItem/components/SaleTunnelStepValidation/index.spec.tsx +0 -71
  471. package/js/widgets/CourseProductItem/contexts/CourseProductContext/index.spec.tsx +0 -35
  472. package/js/widgets/CourseProductItem/contexts/CourseProductContext/index.tsx +0 -45
  473. package/js/widgets/CourseProductItem/index.spec.tsx +0 -486
  474. package/js/widgets/CourseProductItem/index.tsx +0 -205
  475. package/js/widgets/Dashboard/components/DashboardItem/DashboardItemCourseEnrolling.spec.tsx +0 -64
  476. package/js/widgets/Dashboard/components/TeacherCourseDashboardSidebar/index.spec.tsx +0 -105
  477. package/js/widgets/Dashboard/components/TeacherOrganizationDashboardSidebar/index.stories.tsx +0 -28
  478. /package/js/components/AddressesManagement/{validationSchema.spec.ts → AddressForm/validationSchema.spec.ts} +0 -0
  479. /package/js/{widgets/CourseProductItem/components → components}/EnrollmentDate/index.tsx +0 -0
  480. /package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/RegisteredCreditCard/_styles.scss +0 -0
  481. /package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/RegisteredCreditCard/index.spec.tsx +0 -0
  482. /package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/SaleTunnelStepValidation/TargetCourseDetail.tsx +0 -0
  483. /package/js/{widgets/CourseProductItem → components/SaleTunnel}/components/StepBreadcrumb/_styles.scss +0 -0
  484. /package/js/{widgets/CourseProductItem/hooks → hooks}/useStepManager/index.spec.ts +0 -0
  485. /package/js/{widgets/CourseProductItem/hooks → hooks}/useStepManager/index.ts +0 -0
  486. /package/js/pages/{TeacherCourseDashboardLoader → TeacherDashboardCourseLoader}/CourseRunList/CourseRunListCell/index.tsx +0 -0
  487. /package/js/pages/{TeacherCourseDashboardLoader → TeacherDashboardCourseLoader}/CourseRunList/index.tsx +0 -0
  488. /package/js/pages/{TeacherTrainingDashboard → TeacherDashboardTraining}/_styles.scss +0 -0
  489. /package/js/widgets/Dashboard/components/{TeacherCourseDashboardSidebar → TeacherDashboardCourseSidebar}/_styles.scss +0 -0
  490. /package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCourseRuns/CourseRunSection.tsx +0 -0
  491. /package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/components/CourseProductCourseRuns/index.tsx +0 -0
  492. /package/js/widgets/{CourseProductItem → SyllabusCourseRunsList/components/CourseProductItem}/types/payments/payplug.d.ts +0 -0
@@ -1,14 +1,15 @@
1
- import type { CourseState } from 'types';
2
- import type { Nullable } from 'types/utils';
1
+ import type { CourseState, OpenEdXEnrollment } from 'types';
2
+ import type { Maybe, Nullable } from 'types/utils';
3
3
  import { Resource, ResourcesQuery } from 'hooks/useResources';
4
4
  import { OrderResourcesQuery } from 'hooks/useOrders';
5
5
  import { Course as RichieCourse } from 'types/Course';
6
+ import { JoanieUserProfile } from './User';
6
7
 
7
8
  // - Generic
8
9
  export interface PaginatedResponse<T> {
9
10
  count: number;
10
11
  next: string | null;
11
- prev: string | null;
12
+ previous: string | null;
12
13
  results: Array<T>;
13
14
  }
14
15
 
@@ -21,30 +22,40 @@ export interface Organization {
21
22
  id: string;
22
23
  code: string;
23
24
  title: string;
24
- logo: {
25
- filename: string;
26
- src: string;
27
- srcset: string[];
28
- height: number;
29
- width: number;
30
- size: number;
31
- };
25
+ logo: Nullable<JoanieFile>;
26
+ }
27
+
28
+ export interface ContractDefinition {
29
+ id: string;
30
+ description: string;
31
+ language: string;
32
+ title: string;
33
+ }
34
+
35
+ type ContractAbilities = {
36
+ sign: boolean;
37
+ };
38
+
39
+ export interface Contract {
40
+ id: string;
41
+ abilities?: ContractAbilities;
42
+ created_on: string;
43
+ student_signed_on: Nullable<string>;
44
+ organization_signed_on: Nullable<string>;
45
+ organization_signatory: Nullable<JoanieUserProfile>;
46
+ definition: ContractDefinition;
47
+ order: NestedCertificateOrder | NestedCredentialOrder;
32
48
  }
33
49
 
34
50
  export interface CourseListItem extends Resource {
35
51
  id: string;
36
52
  title: string;
37
53
  code: string;
38
- course_runs: CourseRun[];
54
+ course_run_ids: string[];
39
55
  organizations: Organization[];
40
56
  selling_organizations: Organization[];
41
- cover: Nullable<{
42
- filename: string;
43
- url: string;
44
- height: number;
45
- width: number;
46
- }>;
47
- products: Product[];
57
+ cover: Nullable<JoanieFile>;
58
+ product_ids: string[];
48
59
  state: CourseState;
49
60
  created_on: string;
50
61
  }
@@ -59,7 +70,7 @@ export interface CourseRun {
59
70
  start: string;
60
71
  state: CourseState;
61
72
  title: string;
62
- course?: CourseLight;
73
+ course: CourseLight;
63
74
  languages: string[];
64
75
  }
65
76
 
@@ -74,7 +85,7 @@ export interface Certificate {
74
85
  id: string;
75
86
  issued_on: string;
76
87
  certificate_definition: CertificateDefinition;
77
- order: Order;
88
+ order: NestedCertificateOrder | NestedCredentialOrder;
78
89
  }
79
90
 
80
91
  // - Organization
@@ -87,7 +98,6 @@ export interface OrganizationLight {
87
98
  export enum ProductType {
88
99
  CERTIFICATE = 'certificate',
89
100
  CREDENTIAL = 'credential',
90
- ENROLLMENT = 'enrollment',
91
101
  }
92
102
 
93
103
  export interface Product {
@@ -101,20 +111,36 @@ export interface Product {
101
111
  certificate_definition: CertificateDefinition;
102
112
  target_courses: TargetCourse[];
103
113
  created_on: string;
104
- orders: Order['id'][];
105
114
  remaining_order_count?: number | null;
115
+ state: CourseState;
116
+ instructions: Nullable<string>;
117
+ contract_definition?: ContractDefinition;
118
+ }
119
+
120
+ export interface CredentialProduct extends Product {
121
+ type: ProductType.CREDENTIAL;
122
+ }
123
+
124
+ export interface CertificateProduct extends Product {
125
+ type: ProductType.CERTIFICATE;
106
126
  }
127
+ export const isCertificateProduct = (
128
+ entity: Product | CertificateProduct | CredentialProduct,
129
+ ): entity is CertificateProduct => {
130
+ return entity.type === ProductType.CERTIFICATE;
131
+ };
107
132
 
108
133
  export interface CourseProduct extends Product {
109
134
  order: Nullable<OrderLite>;
110
- target_courses: TargetCourse[];
111
135
  }
112
136
 
113
137
  export interface CourseProductRelation {
114
138
  id: string;
115
- course: CourseListItem;
139
+ course: CourseLight;
140
+ organizations: Organization[];
116
141
  product: Product;
117
142
  created_on: string;
143
+ order_groups: OrderGroup[];
118
144
  }
119
145
  export function isCourseProductRelation(
120
146
  entity: CourseListItem | CourseProductRelation | RichieCourse,
@@ -122,6 +148,15 @@ export function isCourseProductRelation(
122
148
  return 'course' in entity && 'product' in entity;
123
149
  }
124
150
 
151
+ export interface JoanieFile {
152
+ filename: string;
153
+ height: number;
154
+ size: number;
155
+ src: string;
156
+ srcset: string;
157
+ width: number;
158
+ }
159
+
125
160
  // - Course
126
161
  export interface AbstractCourse {
127
162
  id: string;
@@ -129,40 +164,17 @@ export interface AbstractCourse {
129
164
  organizations: OrganizationLight[];
130
165
  title: string;
131
166
  course_runs: CourseRun[];
132
- cover?: JoanieFile;
133
167
  }
134
168
 
135
- export interface JoanieFile {
136
- filename: string;
137
- height: number;
138
- size: number;
139
- src: string;
140
- srcset: string;
141
- width: number;
142
- }
169
+ export type CourseLight = Pick<AbstractCourse, 'id' | 'code' | 'title'> & {
170
+ cover: Nullable<JoanieFile>;
171
+ };
143
172
 
144
173
  export interface TargetCourse extends AbstractCourse {
145
174
  is_graded: boolean;
146
175
  position: number;
147
176
  }
148
177
 
149
- export type OrderLite = Pick<
150
- Order,
151
- | 'id'
152
- | 'created_on'
153
- | 'state'
154
- | 'total'
155
- | 'enrollments'
156
- | 'product'
157
- | 'main_proforma_invoice'
158
- | 'certificate'
159
- >;
160
-
161
- export interface CourseLight extends AbstractCourse {
162
- products: CourseProduct[];
163
- orders?: OrderLite[];
164
- }
165
-
166
178
  // Enrollment
167
179
  export enum EnrollmentState {
168
180
  FAILED = 'failed',
@@ -176,29 +188,124 @@ export interface Enrollment {
176
188
  course_run: CourseRun;
177
189
  was_created_by_order: boolean;
178
190
  created_on: string;
191
+ orders: OrderEnrollment[];
192
+ product_relations: CourseProductRelation[];
193
+ certificate_id: Nullable<string>;
194
+ }
195
+ export const isEnrollment = (obj: unknown | Enrollment | OpenEdXEnrollment): obj is Enrollment => {
196
+ if (!obj || typeof obj !== 'object') {
197
+ return false;
198
+ }
199
+ return (
200
+ 'is_active' in obj &&
201
+ 'state' in obj &&
202
+ 'course_run' in obj &&
203
+ 'was_created_by_order' in obj &&
204
+ 'created_on' in obj &&
205
+ 'orders' in obj &&
206
+ 'product_relations' in obj &&
207
+ 'certificate_id' in obj
208
+ );
209
+ };
210
+
211
+ export interface EnrollmentLight {
212
+ id: string;
213
+ is_active: boolean;
214
+ state: EnrollmentState;
215
+ course_run: CourseRun;
216
+ was_created_by_order: boolean;
217
+ created_on: string;
179
218
  }
180
219
 
181
220
  // Order
182
221
  export enum OrderState {
222
+ DRAFT = 'draft',
223
+ SUBMITTED = 'submitted',
183
224
  CANCELED = 'canceled',
184
- FAILED = 'failed',
185
225
  PENDING = 'pending',
186
226
  VALIDATED = 'validated',
187
227
  }
188
228
 
229
+ export const ACTIVE_ORDER_STATES = [OrderState.PENDING, OrderState.VALIDATED, OrderState.SUBMITTED];
230
+
189
231
  export interface Order {
190
232
  id: string;
191
- course?: CourseLight['code'] | CourseLight;
192
233
  created_on: string;
193
- enrollments: Enrollment[];
194
- main_proforma_invoice: string;
195
- certificate?: string;
234
+ target_enrollments: Enrollment[];
235
+ main_invoice_reference: string;
236
+ certificate_id?: Certificate['id'];
237
+ contract?: Contract;
196
238
  owner: string;
197
239
  total: number;
198
240
  total_currency: string;
199
241
  state: OrderState;
200
- product: Product['id'];
242
+ product_id: Product['id'];
201
243
  target_courses: TargetCourse[];
244
+ course: Maybe<CourseLight>;
245
+ enrollment: Maybe<EnrollmentLight>;
246
+ organization_id: Organization['id'];
247
+ order_group_id?: OrderGroup['id'];
248
+ }
249
+
250
+ export interface CredentialOrder extends Order {
251
+ course: CourseLight;
252
+ enrollment: undefined;
253
+ }
254
+
255
+ export interface CredentialOrderWithPaymentInfo extends CredentialOrder {
256
+ payment_info: Payment | PaymentOneClick;
257
+ }
258
+
259
+ export interface CertificateOrder extends Order {
260
+ course: undefined;
261
+ enrollment: EnrollmentLight;
262
+ target_courses: [];
263
+ }
264
+
265
+ export interface CertificateOrderWithPaymentInfo extends CertificateOrder {
266
+ payment_info: Payment | PaymentOneClick;
267
+ }
268
+
269
+ export type OrderLite = Pick<
270
+ Order,
271
+ | 'id'
272
+ | 'created_on'
273
+ | 'state'
274
+ | 'total'
275
+ | 'target_enrollments'
276
+ | 'product_id'
277
+ | 'main_invoice_reference'
278
+ | 'certificate_id'
279
+ >;
280
+
281
+ export interface AbstractNestedOrder {
282
+ id: string;
283
+ organization: Organization;
284
+ product_title: string;
285
+ owner_name: string;
286
+ }
287
+ export interface NestedCertificateOrder extends AbstractNestedOrder {
288
+ course: undefined;
289
+ enrollment: EnrollmentLight;
290
+ }
291
+ export const isNestedCredentialOrder = (
292
+ obj: NestedCertificateOrder | NestedCredentialOrder,
293
+ ): obj is NestedCredentialOrder => {
294
+ return !obj.enrollment && !!obj.course;
295
+ };
296
+
297
+ export interface NestedCredentialOrder extends AbstractNestedOrder {
298
+ course: CourseLight;
299
+ enrollment: undefined;
300
+ }
301
+
302
+ export type OrderEnrollment = Pick<Order, 'id' | 'state' | 'product_id' | 'certificate_id'>;
303
+
304
+ export interface OrderGroup {
305
+ id: string;
306
+ is_active: boolean;
307
+ nb_seats: number;
308
+ nb_available_seats: number;
202
309
  }
203
310
 
204
311
  export enum CreditCardBrand {
@@ -249,7 +356,7 @@ export enum PaymentProviders {
249
356
 
250
357
  export interface Payment {
251
358
  payment_id: string;
252
- provider: string;
359
+ provider_name: string;
253
360
  url: string;
254
361
  }
255
362
 
@@ -257,7 +364,7 @@ export interface PaymentOneClick extends Payment {
257
364
  is_paid: boolean;
258
365
  }
259
366
 
260
- export interface OrderWithPaymentInfo extends Order {
367
+ export interface OrderPaymentInfo {
261
368
  payment_info: Payment | PaymentOneClick;
262
369
  }
263
370
 
@@ -266,29 +373,44 @@ export interface AddressCreationPayload extends Omit<Address, 'id' | 'is_main'>
266
373
  is_main?: boolean;
267
374
  }
268
375
 
269
- interface OrderCreationPayload {
270
- product: Product['id'];
271
- course: CourseLight['code'];
272
- billing_address?: Omit<Address, 'id' | 'is_main'>;
273
- credit_card_id?: CreditCard['id'];
376
+ interface AbstractOrderProductCreationPayload {
377
+ product_id: Product['id'];
378
+ order_group_id?: OrderGroup['id'];
379
+ has_consent_to_terms: boolean;
274
380
  }
275
381
 
382
+ interface OrderCertificateCreationPayload extends AbstractOrderProductCreationPayload {
383
+ enrollment_id: Enrollment['id'];
384
+ }
385
+ export interface OrderCredentialCreationPayload extends AbstractOrderProductCreationPayload {
386
+ course_code: CourseLight['code'];
387
+ }
388
+
389
+ export type OrderCreationPayload = OrderCertificateCreationPayload | OrderCredentialCreationPayload;
390
+
276
391
  interface OrderAbortPayload {
277
392
  id: Order['id'];
278
393
  payment_id?: Payment['payment_id'];
279
394
  }
280
395
 
396
+ interface OrderSubmitPayload {
397
+ id: Order['id'];
398
+ billing_address: Omit<Address, 'id' | 'is_main'>;
399
+ credit_card_id?: CreditCard['id'];
400
+ }
401
+
281
402
  export interface PaginatedResourceQuery extends ResourcesQuery {
282
403
  page?: number;
283
404
  page_size?: number;
284
405
  }
285
406
 
286
407
  export interface EnrollmentsQuery extends PaginatedResourceQuery {
408
+ course_run_id?: CourseRun['id'];
287
409
  was_created_by_order?: boolean;
288
410
  }
289
411
 
290
412
  interface EnrollmentCreationPayload {
291
- course_run: CourseRun['id'];
413
+ course_run_id: CourseRun['id'];
292
414
  is_active: boolean;
293
415
  order?: Order['id'];
294
416
  was_created_by_order: boolean;
@@ -303,10 +425,44 @@ export interface CourseRunFilters extends ResourcesQuery {
303
425
  }
304
426
 
305
427
  export interface CourseQueryFilters extends ResourcesQuery {
428
+ id?: CourseListItem['id'];
429
+ organization_id?: Organization['id'];
430
+ has_listed_course_runs?: Boolean;
431
+ }
432
+ export interface CourseProductQueryFilters extends ResourcesQuery {
433
+ id?: Product['id'];
434
+ course_id?: CourseListItem['id'];
435
+ }
436
+ export interface CourseProductRelationQueryFilters extends PaginatedResourceQuery {
437
+ id?: CourseProductRelation['id'];
306
438
  organization_id?: Organization['id'];
439
+ product_type?: ProductType;
440
+ }
441
+
442
+ export enum ContractState {
443
+ UNSIGNED = 'unsigned',
444
+ LEARNER_SIGNED = 'half_signed',
445
+ SIGNED = 'signed',
307
446
  }
308
- export interface CourseProductRelationQueryFilters extends ResourcesQuery {
447
+ export interface ContractResourceQuery extends PaginatedResourceQuery {
309
448
  organization_id?: Organization['id'];
449
+ course_product_relation_id?: CourseProductRelation['id'];
450
+ contract_ids?: Contract['id'][];
451
+ signature_state?: ContractState;
452
+ }
453
+
454
+ export interface OrganizationContractSignatureLinksFilters {
455
+ contracts_ids?: string[];
456
+ organization_id: Organization['id'];
457
+ course_product_relation_ids?: CourseProductRelation['id'][];
458
+ }
459
+
460
+ export interface ContractInvitationLinkResponse {
461
+ invitation_link: string;
462
+ }
463
+
464
+ export interface OrganizationContractInvitationLinkResponse extends ContractInvitationLinkResponse {
465
+ contract_ids: Contract['id'][];
310
466
  }
311
467
 
312
468
  export interface ApiResourceInterface<
@@ -320,6 +476,9 @@ export interface ApiResourceInterface<
320
476
  }
321
477
 
322
478
  interface APIUser {
479
+ me: {
480
+ get(): Promise<JoanieUserProfile>;
481
+ };
323
482
  addresses: {
324
483
  create(payload: AddressCreationPayload): Promise<Address>;
325
484
  delete(id: Address['id']): Promise<void>;
@@ -336,15 +495,17 @@ interface APIUser {
336
495
  };
337
496
  orders: {
338
497
  abort(payload: OrderAbortPayload): Promise<void>;
339
- create(payload: OrderCreationPayload): Promise<OrderWithPaymentInfo>;
498
+ create(payload: OrderCreationPayload): Promise<CredentialOrder | CertificateOrder>;
340
499
  get<Filters extends OrderResourcesQuery = OrderResourcesQuery>(
341
500
  filters?: Filters,
342
501
  ): Filters extends { id: string }
343
- ? Promise<Nullable<Order>>
344
- : Promise<PaginatedResponse<Order>>;
502
+ ? Promise<Nullable<CredentialOrder | CertificateOrder>>
503
+ : Promise<PaginatedResponse<CredentialOrder | CertificateOrder>>;
345
504
  invoice: {
346
505
  download(payload: { order_id: Order['id']; invoice_reference: string }): Promise<File>;
347
506
  };
507
+ submit(payload: OrderSubmitPayload): Promise<OrderPaymentInfo>;
508
+ submit_for_signature(id: string): Promise<ContractInvitationLinkResponse>;
348
509
  };
349
510
  certificates: {
350
511
  download(id: string): Promise<File>;
@@ -370,28 +531,47 @@ interface APIUser {
370
531
  create(id: string): Promise<CourseWish>;
371
532
  delete(id: string): Promise<void>;
372
533
  };
373
- organizations: {
374
- get<Filters extends ResourcesQuery = ResourcesQuery>(
375
- filters?: Filters,
376
- ): Filters extends { id: string } ? Promise<Nullable<Organization>> : Promise<Organization[]>;
534
+ contracts: {
535
+ get(
536
+ filters?: ContractResourceQuery,
537
+ ): ContractResourceQuery extends { id: string }
538
+ ? Promise<Nullable<Contract>>
539
+ : Promise<PaginatedResponse<Contract>>;
540
+ download(id: string): Promise<File>;
541
+ zip_archive: {
542
+ check: (id: string) => Promise<Response>;
543
+ create: ({ organization_id }: { organization_id: string }) => Promise<{ url: string }>;
544
+ get: (id: string) => Promise<File>;
545
+ };
377
546
  };
378
547
  }
379
548
 
380
549
  export interface API {
381
550
  user: APIUser;
382
- products: {
383
- get<Filters extends ResourcesQuery = ResourcesQuery>(
384
- filters?: Filters,
385
- ): Filters extends { id: string }
386
- ? Promise<Nullable<Product>>
387
- : Promise<PaginatedResponse<Product>>;
388
- };
389
551
  courses: {
390
552
  get<Filters extends PaginatedResourceQuery = PaginatedResourceQuery>(
391
553
  filters?: Filters,
392
554
  ): Filters extends { id: string }
393
555
  ? Promise<Nullable<CourseListItem>>
394
556
  : Promise<PaginatedResponse<CourseListItem>>;
557
+ products: {
558
+ get(filters?: CourseProductQueryFilters): Promise<Nullable<CourseProductRelation>>;
559
+ };
560
+ };
561
+ organizations: {
562
+ get<Filters extends ResourcesQuery = ResourcesQuery>(
563
+ filters?: Filters,
564
+ ): Filters extends { id: string } ? Promise<Nullable<Organization>> : Promise<Organization[]>;
565
+ contracts: {
566
+ get(
567
+ filters?: ContractResourceQuery,
568
+ ): ContractResourceQuery extends { id: string }
569
+ ? Promise<Nullable<Contract>>
570
+ : Promise<PaginatedResponse<Contract>>;
571
+ getSignatureLinks(
572
+ filters?: OrganizationContractSignatureLinksFilters,
573
+ ): Promise<OrganizationContractInvitationLinkResponse>;
574
+ };
395
575
  };
396
576
  courseRuns: {
397
577
  get(
@@ -405,6 +585,9 @@ export interface API {
405
585
  ? Promise<Nullable<CourseProductRelation>>
406
586
  : Promise<PaginatedResponse<CourseProductRelation>>;
407
587
  };
588
+ contractDefinitions: {
589
+ previewTemplate(id: string): Promise<File>;
590
+ };
408
591
  }
409
592
 
410
593
  export interface Backend {
@@ -39,8 +39,8 @@ export function isCourseSuggestion(suggestion: Suggestion<string>): suggestion i
39
39
  export type Suggestion<Kind extends string> = Kind extends 'default'
40
40
  ? DefaultSuggestion
41
41
  : Kind extends 'courses'
42
- ? CourseSuggestion
43
- : GenericSuggestion;
42
+ ? CourseSuggestion
43
+ : GenericSuggestion;
44
44
 
45
45
  /**
46
46
  * The base shape of a resource suggestion section. Contains a bunch of suggestions and a title.
package/js/types/User.ts CHANGED
@@ -1,6 +1,24 @@
1
1
  export interface User {
2
2
  access_token?: string;
3
- fullname?: string;
3
+ full_name?: string;
4
4
  email?: string;
5
5
  username: string;
6
6
  }
7
+
8
+ export enum JoanieUserApiAbilityActions {
9
+ DELETE = 'delete',
10
+ GET = 'get',
11
+ PATCH = 'patch',
12
+ PUT = 'put',
13
+ HAS_COURSE_ACCESS = 'has_course_access',
14
+ HAS_ORGANIZATION_ACCESS = 'has_organization_access',
15
+ }
16
+
17
+ export interface JoanieUserProfile {
18
+ id: string;
19
+ username: string;
20
+ full_name: string;
21
+ is_superuser: boolean;
22
+ is_staff: boolean;
23
+ abilities: { [key in JoanieUserApiAbilityActions]?: boolean };
24
+ }
@@ -31,6 +31,9 @@ export interface RichieContext {
31
31
  release: string;
32
32
  sentry_dsn: Nullable<string>;
33
33
  web_analytics_providers?: Nullable<string[]>;
34
+ site_urls: {
35
+ terms_and_conditions: Nullable<string>;
36
+ };
34
37
  }
35
38
 
36
39
  export interface CommonDataProps {
package/js/types/index.ts CHANGED
@@ -25,7 +25,6 @@ export interface CourseRun {
25
25
  enrollment_end: string;
26
26
  languages: string[];
27
27
  state: CourseState;
28
- starts_in_message: Nullable<string>;
29
28
  dashboard_link: Nullable<string>;
30
29
  title?: string;
31
30
  snapshot?: string;
@@ -70,4 +69,5 @@ export interface OpenEdXEnrollment {
70
69
  * Use an unknown type to make sure we do not depend on any LMS-specific fields
71
70
  * on enrollment objects, just use HTTP response codes.
72
71
  */
72
+ // TODO(rlecellier): rename into UnknownEnrollment
73
73
  export type Enrollment = unknown;
@@ -0,0 +1,35 @@
1
+ import { faker } from '@faker-js/faker';
2
+ import { ContractFactory } from 'utils/test/factories/joanie';
3
+ import { ContractActions } from 'utils/AbilitiesHelper/types';
4
+ import AbilitiesHelper from '.';
5
+
6
+ describe('Abilities.contractAbilities', () => {
7
+ it('should allow or not user to sign contract according to contract abilities', () => {
8
+ const contract = ContractFactory({
9
+ abilities: {
10
+ sign: faker.datatype.boolean(),
11
+ },
12
+ }).one();
13
+
14
+ expect(AbilitiesHelper.can(contract, ContractActions.SIGN)).toBe(contract.abilities?.sign);
15
+ expect(AbilitiesHelper.cannot(contract, ContractActions.SIGN)).toBe(!contract.abilities?.sign);
16
+ });
17
+
18
+ it('should allow or not user to sign contracts list according to contract abilities', () => {
19
+ const signableContracts = ContractFactory({
20
+ abilities: { sign: true },
21
+ }).many(3);
22
+ const unsignableContract = ContractFactory({
23
+ abilities: { sign: false },
24
+ }).one();
25
+
26
+ // We should be able to pass an array of contracts and process ability according to all
27
+ // contracts abilities provided
28
+ expect(AbilitiesHelper.can(signableContracts, ContractActions.SIGN)).toBe(true);
29
+
30
+ // If at least one contract is not allowed, user not be able to sign
31
+ expect(
32
+ AbilitiesHelper.can([...signableContracts, unsignableContract], ContractActions.SIGN),
33
+ ).toBe(false);
34
+ });
35
+ });
@@ -0,0 +1,14 @@
1
+ import { Contract } from 'types/Joanie';
2
+ import { ContractActions } from './types';
3
+
4
+ type ContractAbilityList = {
5
+ [action in ContractActions]: (entities: Contract) => boolean;
6
+ };
7
+
8
+ const abilities: ContractAbilityList = {
9
+ [ContractActions.SIGN]: (contract: Contract) => {
10
+ return contract?.abilities?.sign === true;
11
+ },
12
+ };
13
+
14
+ export default abilities;