richie-education 3.3.2-dev19 → 3.3.2-dev25

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 (117) hide show
  1. package/.eslintrc.json +0 -3
  2. package/.storybook/preview.tsx +1 -1
  3. package/cunningham.cjs +1 -0
  4. package/i18n/compile-translations.js +12 -10
  5. package/jest.config.js +5 -0
  6. package/js/components/AddressesManagement/AddressForm/index.stories.tsx +1 -1
  7. package/js/components/AddressesManagement/AddressForm/index.tsx +4 -3
  8. package/js/components/AddressesManagement/index.stories.tsx +1 -1
  9. package/js/components/AddressesManagement/index.tsx +5 -3
  10. package/js/components/Badge/index.stories.tsx +1 -1
  11. package/js/components/Badge/index.tsx +1 -1
  12. package/js/components/Banner/index.stories.tsx +1 -1
  13. package/js/components/CourseGlimpse/index.stories.tsx +1 -1
  14. package/js/components/CourseGlimpseList/index.stories.tsx +1 -1
  15. package/js/components/CreditCardSelector/index.tsx +11 -3
  16. package/js/components/DownloadCertificateButton/index.tsx +2 -1
  17. package/js/components/DownloadContractButton/index.tsx +7 -1
  18. package/js/components/Form/Form/index.tsx +4 -2
  19. package/js/components/Icon/index.stories.tsx +2 -1
  20. package/js/components/Modal/index.stories.tsx +1 -1
  21. package/js/components/Modal/index.tsx +2 -1
  22. package/js/components/OpenEdxFullNameForm/index.stories.tsx +1 -1
  23. package/js/components/OpenEdxFullNameForm/index.tsx +2 -2
  24. package/js/components/PurchaseButton/index.stories.tsx +1 -1
  25. package/js/components/RegisteredAddress/index.stories.tsx +1 -1
  26. package/js/components/RegisteredAddress/index.tsx +4 -2
  27. package/js/components/SaleTunnel/AddressSelector/CreateAddressFormModal.tsx +1 -1
  28. package/js/components/SaleTunnel/AddressSelector/EditAddressFormModal.tsx +1 -1
  29. package/js/components/SaleTunnel/AddressSelector/index.tsx +4 -2
  30. package/js/components/SaleTunnel/SaleTunnelInformation/SaleTunnelInformationGroup.tsx +4 -3
  31. package/js/components/SaleTunnel/SaleTunnelInformation/SaleTunnelInformationSingular.tsx +8 -2
  32. package/js/components/SaleTunnel/index.stories.tsx +1 -1
  33. package/js/components/Spinner/index.stories.tsx +1 -1
  34. package/js/components/Tabs/index.stories.tsx +1 -1
  35. package/js/components/Tabs/index.tsx +2 -1
  36. package/js/components/TeacherDashboardCourseList/index.tsx +2 -1
  37. package/js/hooks/useAddressesManagement.tsx +4 -2
  38. package/js/hooks/useCreditCards/index.ts +6 -4
  39. package/js/hooks/useDashboardAddressForm.tsx +3 -3
  40. package/js/hooks/useMatchMedia.ts +1 -1
  41. package/js/hooks/useResources/useResourcesRoot.ts +1 -1
  42. package/js/hooks/useUnionResource/index.ts +6 -2
  43. package/js/hooks/useUnionResource/utils/fetchEntity.ts +1 -0
  44. package/js/pages/DashboardAddressesManagement/DashboardAddressBox.tsx +3 -3
  45. package/js/pages/DashboardAddressesManagement/DashboardCreateAddress.stories.tsx +1 -1
  46. package/js/pages/DashboardAddressesManagement/DashboardCreateAddress.tsx +1 -1
  47. package/js/pages/DashboardAddressesManagement/DashboardEditAddress.stories.tsx +1 -1
  48. package/js/pages/DashboardAddressesManagement/DashboardEditAddress.tsx +3 -2
  49. package/js/pages/DashboardAddressesManagement/index.stories.tsx +1 -1
  50. package/js/pages/DashboardAddressesManagement/index.tsx +1 -1
  51. package/js/pages/DashboardCourses/index.tsx +2 -1
  52. package/js/pages/DashboardCreditCardsManagement/CreditCardBrandLogo.stories.tsx +1 -1
  53. package/js/pages/DashboardCreditCardsManagement/DashboardCreditCardBox.tsx +3 -3
  54. package/js/pages/DashboardCreditCardsManagement/DashboardEditCreditCard.stories.tsx +1 -1
  55. package/js/pages/DashboardCreditCardsManagement/DashboardEditCreditCard.tsx +3 -2
  56. package/js/pages/DashboardCreditCardsManagement/index.stories.tsx +1 -1
  57. package/js/pages/DashboardOpenEdxProfile/index.stories.tsx +1 -1
  58. package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.tsx +4 -2
  59. package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.tsx +2 -1
  60. package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.spec.tsx +4 -4
  61. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.spec.tsx +8 -9
  62. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.tsx +14 -3
  63. package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.tsx +6 -1
  64. package/js/pages/TeacherDashboardCourseLoader/CourseRunList/utils.tsx +2 -1
  65. package/js/pages/TeacherDashboardOrganizationAgreements/BulkAgreementContractButton.tsx +4 -2
  66. package/js/pages/TeacherDashboardOrganizationAgreements/SignOrganizationAgreementButton.tsx +2 -1
  67. package/js/pages/TeacherDashboardOrganizationQuotes/index.tsx +2 -1
  68. package/js/utils/ProductHelper/index.spec.ts +1 -1
  69. package/js/utils/cunningham-tokens.ts +1111 -142
  70. package/js/utils/errors/handle.spec.ts +3 -3
  71. package/js/utils/react-query/useSessionMutation/index.ts +8 -3
  72. package/js/widgets/Dashboard/components/DashboardAvatar/index.stories.tsx +1 -1
  73. package/js/widgets/Dashboard/components/DashboardBox/index.stories.tsx +13 -5
  74. package/js/widgets/Dashboard/components/DashboardBreadcrumbs/index.stories.tsx +1 -1
  75. package/js/widgets/Dashboard/components/DashboardBreadcrumbs/index.tsx +3 -2
  76. package/js/widgets/Dashboard/components/DashboardCard/index.spec.tsx +13 -2
  77. package/js/widgets/Dashboard/components/DashboardCard/index.stories.tsx +12 -4
  78. package/js/widgets/Dashboard/components/DashboardCard/index.tsx +1 -1
  79. package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/BatchOrderPaymentModal/BatchOrderPaymentManager.tsx +1 -1
  80. package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/BatchOrderPaymentModal/index.tsx +2 -1
  81. package/js/widgets/Dashboard/components/DashboardItem/Certificate/index.stories.tsx +1 -1
  82. package/js/widgets/Dashboard/components/DashboardItem/Contract/index.stories.tsx +1 -1
  83. package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.stories.tsx +1 -1
  84. package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.tsx +8 -4
  85. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.stories.tsx +1 -1
  86. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.tsx +1 -1
  87. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderReadonly.stories.tsx +1 -1
  88. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderWritable.stories.tsx +1 -1
  89. package/js/widgets/Dashboard/components/DashboardItem/Order/Installment/index.tsx +1 -1
  90. package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentRetryModal/index.tsx +2 -1
  91. package/js/widgets/Dashboard/components/DashboardItem/Order/OrganizationBlock/index.tsx +6 -3
  92. package/js/widgets/Dashboard/components/DashboardItem/index.stories.tsx +1 -1
  93. package/js/widgets/Dashboard/components/DashboardItem/index.tsx +2 -1
  94. package/js/widgets/Dashboard/components/DashboardListAvatar/index.stories.tsx +1 -1
  95. package/js/widgets/Dashboard/components/DashboardSidebar/index.stories.tsx +1 -1
  96. package/js/widgets/Dashboard/components/LearnerDashboardSidebar/index.stories.tsx +1 -1
  97. package/js/widgets/Dashboard/components/ProtectedOutlet/AuthenticatedOutlet.spec.tsx +1 -1
  98. package/js/widgets/Dashboard/components/ProtectedOutlet/ProtectedOutlet.spec.tsx +1 -1
  99. package/js/widgets/Dashboard/components/SearchBar/index.tsx +2 -1
  100. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.stories.tsx +1 -1
  101. package/js/widgets/Dashboard/components/TeacherDashboardProfileSidebar/index.stories.tsx +1 -1
  102. package/js/widgets/Dashboard/index.spec.tsx +1 -1
  103. package/js/widgets/Search/components/SearchFilterValueParent/index.stories.tsx +1 -1
  104. package/js/widgets/Search/components/SearchFiltersPane/index.tsx +2 -1
  105. package/js/widgets/Slider/index.stories.tsx +1 -1
  106. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCertificateItem/index.stories.tsx +1 -1
  107. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.stories.tsx +1 -1
  108. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +1 -1
  109. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.tsx +4 -2
  110. package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRun/index.stories.tsx +1 -1
  111. package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRunCompacted/index.stories.tsx +1 -1
  112. package/js/widgets/UserLogin/index.stories.tsx +1 -1
  113. package/package.json +75 -75
  114. package/scss/vendors/css/cunningham-tokens.css +1259 -154
  115. package/scss/vendors/cunningham-tokens.scss +1479 -150
  116. package/tsconfig.json +1 -1
  117. package/webpack.config.js +6 -0
