richie-education 3.1.3-dev12 → 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 +5 -3
  9. package/js/components/SaleTunnel/index.full-process.spec.tsx +3 -3
  10. package/js/components/SaleTunnel/index.spec.tsx +76 -63
  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 +27 -20
  52. package/js/utils/test/factories/joanie.ts +14 -11
  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 -14
  68. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +105 -75
  69. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +6 -4
  70. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.tsx +27 -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
@@ -1,7 +1,7 @@
1
1
  import { createSearchParams } from 'react-router';
2
2
  import { useMemo } from 'react';
3
3
  import { MenuLink } from 'widgets/Dashboard/components/DashboardSidebar';
4
- import { ContractState, Offer, Organization } from 'types/Joanie';
4
+ import { ContractState, Offering, Organization } from 'types/Joanie';
5
5
  import useTeacherPendingContractsCount from 'hooks/useTeacherPendingContractsCount';
6
6
  import { ContractActions } from 'utils/AbilitiesHelper/types';
7
7
  import useContractAbilities from 'hooks/useContractAbilities';
@@ -11,14 +11,14 @@ import MenuNavLink from '../MenuNavLink';
11
11
  interface ContractNavLinkProps {
12
12
  link: MenuLink;
13
13
  organizationId?: Organization['id'];
14
- offerId?: Offer['id'];
14
+ offeringId?: Offering['id'];
15
15
  }
16
16
 
