richie-education 3.1.3-dev15 → 3.1.3-dev17

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 (73) hide show
  1. package/js/api/joanie.ts +8 -8
  2. package/js/components/ContractFrame/OrganizationContractFrame.spec.tsx +12 -11
  3. package/js/components/ContractFrame/OrganizationContractFrame.tsx +4 -4
  4. package/js/components/CourseGlimpse/utils.ts +28 -22
  5. package/js/components/CourseGlimpseList/utils.ts +2 -2
  6. package/js/components/PurchaseButton/index.tsx +3 -3
  7. package/js/components/SaleTunnel/GenericSaleTunnel.tsx +3 -3
  8. package/js/components/SaleTunnel/SaleTunnelInformation/index.tsx +2 -2
  9. package/js/components/SaleTunnel/index.full-process.spec.tsx +3 -3
  10. package/js/components/SaleTunnel/index.spec.tsx +5 -5
  11. package/js/components/SaleTunnel/index.tsx +2 -2
  12. package/js/components/TeacherDashboardCourseList/index.spec.tsx +3 -3
  13. package/js/components/TeacherDashboardCourseList/index.tsx +2 -2
  14. package/js/hooks/useContractArchive/index.ts +3 -3
  15. package/js/hooks/useCourseProductUnion/index.spec.tsx +16 -16
  16. package/js/hooks/useCourseProductUnion/index.ts +7 -7
  17. package/js/hooks/useCourseProducts.ts +4 -4
  18. package/js/hooks/useDefaultOrganizationId/index.tsx +4 -4
  19. package/js/hooks/useOffering/index.ts +32 -0
  20. package/js/hooks/useTeacherCoursesSearch/index.tsx +4 -4
  21. package/js/hooks/useTeacherPendingContractsCount/index.ts +4 -4
  22. package/js/pages/DashboardCourses/index.spec.tsx +17 -14
  23. package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardContracts/index.spec.tsx +11 -8
  24. package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardContracts/index.tsx +6 -3
  25. package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.spec.tsx +11 -11
  26. package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.timer.spec.tsx +10 -10
  27. package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.tsx +4 -4
  28. package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.spec.tsx +5 -5
  29. package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.tsx +8 -8
  30. package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.spec.tsx +6 -6
  31. package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.tsx +4 -4
  32. package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.spec.tsx +7 -7
  33. package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.tsx +5 -5
  34. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/contractArchiveLocalStorage.spec.ts +21 -21
  35. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/contractArchiveLocalStorage.ts +19 -13
  36. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.spec.tsx +11 -11
  37. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.tsx +6 -6
  38. package/js/pages/TeacherDashboardContractsLayout/hooks/useHasContractToDownload/index.tsx +6 -3
  39. package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractFilters/index.spec.tsx +16 -16
  40. package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractFilters/index.tsx +4 -4
  41. package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractsToSign.tsx +7 -4
  42. package/js/pages/TeacherDashboardCourseLearnersLayout/hooks/useCourseLearnersFilters/index.spec.tsx +21 -21
  43. package/js/pages/TeacherDashboardCourseLearnersLayout/hooks/useCourseLearnersFilters/index.ts +5 -5
  44. package/js/pages/TeacherDashboardCourseLearnersLayout/index.spec.tsx +55 -55
  45. package/js/pages/TeacherDashboardCourseLearnersLayout/index.tsx +1 -1
  46. package/js/pages/TeacherDashboardCoursesLoader/index.spec.tsx +11 -11
  47. package/js/pages/TeacherDashboardOrganizationCourseLoader/index.spec.tsx +11 -11
  48. package/js/pages/TeacherDashboardTraining/TeacherDashboardTrainingLoader.tsx +7 -7
  49. package/js/pages/TeacherDashboardTraining/index.spec.tsx +25 -25
  50. package/js/pages/TeacherDashboardTraining/index.tsx +16 -12
  51. package/js/types/Joanie.ts +21 -19
  52. package/js/utils/test/factories/joanie.ts +3 -3
  53. package/js/utils/test/mockCourseProductWithOrder.ts +4 -4
  54. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.tsx +1 -1
  55. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +1 -1
  56. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +3 -3
  57. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.useUnionResource.cache.spec.tsx +1 -1
  58. package/js/widgets/Dashboard/components/DashboardItem/Order/Installment/index.tsx +4 -4
  59. package/js/widgets/Dashboard/components/DashboardItem/stories.mock.ts +1 -1
  60. package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.spec.tsx +23 -23
  61. package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.tsx +4 -4
  62. package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/index.spec.tsx +20 -17
  63. package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/index.tsx +22 -16
  64. package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/utils.ts +4 -4
  65. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.tsx +3 -3
  66. package/js/widgets/Dashboard/utils/teacherDashboardPaths.tsx +4 -4
  67. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/CourseProductItemFooter/index.tsx +14 -10
  68. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +87 -63
  69. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +2 -2
  70. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.tsx +24 -20
  71. package/js/widgets/SyllabusCourseRunsList/index.spec.tsx +8 -8
  72. package/package.json +1 -1
  73. package/js/hooks/useOffer/index.ts +0 -32