package/.eslintrc.json CHANGED
@@ -39,9 +39,6 @@
39
39
  "arrow-parens": "error",
40
40
  "consistent-return": "off",
41
41
  "default-case": "off",
42
- "formatjs/no-multiple-whitespaces": "error",
43
- "formatjs/enforce-description": "error",
44
- "formatjs/enforce-default-message": "error",
45
42
  "global-require": "off",
46
43
  "import/extensions": "off",
47
44
  "import/no-cycle": ["off"],
@@ -1,7 +1,7 @@
1
1
  import { useState } from 'react';
2
2
  import { IntlProvider } from 'react-intl';
3
3
  import { CunninghamProvider } from '@openfun/cunningham-react';
4
- import { Preview } from '@storybook/react';
4
+ import { Preview } from '@storybook/react-webpack5';
5
5
  import { useAsyncEffect } from 'hooks/useAsyncEffect';
6
6
  import frMessages from 'translations/fr-FR.json';
7
7
  import './__mocks__/utils/context';
package/cunningham.cjs CHANGED
@@ -63,6 +63,7 @@ module.exports = {
63
63
  midnightblue: '#141b2c',
64
64
  mantis: '#76ce68',
65
65
  'mantis-darken': '#006908',
66
+ 'warning-500': '#937303',
66
67
  },