17
- const ContractNavLink = ({ link, organizationId, offerId }: ContractNavLinkProps) => {
17
+ const ContractNavLink = ({ link, organizationId, offeringId }: ContractNavLinkProps) => {
18
18
  const defaultOrganizationId = useDefaultOrganizationId();
19
19
  const { contracts: pendingContracts, pendingContractCount } = useTeacherPendingContractsCount({
20
20
  organizationId: organizationId || defaultOrganizationId,
21
- offerId,
21
+ offeringId,
22
22
  });
23
23
  const contractAbilities = useContractAbilities(pendingContracts);
24
24
  const canSignContracts = contractAbilities.can(ContractActions.SIGN);
@@ -4,7 +4,7 @@ import { createIntl } from 'react-intl';
4
4
  import { generatePath } from 'react-router';
5
5
  import { CourseListItem } from 'types/Joanie';
6
6
  import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
7
- import { CourseFactory, OfferFactory, OrganizationFactory } from 'utils/test/factories/joanie';
7
+ import { CourseFactory, OfferingFactory, OrganizationFactory } from 'utils/test/factories/joanie';
8
8
  import { expectNoSpinner } from 'utils/test/expectSpinner';
9
9
  import { render } from 'utils/test/render';
10
10
  import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
@@ -61,14 +61,14 @@ describe('<TeacherDashboardCourseSidebar/>', () => {
61
61
  label: 'course',
62
62
  course: CourseFactory().one(),
63
63
  organization: undefined,
64
- offer: undefined,
64
+ offering: undefined,
65
65
  expectedRoutes: [TeacherDashboardPaths.COURSE_GENERAL_INFORMATION],
66
66
  },
67
67
  {
68
68
  label: 'training',
69
69
  course: CourseFactory().one(),
70
70
  organization: undefined,
71
- offer: OfferFactory().one(),
71
+ offering: OfferingFactory().one(),
72
72
  expectedRoutes: [
73
73
  TeacherDashboardPaths.COURSE_PRODUCT,
74
74
  TeacherDashboardPaths.COURSE_PRODUCT_CONTRACTS,
@@ -79,14 +79,14 @@ describe('<TeacherDashboardCourseSidebar/>', () => {
79
79
  label: "organization's course",
80
80
  course: CourseFactory().one(),
81
81
  organization: OrganizationFactory().one(),
82
- offer: undefined,
82
+ offering: undefined,
83
83
  expectedRoutes: [TeacherDashboardPaths.ORGANIZATION_COURSE_GENERAL_INFORMATION],
84
84
  },
85
85
  {
86
86
  label: "organization's training",
87
87
  course: CourseFactory().one(),
88
88
  organization: OrganizationFactory().one(),
89
- offer: OfferFactory().one(),
89
+ offering: OfferingFactory().one(),
90
90
  expectedRoutes: [
91
91
  TeacherDashboardPaths.ORGANIZATION_PRODUCT,
92
92
  TeacherDashboardPaths.ORGANIZATION_PRODUCT_CONTRACTS,
@@ -95,20 +95,20 @@ describe('<TeacherDashboardCourseSidebar/>', () => {
95
95
  },
96
96
  ])(
97
97
  'should display menu items for "$label" route',
98
- async ({ course, organization, offer, expectedRoutes }) => {
98
+ async ({ course, organization, offering, expectedRoutes }) => {
99
99
  // mock api for organization's training
100
- if (organization && offer) {
100
+ if (organization && offering) {
101
101
  // fetching training's contracts
102
102
  nbApiRequest += 1;
103
103
  fetchMock.get(
104
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/contracts/?offer_id=${offer.id}&signature_state=half_signed&page=1&page_size=25`,
104
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/contracts/?offering_id=${offering.id}&signature_state=half_signed&page=1&page_size=25`,
105
105
  [],
106
106
  );
107
107
  // fetching organization's training
108
108
  nbApiRequest += 1;
109
109
  fetchMock.get(
110
- `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offers/${offer.id}/`,
111
- offer,
110
+ `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/${offering.id}/`,
111
+ offering,
112
112
  );
113
113
  } else if (organization) {
114
114
  // fetching organization's course
@@ -117,12 +117,15 @@ describe('<TeacherDashboardCourseSidebar/>', () => {
117
117
  `https://joanie.endpoint/api/v1.0/organizations/${organization.id}/courses/${course.id}/`,
118
118
  course,
119
119
  );
120
- } else if (offer) {
120
+ } else if (offering) {
121
121
  // fetching training
122
122
  nbApiRequest += 1;
123
- fetchMock.get(`https://joanie.endpoint/api/v1.0/offers/${offer.id}/`, offer);
123
+ fetchMock.get(`https://joanie.endpoint/api/v1.0/offerings/${offering.id}/`, offering);
124
124
  nbApiRequest += 1;
125
- fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/?offer_id=${offer.id}`, []);
125
+ fetchMock.get(
126
+ `https://joanie.endpoint/api/v1.0/organizations/?offering_id=${offering.id}`,
127
+ [],
128
+ );
126
129
  } else {
127
130
  // mock api for course
128
131
  nbApiRequest += 1;
@@ -132,9 +135,9 @@ describe('<TeacherDashboardCourseSidebar/>', () => {
132
135
  let routePath = '/:courseId';
133
136
  let initialEntry = `/${course.id}`;
134
137
 
135
- if (offer) {
136
- routePath += '/:offerId';
137
- initialEntry += `/${offer.id}`;
138
+ if (offering) {
139
+ routePath += '/:offeringId';
140
+ initialEntry += `/${offering.id}`;
138
141
  }
139
142
  if (organization) {
140
143
  routePath = '/:organizationId' + routePath;
@@ -158,7 +161,7 @@ describe('<TeacherDashboardCourseSidebar/>', () => {
158
161
  generatePath(expectedRoute, {
159
162
  organizationId: organization ? organization.id : null,
160
163
  courseId: course.id,
161
- offerId: offer ? offer.id : null,
164
+ offeringId: offering ? offering.id : null,
162
165
  }),
163
166
  );
164
167
  });
@@ -2,7 +2,7 @@ import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
2
2
  import { generatePath, useParams } from 'react-router';
3
3
  import { useMemo } from 'react';
4
4
  import { capitalize } from 'lodash-es';
5
- import { useOffer } from 'hooks/useOffer';
5
+ import { useOffering } from 'hooks/useOffering';
6
6
  import { DashboardSidebar, MenuLink } from 'widgets/Dashboard/components/DashboardSidebar';
7
7
  import { getDashboardRouteLabel } from 'widgets/Dashboard/utils/dashboardRoutes';
8
8
  import { useCourse } from 'hooks/useCourses';
@@ -41,11 +41,11 @@ export const TeacherDashboardCourseSidebar = () => {
41
41
  const {
42
42
  organizationId: routeOrganizationId,
43
43
  courseId: routeCourseId,
44
- offerId: routeofferId = '',
44
+ offeringId: routeOfferingId = '',
45
45
  } = useParams<{
46
46
  organizationId?: string;
47
47
  courseId: string;
48
- offerId: string;
48
+ offeringId: string;
49
49
  }>();
50
50
 
51
51
  const {
@@ -54,29 +54,35 @@ export const TeacherDashboardCourseSidebar = () => {
54
54
  } = useCourse(
55
55
  routeCourseId,
56
56
  { organization_id: routeOrganizationId },
57
- { enabled: !routeofferId },
57
+ { enabled: !routeOfferingId },
58
58
  );
59
59
 
60
60
  const {
61
- item: offer,
62
- states: { fetching: offerFetching },
63
- } = useOffer(
64
- routeofferId,
61
+ item: offering,
62
+ states: { fetching: offeringFetching },
63
+ } = useOffering(
64
+ routeOfferingId,
65
65
  {
66
66
  organization_id: routeOrganizationId,
67
67
  },
68
- { enabled: !!routeofferId },
68
+ { enabled: !!routeOfferingId },
69
69
  );
70
70
 
71
- const fetching = useMemo(() => courseFetching || offerFetching, [courseFetching, offerFetching]);
72
- const product = useMemo(() => (offer ? offer.product : undefined), [offer]);
73
- const course = useMemo(() => (offer ? offer.course : singleCourse), [offer, singleCourse]);
71
+ const fetching = useMemo(
72
+ () => courseFetching || offeringFetching,
73
+ [courseFetching, offeringFetching],
74
+ );
75
+ const product = useMemo(() => (offering ? offering.product : undefined), [offering]);
76
+ const course = useMemo(
77
+ () => (offering ? offering.course : singleCourse),
78
+ [offering, singleCourse],
79
+ );
74
80
 
75
81
  const getMenuLinkFromPath = (basePath: TeacherDashboardPaths) => {
76
82
  const path = generatePath(basePath, {
77
83
  organizationId: routeOrganizationId ?? '',
78
84
  courseId: routeCourseId ?? '',
79
- offerId: routeofferId ?? '',
85
+ offeringId: routeOfferingId ?? '',
80
86
  });
81
87
  const menuLink: MenuLink = {
82
88
  to: path,
@@ -93,7 +99,7 @@ export const TeacherDashboardCourseSidebar = () => {
93
99
  <ContractNavLink
94
100
  link={menuLink}
95
101
  organizationId={routeOrganizationId}
96
- offerId={routeofferId}
102
+ offeringId={routeOfferingId}
97
103
  />
98
104
  );
99
105
  }
@@ -103,10 +109,10 @@ export const TeacherDashboardCourseSidebar = () => {
103
109
  const menuLinkList = useMemo(
104
110
  () =>
105
111
  getMenuRoutes({
106
- offerId: routeofferId,
112
+ offeringId: routeOfferingId,
107
113
  organizationId: routeOrganizationId,
108
114
  }).map(getMenuLinkFromPath),
109
- [routeOrganizationId, routeofferId],
115
+ [routeOrganizationId, routeOfferingId],
110
116
  );
111
117
 
112
118
  return (
@@ -1,13 +1,13 @@
1
1
  import { TeacherDashboardPaths } from 'widgets/Dashboard/utils/teacherDashboardPaths';
2
2
 
3
3
  interface GetMenuRoutesArgs {
4
- offerId?: string;
4
+ offeringId?: string;
5
5
  organizationId?: string;
6
6
  }
7
7
 
8
- export const getMenuRoutes = ({ offerId, organizationId }: GetMenuRoutesArgs) => {
8
+ export const getMenuRoutes = ({ offeringId, organizationId }: GetMenuRoutesArgs) => {
9
9
  if (organizationId) {
10
- if (offerId) {
10
+ if (offeringId) {
11
11
  return [
12
12
  TeacherDashboardPaths.ORGANIZATION_PRODUCT,
13
13
  TeacherDashboardPaths.ORGANIZATION_PRODUCT_CONTRACTS,
@@ -17,7 +17,7 @@ export const getMenuRoutes = ({ offerId, organizationId }: GetMenuRoutesArgs) =>
17
17
  return [TeacherDashboardPaths.ORGANIZATION_COURSE_GENERAL_INFORMATION];
18
18
  }
19
19
 
20
- if (offerId) {
20
+ if (offeringId) {
21
21
  return [
22
22
  TeacherDashboardPaths.COURSE_PRODUCT,
23
23
  TeacherDashboardPaths.COURSE_PRODUCT_CONTRACTS,
@@ -24,9 +24,9 @@ const messages = defineMessages({
24
24
  export const TeacherDashboardOrganizationSidebar = () => {
25
25
  const intl = useIntl();
26
26
  const getRouteLabel = getDashboardRouteLabel(intl);
27
- const { organizationId, offerId } = useParams<{
27
+ const { organizationId, offeringId } = useParams<{
28
28
  organizationId: string;
29
- offerId?: string;
29
+ offeringId?: string;
30
30
  }>();
31
31
  const {
32
32
  item: organization,
@@ -43,7 +43,7 @@ export const TeacherDashboardOrganizationSidebar = () => {
43
43
 
44
44
  if (basePath === TeacherDashboardPaths.ORGANIZATION_CONTRACTS) {
45
45
  menuLink.component = (
46
- <ContractNavLink link={menuLink} organizationId={organizationId} offerId={offerId} />
46
+ <ContractNavLink link={menuLink} organizationId={organizationId} offeringId={offeringId} />
47
47
  );
48
48
  }
49
49
 
@@ -9,14 +9,14 @@ export enum TeacherDashboardPaths {
9
9
  ORGANIZATION = `${ROOT}/organizations/:organizationId`,
10
10
  ORGANIZATION_CONTRACTS = `${ORGANIZATION}/contracts`,
11
11
  ORGANIZATION_COURSES = `${ORGANIZATION}/courses`,
12
- ORGANIZATION_PRODUCT = `${ORGANIZATION_COURSES}/:courseId/products/:offerId`,
12
+ ORGANIZATION_PRODUCT = `${ORGANIZATION_COURSES}/:courseId/products/:offeringId`,
13
13
  ORGANIZATION_COURSE_CONTRACTS = `${ORGANIZATION_COURSES}/:courseId/contracts`,
14
- ORGANIZATION_PRODUCT_CONTRACTS = `${ORGANIZATION_COURSES}/:courseId/products/:offerId/contracts`,
15
- ORGANIZATION_COURSE_PRODUCT_LEARNER_LIST = `${ORGANIZATION_COURSES}/:courseId/products/:offerId/learners`,
14
+ ORGANIZATION_PRODUCT_CONTRACTS = `${ORGANIZATION_COURSES}/:courseId/products/:offeringId/contracts`,
15
+ ORGANIZATION_COURSE_PRODUCT_LEARNER_LIST = `${ORGANIZATION_COURSES}/:courseId/products/:offeringId/learners`,
16
16
  ORGANIZATION_COURSE_GENERAL_INFORMATION = `${ORGANIZATION_COURSES}/:courseId/information`,
17
17
  COURSE = `${TEACHER_COURSES}/:courseId`,
18
18
  COURSE_GENERAL_INFORMATION = `${COURSE}/information`,
19
- COURSE_PRODUCT = `${COURSE}/products/:offerId`,
19
+ COURSE_PRODUCT = `${COURSE}/products/:offeringId`,
20
20
  COURSE_PRODUCT_LEARNER_LIST = `${COURSE_PRODUCT}/learners`,
21
21
  COURSE_PRODUCT_CONTRACTS = `${COURSE_PRODUCT}/contracts`,
22
22
  }
@@ -1,6 +1,6 @@
1
1
  import { FormattedMessage, defineMessages } from 'react-intl';
2
2
  import PurchaseButton from 'components/PurchaseButton';
3
- import { Offer, CredentialProduct } from 'types/Joanie';
3
+ import { Offering, CredentialProduct } from 'types/Joanie';
4
4
  import { PacedCourse } from 'types';
5
5
 
6
6
  const messages = defineMessages({
@@ -24,16 +24,16 @@ other {# remaining seats}
24
24
 
25
25
  interface CourseProductItemFooterProps {
26
26
  course: PacedCourse;
27
- offer: Offer;
27
+ offering: Offering;
28
28
  canPurchase: boolean;
29
29
  }
30
30
 
31
- const CourseProductItemFooter = ({ course, offer, canPurchase }: CourseProductItemFooterProps) => {
32
- // eslint-disable-next-line @typescript-eslint/naming-convention
33
- const { seats, nb_seats_available } = offer;
34
- const hasSeatsLimit = seats && nb_seats_available !== undefined;
35
- const hasNoSeatsAvailable = hasSeatsLimit && nb_seats_available === 0;
36
- if (hasNoSeatsAvailable)
31
+ const CourseProductItemFooter = ({
32
+ course,
33
+ offering,
34
+ canPurchase,
35
+ }: CourseProductItemFooterProps) => {
36
+ if (!offering.rules.has_seats_left)
37
37
  return (
38
38
  <p className="product-widget__footer__message">
39
39
  <FormattedMessage {...messages.noSeatsAvailable} />
@@ -43,18 +43,18 @@ const CourseProductItemFooter = ({ course, offer, canPurchase }: CourseProductIt
43
43
  <div className="product-widget__footer__order-group">
44
44
  <PurchaseButton
45
45
  course={course}
46
- product={offer.product as CredentialProduct}
47
- offer={offer}
48
- organizations={offer.organizations}
49
- isWithdrawable={offer.is_withdrawable}
46
+ product={offering.product as CredentialProduct}
47
+ offering={offering}
48
+ organizations={offering.organizations}
49
+ isWithdrawable={offering.is_withdrawable}
50
50
  disabled={!canPurchase}
51
51
  buttonProps={{ fullWidth: true }}
52
52
  />
53
- {hasSeatsLimit && (
53
+ {offering.rules.has_seat_limit && (
54
54
  <p className="product-widget__footer__message">
55
55
  <FormattedMessage
56
56
  {...messages.nbSeatsAvailable}
57
- values={{ nb: offer.nb_seats_available }}
57
+ values={{ nb: offering.rules.nb_available_seats }}
58
58
  />
59
59
  </p>
60
60
  )}