@@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event';
4
4
  import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
5
5
  import {
6
6
  CourseListItemFactory,
7
- OfferFactory,
7
+ OfferingFactory,
8
8
  OrganizationFactory,
9
9
  } from 'utils/test/factories/joanie';
10
10
  import { expectNoSpinner } from 'utils/test/expectSpinner';
@@ -59,8 +59,8 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
59
59
  mockPaginatedResponse(CourseListItemFactory().many(15), 15, false),
60
60
  );
61
61
  fetchMock.get(
62
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offers/?product_type=credential&page=1&page_size=${perPage}`,
63
- mockPaginatedResponse(OfferFactory().many(15), 15, false),
62
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?product_type=credential&page=1&page_size=${perPage}`,
63
+ mockPaginatedResponse(OfferingFactory().many(15), 15, false),
64
64
  );
65
65
  fetchMock.get(
66
66
  `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/contracts/?signature_state=half_signed&page=1`,
@@ -76,7 +76,7 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
76
76
  await expectNoSpinner('Loading courses...');
77
77
 
78
78
  nbApiCalls += 1; // course api call
79
- nbApiCalls += 1; // offers api call
79
+ nbApiCalls += 1; // offerings api call
80
80
  nbApiCalls += 1; // contracts api call
81
81
  const calledUrls = fetchMock.calls().map((call) => call[0]);
82
82
  expect(calledUrls).toHaveLength(nbApiCalls);
@@ -84,7 +84,7 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
84
84
  `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/courses/?has_listed_course_runs=true&page=1&page_size=${perPage}`,
85
85
  );
86
86
  expect(calledUrls).toContain(
87
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offers/?product_type=credential&page=1&page_size=${perPage}`,
87
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?product_type=credential&page=1&page_size=${perPage}`,
88
88
  );
89
89
  await expectNoSpinner('Loading organization...');
90
90
 
@@ -117,8 +117,8 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
117
117
  mockPaginatedResponse(CourseListItemFactory().many(15), 15, false),
118
118
  );
119
119
  fetchMock.get(
120
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offers/?product_type=credential&page=1&page_size=${perPage}`,
121
- mockPaginatedResponse(OfferFactory().many(15), 15, false),
120
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?product_type=credential&page=1&page_size=${perPage}`,
121
+ mockPaginatedResponse(OfferingFactory().many(15), 15, false),
122
122
  );
123
123
 