67
68
  },
68
69
  components: {
@@ -1,41 +1,43 @@
1
1
  #! /usr/bin/env node
2
2
  const path = require('path');
3
3
  const fs = require('fs');
4
- const yargs = require('yargs');
4
+ const yargs = require('yargs/yargs');
5
+ const { hideBin } = require('yargs/helpers');
5
6
  const { glob } = require('glob');
6
7
  const { merge } = require('cljs-merge');
7
8
 
8
9
  /**
9
10
  * compile-translations
10
- *
11
+ *
11
12
  * formatjs/cli compile and compile-folder methods do not allow merge.
12
13
  * So we need your own compile method.
13
- *
14
+ *
14
15
  * Without specify option, this script compile all translations files includes
15
16
  * in i18n/locales into js/translations
16
- *
17
+ *
17
18
  * You can provide a search pattern to include other translation sources. If several files have the
18
19
  * same name, they will be merged.
19
- *
20
+ *
20
21
  * Usage: ./compile-translations.js [search_patterns] [--ignore] [--outDir <path_to_output_files]
21
- *
22
- *
22
+ *
23
+ *
23
24
  * ARGUMENTS:
24
25
  * search_pattern list of patterns to search additional translation files (support only json)
25
26
  * --ignore a pattern to ignore a path where search files (e.g ./node_modules)
26
27
  * --outDir output directory
27
- *
28
+ *
28
29
  */
29
30
 
31
+ const { argv } = yargs(hideBin(process.argv));
30
32
 
31
33
  // Transparently includes Richie default translation files to lighten command
32
34
  const LOCALES_PATTERN = path.resolve(__dirname, `./locales/*.json`);
33
35
  // Output directory
34
- const OUT_DIR = yargs.argv.outDir || path.resolve(__dirname, `../js/translations`);
36
+ const OUT_DIR = argv.outDir || path.resolve(__dirname, `../js/translations`);
35
37
 
36
38
 
37
39
  (async () => {
38
- const { ignore, _: patterns } = yargs.argv
40
+ const { ignore, _: patterns } = argv
39
41
  const filesPattern = [
40
42
  LOCALES_PATTERN,
41
43
  ...patterns.map((filepath) => path.resolve(process.cwd(), filepath))
package/jest.config.js CHANGED
@@ -17,6 +17,10 @@ module.exports = {
17
17
  transformIgnorePatterns: [
18
18
  'node_modules/(?!(' +
19
19
  'react-intl' +
20
+ '|@formatjs' +
21
+ '|intl-messageformat' +
22
+ '|@tanstack' +
23
+ '|uuid' +
20
24
  '|lodash-es' +
21
25
  '|@hookform/resolvers' +
22
26
  '|query-string' +
@@ -25,6 +29,7 @@ module.exports = {
25
29
  '|filter-obj' +
26
30
  '|@openfun/cunningham-react' +
27
31
  '|keycloak-js' +
32
+ '|@faker-js/faker' +
28
33
  ')/)',
29
34
  ],
30
35
  globals: {
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { StorybookHelper } from 'utils/StorybookHelper';
3
3
  import { AddressFactory } from 'utils/test/factories/joanie';
4
4
  import AddressForm from '.';
@@ -1,6 +1,6 @@
1
1
  import { yupResolver } from '@hookform/resolvers/yup';
2
2
  import { Fragment, useEffect } from 'react';
3
- import { FormProvider, useForm } from 'react-hook-form';
3
+ import { FormProvider, Resolver, useForm } from 'react-hook-form';
4
4
  import { FormattedMessage, useIntl } from 'react-intl';
5
5
  import { Button, Checkbox } from '@openfun/cunningham-react';
6
6
  import { getLocalizedCunninghamErrorProp } from 'components/Form/utils';
@@ -39,7 +39,7 @@ const AddressForm = ({ handleReset, onSubmit, address }: Props) => {
39
39
  defaultValues: address || defaultValues,
40
40
  mode: 'onBlur',
41
41
  reValidateMode: 'onChange',
42
- resolver: yupResolver(validationSchema),
42
+ resolver: yupResolver(validationSchema) as Resolver<AddressFormValues>,
43
43
  });
44
44
  const { register, handleSubmit, reset, formState } = form;
45
45
 
@@ -140,7 +140,8 @@ const AddressForm = ({ handleReset, onSubmit, address }: Props) => {
140
140
  {address ? (
141
141
  <Fragment>
142
142
  <Button
143
- color="tertiary"
143
+ color="brand"
144
+ variant="tertiary"
144
145
  onClick={handleCancel}
145
146
  title={intl.formatMessage(messages.cancelTitleButton)}
146
147
  >
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { StorybookHelper } from 'utils/StorybookHelper';
3
3
  import { RichieContextFactory } from 'utils/test/factories/richie';
4
4
  import AddressesManagement from '.';
@@ -1,4 +1,4 @@
1
- import { Children, useEffect, useState, RefAttributes } from 'react';
1
+ import { Children, useEffect, useState, Ref } from 'react';
2
2
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
3
3
  import { Button } from '@openfun/cunningham-react';
4
4
  import AddressForm, { type AddressFormValues } from 'components/AddressesManagement/AddressForm';
@@ -105,9 +105,10 @@ export const messages = defineMessages({
105
105
  },
106
106
  });
107
107
 
108
- interface AddressesManagementProps extends RefAttributes<HTMLDivElement> {
108
+ interface AddressesManagementProps {
109
109
  handleClose: () => void;
110
110
  selectAddress: (address: Joanie.Address) => void;
111
+ ref?: Ref<HTMLDivElement>;
111
112
  }
112
113
 
113
114
  const AddressesManagement = ({ handleClose, selectAddress, ref }: AddressesManagementProps) => {
@@ -191,7 +192,8 @@ const AddressesManagement = ({ handleClose, selectAddress, ref }: AddressesManag
191
192
  <div className="AddressesManagement" ref={ref}>
192
193
  <Button
193
194
  className="AddressesManagement__closeButton"
194
- color="tertiary"
195
+ color="brand"
196
+ variant="tertiary"
195
197
  size="small"
196
198
  onClick={handleClose}
197
199
  >
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import Badge from '.';
3
3
 
4
4
  export default {
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import { PropsWithChildren } from 'react/ts5.0';
2
+ import { PropsWithChildren } from 'react';
3
3
 
4
4
  type BadgeProps = PropsWithChildren<{
5
5
  color?: 'primary' | 'secondary' | 'tertiary';
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import Banner, { BannerType } from './index';
3
3
 
4
4
  export default {
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { CourseLightFactory, RichieContextFactory } from 'utils/test/factories/richie';
3
3
  import { CourseGlimpse, getCourseGlimpseProps } from 'components/CourseGlimpse';
4
4
  import { CourseCertificateOffer, CourseOffer } from 'types/Course';
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { RichieContextFactory, CourseLightFactory } from 'utils/test/factories/richie';
3
3
  import { CourseGlimpseList, getCourseGlimpseListProps } from '.';
4
4
 
@@ -111,7 +111,8 @@ export const CreditCardSelector = ({
111
111
  {allowEdit && creditCards?.length > 0 && (
112
112
  <Button
113
113
  icon={<span className="material-icons">edit</span>}
114
- color="tertiary-text"
114
+ color="brand"
115
+ variant="tertiary"
115
116
  size="medium"
116
117
  onClick={modal.open}
117
118
  aria-label={intl.formatMessage(messages.editCreditCardAriaLabel)}
@@ -122,7 +123,8 @@ export const CreditCardSelector = ({
122
123
  <Button
123
124
  onClick={() => setCreditCard(undefined)}
124
125
  size="small"
125
- color="secondary"
126
+ color="brand"
127
+ variant="secondary"
126
128
  className="mt-t"
127
129
  fullWidth={isMobile}
128
130
  >
@@ -217,7 +219,13 @@ const CreditCardSelectorModal = ({
217
219
  size={ModalSize.MEDIUM}
218
220
  title={intl.formatMessage(messages.modalTitle)}
219
221
  actions={
220
- <Button color="primary" size="small" fullWidth={true} onClick={() => onChange(selected)}>
222
+ <Button
223
+ color="brand"
224
+ variant="primary"
225
+ size="small"
226
+ fullWidth={true}
227
+ onClick={() => onChange(selected)}
228
+ >
221
229
  <FormattedMessage {...messages.modalTitle} />
222
230
  </Button>
223
231
  }
@@ -38,7 +38,8 @@ const DownloadCertificateButton = ({
38
38
  <Button
39
39
  className={className}
40
40
  size="small"
41
- color="secondary"
41
+ color="brand"
42
+ variant="secondary"
42
43
  disabled={loading}
43
44
  onClick={onDownloadClick}
44
45
  >
@@ -39,7 +39,13 @@ const DownloadContractButton = ({ contract, className }: DownloadContractButtonP
39
39
  };
40
40
 
41
41
  return (
42
- <Button size="small" className={className} color="secondary" onClick={downloadContract}>
42
+ <Button
43
+ size="small"
44
+ className={className}
45
+ color="brand"
46
+ variant="secondary"
47
+ onClick={downloadContract}
48
+ >
43
49
  <FormattedMessage {...messages.contractDownloadActionLabel} />
44
50
  </Button>
45
51
  );
@@ -1,8 +1,10 @@
1
1
  import c from 'classnames';
2
2
  import { PropsWithChildren } from 'react';
3
3
 
4
- interface FormProps
5
- extends React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement> {}
4
+ interface FormProps extends React.DetailedHTMLProps<
5
+ React.FormHTMLAttributes<HTMLFormElement>,
6
+ HTMLFormElement
7
+ > {}
6
8
 
7
9
  const Form = ({ children, onSubmit, className, name, noValidate = true }: FormProps) => {
8
10
  return (
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { PropsWithChildren, useState, useRef, CSSProperties } from 'react';
3
3
  import { HttpStatusCode } from 'utils/errors/HttpError';
4
4
  import { Icon, IconTypeEnum } from './index';
@@ -69,6 +69,7 @@ const IconContainer = ({ name, enumKey }: IconContainerProps) => {
69
69
  };
70
70
 
71
71
  const clipboardCopy = () => {
72
+ // eslint-disable-next-line compat/compat
72
73
  navigator.clipboard.writeText(`${ENUM_NAME}.${enumKey}`);
73
74
  setShowTooltip(true);
74
75
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { useState } from 'react';
3
3
  import { Modal } from './index';
4
4
 
@@ -78,7 +78,8 @@ export const Modal = ({
78
78
  className="modal__closeButton"
79
79
  onClick={(e) => props.onRequestClose?.(e)}
80
80
  title={intl.formatMessage(messages.closeDialog)}
81
- color="tertiary"
81
+ color="brand"
82
+ variant="tertiary"
82
83
  size="small"
83
84
  >
84
85
  <Icon name={IconTypeEnum.ROUND_CLOSE} />
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { BaseJoanieAppWrapper } from 'utils/test/wrappers/BaseJoanieAppWrapper';
3
3
  import OpenEdxFullNameForm from '.';
4
4
 
@@ -1,6 +1,6 @@
1
1
  import { ButtonElement, Input, Alert, VariantType } from '@openfun/cunningham-react';
2
2
  import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
3
- import { FormProvider, useForm } from 'react-hook-form';
3
+ import { FormProvider, Resolver, useForm } from 'react-hook-form';
4
4
  import * as Yup from 'yup';
5
5
  import { yupResolver } from '@hookform/resolvers/yup';
6
6
  import { useEffect, useMemo, useRef } from 'react';
@@ -78,7 +78,7 @@ const OpenEdxFullNameForm = () => {
78
78
  defaultValues,
79
79
  mode: 'onBlur',
80
80
  reValidateMode: 'onChange',
81
- resolver: yupResolver(validationSchema),
81
+ resolver: yupResolver(validationSchema) as Resolver<OpenEdxFullNameFormValues>,
82
82
  });
83
83
 
84
84
  const { getValues, register, handleSubmit, reset, formState } = form;
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { ProductFactory } from 'utils/test/factories/joanie';
3
3
  import PurchaseButton from '.';
4
4
 
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { StorybookHelper } from 'utils/StorybookHelper';
3
3
  import { AddressFactory } from 'utils/test/factories/joanie';
4
4
  import RegisteredAddress from '.';
@@ -91,7 +91,8 @@ const RegisteredAddress = ({ promote, select, edit, remove, address }: Props) =>
91
91
  </Button>
92
92
  <Button
93
93
  aria-label={intl.formatMessage(messages.editButtonLabel, { title: address.title })}
94
- color="secondary"
94
+ color="brand"
95
+ variant="secondary"
95
96
  size="small"
96
97
  onClick={() => edit(address)}
97
98
  >
@@ -101,7 +102,8 @@ const RegisteredAddress = ({ promote, select, edit, remove, address }: Props) =>
101
102
  aria-label={intl.formatMessage(messages.deleteButtonLabel, {
102
103
  title: address.title,
103
104
  })}
104
- color="secondary"
105
+ color="brand"
106
+ variant="secondary"
105
107
  size="small"
106
108
  disabled={address.is_main}
107
109
  onClick={() => remove(address)}
@@ -52,7 +52,7 @@ export const CreateAddressFormModal = (props: AddressFormModalProps) => {
52
52
  size={ModalSize.MEDIUM}
53
53
  title={intl.formatMessage(messages.title)}
54
54
  actions={
55
- <Button color="primary" size="small" onClick={handleSubmit(onSubmit)}>
55
+ <Button color="brand" variant="primary" size="small" onClick={handleSubmit(onSubmit)}>
56
56
  <FormattedMessage {...messages.submit} />
57
57
  </Button>
58
58
  }
@@ -49,7 +49,7 @@ export const EditAddressFormModal = ({
49
49
  size={ModalSize.MEDIUM}
50
50
  title={intl.formatMessage(messages.title)}
51
51
  actions={
52
- <Button color="primary" size="small" onClick={handleSubmit(onSubmit)}>
52
+ <Button color="brand" variant="primary" size="small" onClick={handleSubmit(onSubmit)}>
53
53
  <FormattedMessage {...messages.save} />
54
54
  </Button>
55
55
  }
@@ -75,7 +75,8 @@ export const AddressSelector = () => {
75
75
  <Button
76
76
  size="small"
77
77
  icon={<span className="material-icons">edit</span>}
78
- color="tertiary"
78
+ color="brand"
79
+ variant="tertiary"
79
80
  onClick={editFormModal.open}
80
81
  fullWidth={isMobile}
81
82
  >
@@ -85,7 +86,8 @@ export const AddressSelector = () => {
85
86
  <Button
86
87
  size="small"
87
88
  icon={<span className="material-icons">add</span>}
88
- color="primary"
89
+ color="brand"
90
+ variant="primary"
89
91
  onClick={createFormModal.open}
90
92
  fullWidth={isMobile}
91
93
  >
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
2
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
3
- import { FormProvider, useForm } from 'react-hook-form';
3
+ import { FormProvider, Resolver, useForm } from 'react-hook-form';
4
4
  import { yupResolver } from '@hookform/resolvers/yup';
5
5
  import * as Yup from 'yup';
6
6
  import { Step, StepLabel, Stepper } from '@mui/material';
@@ -197,7 +197,7 @@ const BatchOrderForm = () => {
197
197
  const form = useForm<BatchOrder>({
198
198
  defaultValues: batchOrder || defaultValues,
199
199
  mode: 'onBlur',
200
- resolver: yupResolver(validationSchema),
200
+ resolver: yupResolver(validationSchema) as Resolver<BatchOrder>,
201
201
  });
202
202
  const { watch } = form;
203
203
  const values = watch();
@@ -268,7 +268,8 @@ const BatchOrderForm = () => {
268
268
  }
269
269
  }}
270
270
  hidden={activeStep === 0}
271
- color="tertiary"
271
+ color="brand"
272
+ variant="tertiary"
272
273
  >
273
274
  <FormattedMessage {...messages.previousButton} />
274
275
  </Button>
@@ -443,7 +443,13 @@ const Voucher = ({
443
443
  label={intl.formatMessage(messages.voucherTitle)}
444
444
  disabled={!!voucherCode}
445
445
  />
446
- <Button size="small" color="primary" onClick={submitVoucher} disabled={!!voucherCode}>
446
+ <Button
447
+ size="small"
448
+ color="brand"
449
+ variant="primary"
450
+ onClick={submitVoucher}
451
+ disabled={!!voucherCode}
452
+ >
447
453
  <FormattedMessage {...messages.voucherValidate} />
448
454
  </Button>
449
455
  </div>
@@ -500,7 +506,7 @@ const CpfPayment = ({ deepLink }: { deepLink: string }) => {
500
506
  <FormattedMessage {...messages.cpfDescription} />
501
507
  </p>
502
508
  <Button
503
- color="primary"
509
+ color="brand"
504
510
  fullWidth={true}
505
511
  href={deepLink}
506
512
  target="_blank"
@@ -1,4 +1,4 @@
1
- import { StoryObj, Meta } from '@storybook/react';
1
+ import { StoryObj, Meta } from '@storybook/react-webpack5';
2
2
  import { BaseJoanieAppWrapper } from 'utils/test/wrappers/BaseJoanieAppWrapper';
3
3
  import {
4
4
  CertificateProductFactory,
@@ -1,4 +1,4 @@
1
- import { StoryObj, Meta } from '@storybook/react';
1
+ import { StoryObj, Meta } from '@storybook/react-webpack5';
2
2
  import { Spinner } from './index';
3
3
 
4
4
  export default {
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { useState } from 'react';
3
3
  import { RouterWrapper } from 'utils/test/wrappers/RouterWrapper';
4
4
  import Tabs from './index';
@@ -45,7 +45,8 @@ const Tab = ({
45
45
  return (
46
46
  <div className="tabs__tab">
47
47
  <Button
48
- color="tertiary-text"
48
+ color="brand"
49
+ variant="tertiary"
49
50
  onClick={handleOnClick}
50
51
  className={classNames('c__button--tab', {
51
52
  'c__button--active': isActive,
@@ -91,7 +91,8 @@ const TeacherDashboardCourseList = ({
91
91
  onClick={() => loadMore()}
92
92
  disabled={isLoadingMore}
93
93
  ref={loadMoreButtonRef}
94
- color="tertiary"
94
+ color="brand"
95
+ variant="tertiary"
95
96
  >
96
97
  <FormattedMessage {...messages.loadMore} />
97
98
  </Button>
@@ -1,5 +1,4 @@
1
1
  import { defineMessages, useIntl } from 'react-intl';
2
- import { MutateOptions } from '@tanstack/react-query';
3
2
  import { useAddresses } from 'hooks/useAddresses';
4
3
  import * as Joanie from 'types/Joanie';
5
4
  import { confirm } from 'utils/indirection/window';
@@ -58,7 +57,10 @@ export function useAddressesManagement() {
58
57
  * @param {Joanie.Address} address
59
58
  * @param {AddressesMutateOptions} options
60
59
  */
61
- const remove = (address: Joanie.Address, options?: MutateOptions) => {
60
+ const remove = (
61
+ address: Joanie.Address,
62
+ options?: Parameters<typeof addresses.methods.delete>[1],
63
+ ) => {
62
64
  if (address.is_main) {
63
65
  addresses.methods.setError(intl.formatMessage(messages.errorCannotRemoveMain));
64
66
  return;
@@ -1,6 +1,5 @@
1
1
  import { defineMessages, useIntl } from 'react-intl';
2
2
  import { useMutation, useQueryClient } from '@tanstack/react-query';
3
- import { MutateOptions } from '@tanstack/query-core';
4
3
  import { API, CreditCard } from 'types/Joanie';
5
4
  import { useJoanieApi } from 'contexts/JoanieApiContext';
6
5
  import { useSessionMutation } from 'utils/react-query/useSessionMutation';
@@ -84,10 +83,13 @@ const useCreditCardResources =
84
83
  * If the error is a 409, it means the credit card is used to pay at least one order
85
84
  * and the user should be informed about that.
86
85
  */
87
- const deleteMutateAsync = async (creditCard: CreditCard, options?: MutateOptions) => {
86
+ const deleteMutateAsync = async (
87
+ creditCard: CreditCard,
88
+ options?: Parameters<typeof custom.methods.delete>[1],
89
+ ) => {
88
90
  return custom.methods.delete(creditCard.id, {
89
91
  ...options,
90
- onError: (error: HttpError, variables, context) => {
92
+ onError: (error: HttpError, variables, context, mutationContext) => {
91
93
  if (error.code === HttpStatusCode.CONFLICT) {
92
94
  custom.methods.setError(
93
95
  intl.formatMessage(messages.errorCannotDelete, {
@@ -97,7 +99,7 @@ const useCreditCardResources =
97
99
  } else {
98
100
  custom.methods.setError(intl.formatMessage(messages.errorDelete));
99
101
  }
100
- options?.onError?.(error, variables, context);
102
+ options?.onError?.(error, variables, context, mutationContext);
101
103
  },
102
104
  });
103
105
  };
@@ -1,5 +1,5 @@
1
- import { yupResolver } from '@hookform/resolvers/yup/dist/yup';
2
- import { FormProvider, useForm } from 'react-hook-form';
1
+ import { yupResolver } from '@hookform/resolvers/yup';
2
+ import { FormProvider, Resolver, useForm } from 'react-hook-form';
3
3
  import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
4
4
  import * as Yup from 'yup';
5
5
  import countries from 'i18n-iso-countries';
@@ -60,7 +60,7 @@ export const useDashboardAddressForm = (address?: Address) => {
60
60
  defaultValues: address || defaultValues,
61
61
  mode: 'onBlur',
62
62
  reValidateMode: 'onChange',
63
- resolver: yupResolver(validationSchema),
63
+ resolver: yupResolver(validationSchema) as Resolver<AddressFormValues>,
64
64
  });
65
65
  const { register, handleSubmit, formState } = form;
66
66
 
@@ -36,6 +36,6 @@ const useMatchMedia = (query: string): boolean => {
36
36
  };
37
37
 
38
38
  export const useMatchMediaLg = () =>
39
- useMatchMedia(`(max-width: ${tokens.themes.default.theme.breakpoints.lg})`);
39
+ useMatchMedia(`(max-width: ${tokens.themes.default.globals.breakpoints.lg})`);
40
40
 
41
41
  export default useMatchMedia;
@@ -1,7 +1,7 @@
1
1
  import { useMutation, useQuery, useQueryClient, UseQueryResult } from '@tanstack/react-query';
2
2
  import { useCallback, useMemo, useState } from 'react';
3
3
  import { defineMessages, useIntl } from 'react-intl';
4
- import { MutateOptions } from '@tanstack/query-core/src/types';
4
+ import { MutateOptions } from '@tanstack/query-core';
5
5
  import { AddParameters, Maybe } from 'types/utils';
6
6
  import { HttpError } from 'utils/errors/HttpError';
7
7
  import { useSessionQuery } from 'utils/react-query/useSessionQuery';
@@ -35,8 +35,12 @@ export interface ResourceUnionPaginationProps {
35
35
  perPage?: number;
36
36
  }
37
37
 
38
- interface UseUnionResourceProps<DataA, DataB, FiltersA, FiltersB>
39
- extends ResourceUnionPaginationProps {
38
+ interface UseUnionResourceProps<
39
+ DataA,
40
+ DataB,
41
+ FiltersA,
42
+ FiltersB,
43
+ > extends ResourceUnionPaginationProps {
40
44
  queryAConfig: QueryConfig<DataA, FiltersA>;
41
45
  queryBConfig: QueryConfig<DataB, FiltersB>;
42
46
  errorGetMessage?: MessageDescriptor;
@@ -53,6 +53,7 @@ export const fetchEntity = async <
53
53
  // Here we need to mimic the behavior of staleTime, which does not seems to be implemented when using `getQueryData`.
54
54
  if (
55
55
  state &&
56
+ state.status === 'success' &&
56
57
  state.dataUpdatedAt >= new Date().getTime() - REACT_QUERY_SETTINGS.staleTimes.sessionItems &&
57
58
  !state.isInvalidated
58
59
  ) {