124
124
  render(<TeacherDashboardOrganizationCourseLoader />, {
@@ -136,22 +136,22 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
136
136
  mockPaginatedResponse(CourseListItemFactory().many(5), 5, false),
137
137
  );
138
138
  fetchMock.get(
139
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offers/?query=text+query&product_type=credential&page=1&page_size=${perPage}`,
140
- mockPaginatedResponse(OfferFactory().many(5), 5, false),
139
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?query=text+query&product_type=credential&page=1&page_size=${perPage}`,
140
+ mockPaginatedResponse(OfferingFactory().many(5), 5, false),
141
141
  );
142
142
  const user = userEvent.setup();
143
143
  await user.type(screen.getByRole('textbox', { name: /Search/ }), 'text query');
144
144
  await user.click(screen.getByRole('button', { name: /Search/ }));
145
145
 
146
146
  nbApiCalls = 1; // course api call
147
- nbApiCalls += 1; // offers api call
147
+ nbApiCalls += 1; // offerings api call
148
148
  const calledUrls = fetchMock.calls().map((call) => call[0]);
149
149
  expect(calledUrls).toHaveLength(nbApiCalls);
150
150
  expect(calledUrls).toContain(
151
151
  `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/courses/?query=text+query&has_listed_course_runs=true&page=1&page_size=${perPage}`,
152
152
  );
153
153
  expect(calledUrls).toContain(
154
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offers/?query=text+query&product_type=credential&page=1&page_size=${perPage}`,
154
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?query=text+query&product_type=credential&page=1&page_size=${perPage}`,
155
155
  );
156
156
 
157
157
  await waitFor(() => {
@@ -1,7 +1,7 @@
1
1
  import { FormattedMessage, defineMessages } from 'react-intl';
2
2
  import { useParams } from 'react-router';
3
3
 
4
- import { useOffer } from 'hooks/useOffer';
4
+ import { useOffering } from 'hooks/useOffering';
5
5
  import { DashboardLayout } from 'widgets/Dashboard/components/DashboardLayout';
6
6
  import { TeacherDashboardCourseSidebar } from 'widgets/Dashboard/components/TeacherDashboardCourseSidebar';
7
7
  import { Spinner } from 'components/Spinner';
@@ -22,17 +22,17 @@ const messages = defineMessages({
22
22
  });
23
23
 
24
24
  export const TeacherDashboardTrainingLoader = () => {
25
- const { offerId, organizationId } = useParams<{
26
- offerId: string;
25
+ const { offeringId, organizationId } = useParams<{
26
+ offeringId: string;
27
27
  organizationId?: string;
28
28
  }>();
29
29
 
30
30
  const {
31
- item: offer,
31
+ item: offering,
32
32
  states: { fetching },
33
- } = useOffer(offerId, { organization_id: organizationId });
33
+ } = useOffering(offeringId, { organization_id: organizationId });
34
34
  useBreadcrumbsPlaceholders({
35
- courseTitle: offer?.product.title ?? '',
35
+ courseTitle: offering?.product.title ?? '',
36
36
  });
37
37
  return (
38
38
  <DashboardLayout sidebar={<TeacherDashboardCourseSidebar />}>
@@ -48,7 +48,7 @@ export const TeacherDashboardTrainingLoader = () => {
48
48
  </span>
49
49
  </Spinner>
50
50
  ) : (
51
- <TeacherDashboardTraining offer={offer} />
51
+ <TeacherDashboardTraining offering={offering} />
52
52
  )}
53
53
  </DashboardLayout>
54
54
  );
@@ -11,7 +11,7 @@ import {
11
11
  UserFactory,
12
12
  } from 'utils/test/factories/richie';
13
13
  import JoanieSessionProvider from 'contexts/SessionContext/JoanieSessionProvider';
14
- import { OfferFactory, OrganizationFactory } from 'utils/test/factories/joanie';
14
+ import { OfferingFactory, OrganizationFactory } from 'utils/test/factories/joanie';
15
15
  import { createTestQueryClient } from 'utils/test/createTestQueryClient';
16
16
  import { expectNoSpinner } from 'utils/test/expectSpinner';
17
17
  import { DashboardBreadcrumbsProvider } from 'widgets/Dashboard/contexts/DashboardBreadcrumbsContext';
@@ -46,9 +46,9 @@ describe('components/TeacherDashboardTrainingLoader', () => {
46
46
  });
47
47
 
48
48
  it('should render TeacherDashboardTrainingLoader page', async () => {
49
- const offer = OfferFactory().one();
50
- fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/?offer_id=${offer.id}`, []);
51
- fetchMock.get(`https://joanie.endpoint/api/v1.0/offers/${offer.id}/`, offer);
49
+ const offering = OfferingFactory().one();
50
+ fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/?offering_id=${offering.id}`, []);
51
+ fetchMock.get(`https://joanie.endpoint/api/v1.0/offerings/${offering.id}/`, offering);
52
52
 
53
53
  const user = UserFactory().one();
54
54
  render(
@@ -61,12 +61,12 @@ describe('components/TeacherDashboardTrainingLoader', () => {
61
61
  router={createMemoryRouter(
62
62
  [
63
63
  {
64
- path: ':offerId',
64
+ path: ':offeringId',
65
65
  element: <TeacherDashboardTrainingLoader />,
66
66
  },
67
67
  ],
68
68
  {
69
- initialEntries: [`/${offer.id}`],
69
+ initialEntries: [`/${offering.id}`],
70
70
  },
71
71
  )}
72
72
  />
@@ -82,10 +82,10 @@ describe('components/TeacherDashboardTrainingLoader', () => {
82
82
  await expectNoSpinner('Loading course...');
83
83
 
84
84
  nbApiCalls += 1; // organizations api call
85
- nbApiCalls += 1; // offers api call
85
+ nbApiCalls += 1; // offerings api call
86
86
  const calledUrls = fetchMock.calls().map((call) => call[0]);
87
87
  expect(calledUrls).toHaveLength(nbApiCalls);
88
- expect(calledUrls).toContain(`https://joanie.endpoint/api/v1.0/offers/${offer.id}/`);
88
+ expect(calledUrls).toContain(`https://joanie.endpoint/api/v1.0/offerings/${offering.id}/`);
89
89
 
90
90
  // main titles
91
91
  expect(
@@ -94,28 +94,28 @@ describe('components/TeacherDashboardTrainingLoader', () => {
94
94
  }),
95
95
  ).toBeInTheDocument();
96
96
 
97
- expect(screen.getAllByRole('heading', { name: capitalize(offer.product.title) })).toHaveLength(
98
- 2,
99
- );
97
+ expect(
98
+ screen.getAllByRole('heading', { name: capitalize(offering.product.title) }),
99
+ ).toHaveLength(2);
100
100
 
101
- const nbCourseRun = offer.product.target_courses.reduce(
101
+ const nbCourseRun = offering.product.target_courses.reduce(
102
102
  (acc, course) => acc + course.course_runs.length,
103
103
  0,
104
104
  );
105
105
  expect(screen.getAllByRole('link', { name: 'Go to course area' })).toHaveLength(nbCourseRun);
106
106
  });
107
107
 
108
- it('should fetch offer with organization id if there is one in the path', async () => {
108
+ it('should fetch offering with organization id if there is one in the path', async () => {
109
109
  const organization = OrganizationFactory().one();
110
- const offer = OfferFactory({
110
+ const offering = OfferingFactory({
111
111
  organizations: [organization],
112
112
  }).one();
113
113
  fetchMock.get(
114
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offers/${offer.id}/`,
115
- offer,
114
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/${offering.id}/`,
115
+ offering,
116
116
  );
117
117
  fetchMock.get(
118
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/contracts/?offer_id=${offer.id}&signature_state=half_signed&page=1&page_size=25`,
118
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/contracts/?offering_id=${offering.id}&signature_state=half_signed&page=1&page_size=25`,
119
119
  [],
120
120
  );
121
121
 
@@ -130,12 +130,12 @@ describe('components/TeacherDashboardTrainingLoader', () => {
130
130
  router={createMemoryRouter(
131
131
  [
132
132
  {
133
- path: '/:organizationId/:offerId',
133
+ path: '/:organizationId/:offeringId',
134
134
  element: <TeacherDashboardTrainingLoader />,
135
135
  },
136
136
  ],
137
137
  {
138
- initialEntries: [`/${organization.id}/${offer.id}`],
138
+ initialEntries: [`/${organization.id}/${offering.id}`],
139
139
  },
140
140
  )}
141
141
  />
@@ -151,11 +151,11 @@ describe('components/TeacherDashboardTrainingLoader', () => {
151
151
  await expectNoSpinner('Loading course...');
152
152
 
153
153
  nbApiCalls += 1; // contracts api call
154
- nbApiCalls += 1; // offers api call
154
+ nbApiCalls += 1; // offerings api call
155
155
  const calledUrls = fetchMock.calls().map((call) => call[0]);
156
156
  expect(calledUrls).toHaveLength(nbApiCalls);
157
157
  expect(calledUrls).toContain(
158
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offers/${offer.id}/`,
158
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/${offering.id}/`,
159
159
  );
160
160
 
161
161
  // main titles
@@ -165,11 +165,11 @@ describe('components/TeacherDashboardTrainingLoader', () => {
165
165
  }),
166
166
  ).toBeInTheDocument();
167
167
 
168
- expect(screen.getAllByRole('heading', { name: capitalize(offer.product.title) })).toHaveLength(
169
- 2,
170
- );
168
+ expect(
169
+ screen.getAllByRole('heading', { name: capitalize(offering.product.title) }),
170
+ ).toHaveLength(2);
171
171
 
172
- const nbCourseRun = offer.product.target_courses.reduce(
172
+ const nbCourseRun = offering.product.target_courses.reduce(
173
173
  (acc, course) => acc + course.course_runs.length,
174
174
  0,
175
175
  );
@@ -6,33 +6,33 @@ import { DashboardLayout } from 'widgets/Dashboard/components/DashboardLayout';
6
6
  import { DashboardCard } from 'widgets/Dashboard/components/DashboardCard';
7
7
  import { Icon, IconTypeEnum } from 'components/Icon';
8
8
  import Banner, { BannerType } from 'components/Banner';
9
- import { Offer } from 'types/Joanie';
9
+ import { Offering } from 'types/Joanie';
10
10
 
11
11
  const messages = defineMessages({
12
- errorNoOffer: {
12
+ errorNoOffering: {
13
13
  defaultMessage: "This product doesn't exist",
14
- description: 'Message displayed when requested offer is not found',
15
- id: 'components.TeacherDashboardTraining.errorNoOffer',
14
+ description: 'Message displayed when requested offering is not found',
15
+ id: 'components.TeacherDashboardTraining.errorNoOffering',
16
16
  },
17
17
  });
18
18
 
19
19
  interface TeacherDashboardTrainingProps {
20
- offer: Offer;
20
+ offering: Offering;
21
21
  }
22
22
 
23
- export const TeacherDashboardTraining = ({ offer }: TeacherDashboardTrainingProps) => {
23
+ export const TeacherDashboardTraining = ({ offering }: TeacherDashboardTrainingProps) => {
24
24
  const intl = useIntl();
25
- return offer ? (
25
+ return offering ? (
26
26
  <div className="teacher-course-page">
27
27
  <DashboardCard
28
28
  className="icon-arrow-right-rounded"
29
29
  header={
30
30
  <div>
31
31
  <div className="dashboard__title_container--small">
32
- <h2 className="dashboard__title--large">{capitalize(offer.product.title)}</h2>
32
+ <h2 className="dashboard__title--large">{capitalize(offering.product.title)}</h2>
33
33
  </div>
34
- {offer.product.description && (
35
- <div className="dashboard__quote">{offer.product.description}</div>
34
+ {offering.product.description && (
35
+ <div className="dashboard__quote">{offering.product.description}</div>
36
36
  )}
37
37
  </div>
38
38
  }
@@ -40,7 +40,7 @@ export const TeacherDashboardTraining = ({ offer }: TeacherDashboardTrainingProp
40
40
  fullWidth
41
41
  />
42
42
  <DashboardLayout.NestedSection>
43
- {offer.product.target_courses.map((course) => (
43
+ {offering.product.target_courses.map((course) => (
44
44
  <DashboardLayout.Section key={`course_target_${course.code}`}>
45
45
  <DashboardCard
46
46
  className="icon-arrow-right-rounded"
@@ -62,7 +62,11 @@ export const TeacherDashboardTraining = ({ offer }: TeacherDashboardTrainingProp
62
62
  </DashboardLayout.NestedSection>
63
63
  </div>
64
64
  ) : (
65
- <Banner message={intl.formatMessage(messages.errorNoOffer)} type={BannerType.ERROR} rounded />
65
+ <Banner
66
+ message={intl.formatMessage(messages.errorNoOffering)}
67
+ type={BannerType.ERROR}
68
+ rounded
69
+ />
66
70
  );
67
71
  };
68
72
 
@@ -38,7 +38,7 @@ export interface Organization {
38
38
  }
39
39
 
40
40
  export interface OrganizationResourceQuery extends ResourcesQuery {
41
- offer_id?: Offer['id'];
41
+ offering_id?: Offering['id'];
42
42
  }
43
43
 
44
44
  export interface ContractDefinition {
@@ -174,7 +174,7 @@ export interface DefinitionResourcesProduct {
174
174
  contract_definition_id: Nullable<ContractDefinition['id']>;
175
175
  }
176
176
 
177
- export interface OfferLight {
177
+ export interface OfferingLight {
178
178
  id: string;
179
179
  course: CourseLight;
180
180
  organizations: Organization[];
@@ -182,7 +182,7 @@ export interface OfferLight {
182
182
  created_on: string;
183
183
  }
184
184
 
185
- export interface OfferRule {
185
+ export interface OfferingRule {
186
186
  discounted_price: Nullable<number>;
187
187
  discount_rate: Nullable<number>;
188
188
  discount_amount: Nullable<number>;
@@ -194,11 +194,13 @@ export interface OfferRule {
194
194
  has_seats_left: boolean;
195
195
  }
196
196
 
197
- export interface Offer extends OfferLight {
197
+ export interface Offering extends OfferingLight {
198
198
  is_withdrawable: boolean;
199
- rules: OfferRule;
199
+ rules: OfferingRule;
200
200
  }
201
- export function isOffer(entity: CourseListItem | OfferLight | RichieCourse): entity is OfferLight {
201
+ export function isOffering(
202
+ entity: CourseListItem | OfferingLight | RichieCourse,
203
+ ): entity is OfferingLight {
202
204
  return 'course' in entity && 'product' in entity;
203
205
  }
204
206
 
@@ -243,7 +245,7 @@ export interface Enrollment {
243
245
  was_created_by_order: boolean;
244
246
  created_on: string;
245
247
  orders: OrderEnrollment[];
246
- offers: Offer[];
248
+ offerings: Offering[];
247
249
  certificate_id: Nullable<string>;
248
250
  }
249
251
  export const isEnrollment = (obj: unknown | Enrollment | OpenEdXEnrollment): obj is Enrollment => {
@@ -257,7 +259,7 @@ export const isEnrollment = (obj: unknown | Enrollment | OpenEdXEnrollment): obj
257
259
  'was_created_by_order' in obj &&
258
260
  'created_on' in obj &&
259
261
  'orders' in obj &&
260
- 'offers' in obj &&
262
+ 'offerings' in obj &&
261
263
  'certificate_id' in obj
262
264
  );
263
265
  };
@@ -407,7 +409,7 @@ export interface NestedCourseOrder {
407
409
 
408
410
  export interface CourseOrderResourceQuery extends PaginatedResourceQuery {
409
411
  course_id?: CourseListItem['id'];
410
- offer_id?: Offer['id'];
412
+ offering_id?: Offering['id'];
411
413
  organization_id?: Organization['id'];
412
414
  product_id?: Product['id'];
413
415
  }
@@ -542,8 +544,8 @@ export interface CourseProductQueryFilters extends ResourcesQuery {
542
544
  id?: Product['id'];
543
545
  course_id?: CourseListItem['id'];
544
546
  }
545
- export interface OfferQueryFilters extends PaginatedResourceQuery {
546
- id?: Offer['id'];
547
+ export interface OfferingQueryFilters extends PaginatedResourceQuery {
548
+ id?: Offering['id'];
547
549
  organization_id?: Organization['id'];
548
550
  product_type?: ProductType;
549
551
  query?: string;
@@ -556,7 +558,7 @@ export enum ContractState {
556
558
  }
557
559
  export interface ContractResourceQuery extends PaginatedResourceQuery {
558
560
  organization_id?: Organization['id'];
559
- offer_id?: Offer['id'];
561
+ offering_id?: Offering['id'];
560
562
  contract_ids?: Contract['id'][];
561
563
  signature_state?: ContractState;
562
564
  }
@@ -564,7 +566,7 @@ export interface ContractResourceQuery extends PaginatedResourceQuery {
564
566
  export interface OrganizationContractSignatureLinksFilters {
565
567
  contracts_ids?: string[];
566
568
  organization_id: Organization['id'];
567
- offer_ids?: Offer['id'][];
569
+ offering_ids?: Offering['id'][];
568
570
  }
569
571
 
570
572
  export interface ContractInvitationLinkResponse {
@@ -658,10 +660,10 @@ interface APIUser {
658
660
  check: (id: string) => Promise<Response>;
659
661
  create: ({
660
662
  organization_id,
661
- offer_id,
663
+ offering_id,
662
664
  }: {
663
665
  organization_id?: Organization['id'];
664
- offer_id?: Offer['id'];
666
+ offering_id?: Offering['id'];
665
667
  }) => Promise<{ url: string }>;
666
668
  get: (id: string) => Promise<File>;
667
669
  };
@@ -677,7 +679,7 @@ export interface API {
677
679
  ? Promise<Nullable<CourseListItem>>
678
680
  : Promise<PaginatedResponse<CourseListItem>>;
679
681
  products: {
680
- get(filters?: CourseProductQueryFilters): Promise<Nullable<Offer>>;
682
+ get(filters?: CourseProductQueryFilters): Promise<Nullable<Offering>>;
681
683
  paymentSchedule: {
682
684
  get(filters?: CourseProductQueryFilters): Promise<Nullable<PaymentSchedule>>;
683
685
  };
@@ -710,12 +712,12 @@ export interface API {
710
712
  filters?: CourseRunFilters,
711
713
  ): CourseRunFilters extends { id: string } ? Promise<Nullable<CourseRun>> : Promise<CourseRun>;
712
714
  };
713
- offers: {
715
+ offerings: {
714
716
  get<Filters extends PaginatedResourceQuery = PaginatedResourceQuery>(
715
717
  filters?: Filters,
716
718
  ): Filters extends { id: string }
717
- ? Promise<Nullable<Offer>>
718
- : Promise<PaginatedResponse<OfferLight>>;
719
+ ? Promise<Nullable<Offering>>
720
+ : Promise<PaginatedResponse<OfferingLight>>;
719
721
  };
720
722
  contractDefinitions: {
721
723
  previewTemplate(id: string): Promise<File>;
@@ -12,7 +12,7 @@ import {
12
12
  CourseLight,
13
13
  CourseListItem,
14
14
  CourseProduct,
15
- Offer,
15
+ Offering,
16
16
  CourseRun,
17
17
  CredentialOrder,
18
18
  CredentialProduct,
@@ -89,7 +89,7 @@ export const EnrollmentFactory = factory((): Enrollment => {
89
89
  id: faker.string.uuid(),
90
90
  course_run: CourseRunWithCourseFactory().one(),
91
91
  is_active: true,
92
- offers: OfferFactory().many(1),
92
+ offerings: OfferingFactory().many(1),
93
93
  state: EnrollmentState.SET,
94
94
  was_created_by_order: false,
95
95
  created_on: faker.date.past({ years: 1 }).toISOString(),
@@ -309,7 +309,7 @@ export const NestedCourseOrderFactory = factory((): NestedCourseOrder => {
309
309
  };
310
310
  });
311
311
 
312
- export const OfferFactory = factory((): Offer => {
312
+ export const OfferingFactory = factory((): Offering => {
313
313
  return {
314
314
  id: faker.string.uuid(),
315
315
  created_on: faker.date.past().toISOString(),
@@ -3,14 +3,14 @@ import { CredentialOrder } from 'types/Joanie';
3
3
  import {
4
4
  ContractDefinitionFactory,
5
5
  CourseFactory,
6
- OfferFactory,
6
+ OfferingFactory,
7
7
  ProductFactory,
8
8
  } from 'utils/test/factories/joanie';
9
9
 
10
10
  export const mockCourseProductWithOrder = (order: CredentialOrder) => {
11
11
  const courseCode = order.course.code;
12
12
  const productId = order.product_id;
13
- const offer = OfferFactory({
13
+ const offering = OfferingFactory({
14
14
  product: ProductFactory({
15
15
  id: order.product_id,
16
16
  contract_definition: order.contract ? ContractDefinitionFactory().one() : undefined,
@@ -22,7 +22,7 @@ export const mockCourseProductWithOrder = (order: CredentialOrder) => {
22
22
 
23
23
  fetchMock.get(
24
24
  `https://joanie.endpoint/api/v1.0/courses/${courseCode}/products/${productId}/`,
25
- offer,
25
+ offering,
26
26
  );
27
- return offer;
27
+ return offering;
28
28
  };
@@ -33,7 +33,7 @@ export const DashboardItemEnrollment = ({ enrollment }: DashboardItemCourseRunPr
33
33
  </div>
34
34
  </div>,
35
35
  ];
36
- enrollment.offers.forEach(({ product, is_withdrawable }) => {
36
+ enrollment.offerings.forEach(({ product, is_withdrawable }) => {
37
37
  if (isCertificateProduct(product)) {
38
38
  partialFooterList.push(
39
39
  <ProductCertificateFooter
@@ -249,7 +249,7 @@ describe('<ProductCertificateFooter/>', () => {
249
249
  course,
250
250
  }).one(),
251
251
  }).one();
252
- enrollment.offers[0].product = CertificateProductFactory().one();
252
+ enrollment.offerings[0].product = CertificateProductFactory().one();
253
253
 
254
254
  fetchMock.get(
255
255
  `https://joanie.endpoint/api/v1.0/enrollments/?was_created_by_order=false&is_active=true&page=1&page_size=${PER_PAGE.useOrdersEnrollments}`,
@@ -67,15 +67,15 @@ export const DashboardItemOrder = ({
67
67
  }: DashboardItemOrderProps) => {
68
68
  const { course } = order;
69
69
  const intl = useIntl();
70
- const { item: offer } = useCourseProduct({
70
+ const { item: offering } = useCourseProduct({
71
71
  product_id: order.product_id,
72
72
  course_id: course.code,
73
73
  });
74
- const { product } = offer || {};
74
+ const { product } = offering || {};
75
75
  const needsSignature = OrderHelper.orderNeedsSignature(order);
76
76
  const needsPaymentMethod = order.state === OrderState.TO_SAVE_PAYMENT_METHOD;
77
77
  const isActive = OrderHelper.isActive(order);
78
- const isProductPurchasable = ProductHelper.isPurchasable(offer?.product);
78
+ const isProductPurchasable = ProductHelper.isPurchasable(offering?.product);
79
79
  const isNotResumable = !isActive && !isProductPurchasable;
80
80
  const canEnroll = OrderHelper.allowEnrollment(order);
81
81
 
@@ -57,7 +57,7 @@ describe('<DashboardItemOrder/> Contract', () => {
57
57
  contract: ContractFactory({ student_signed_on: null }).one(),
58
58
  }).one();
59
59
 
60
- // learner dashboard course page do one call to offer per order
60
+ // learner dashboard course page do one call to offering per order
61
61
  const { product } = mockCourseProductWithOrder(order);
62
62
 
63
63
  // overwrite useOmniscientOrders call
@@ -94,7 +94,7 @@ const Installment = ({ order }: Props) => {
94
94
 
95
95
  const PaymentMethodManager = ({ order }: Props) => {
96
96
  const needsPaymentMethod = order.state === OrderState.TO_SAVE_PAYMENT_METHOD;
97
- const { item: offer, states } = useCourseProduct({
97
+ const { item: offering, states } = useCourseProduct({
98
98
  course_id: order.course.code,
99
99
  product_id: order.product_id,
100
100
  });
@@ -118,9 +118,9 @@ const PaymentMethodManager = ({ order }: Props) => {
118
118
  )}
119
119
  <SaleTunnel
120
120
  {...modal}
121
- product={offer.product as CredentialProduct}
122
- course={offer.course}
123
- isWithdrawable={offer.is_withdrawable}
121
+ product={offering.product as CredentialProduct}
122
+ course={offering.course}
123
+ isWithdrawable={offering.is_withdrawable}
124
124
  />
125
125
  </>
126
126
  );
@@ -25,6 +25,6 @@ export const enrollment: Enrollment = {
25
25
  },
26
26
  languages: ['en'],
27
27
  },
28
- offers: [],
28
+ offerings: [],
29
29
  certificate_id: null,
30
30
  };