richie-education 2.28.2-dev39 → 2.28.2-dev58
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.
- package/.eslintrc.json +11 -2
- package/i18n/locales/ar-SA.json +209 -125
- package/i18n/locales/es-ES.json +210 -126
- package/i18n/locales/fa-IR.json +209 -125
- package/i18n/locales/fr-CA.json +209 -125
- package/i18n/locales/fr-FR.json +209 -125
- package/i18n/locales/ko-KR.json +209 -125
- package/i18n/locales/pt-PT.json +212 -128
- package/i18n/locales/ru-RU.json +209 -125
- package/i18n/locales/vi-VN.json +209 -125
- package/js/api/joanie.ts +14 -17
- package/js/api/lms/dummy.ts +1 -12
- package/js/components/ContractFrame/AbstractContractFrame.spec.tsx +16 -9
- package/js/components/ContractFrame/AbstractContractFrame.tsx +32 -25
- package/js/components/ContractFrame/LearnerContractFrame.tsx +2 -2
- package/js/components/ContractFrame/_styles.scss +6 -14
- package/js/components/CreditCardSelector/index.spec.tsx +7 -7
- package/js/components/CreditCardSelector/index.tsx +2 -2
- package/js/components/DownloadContractButton/index.spec.tsx +1 -1
- package/js/components/OpenEdxFullNameForm/index.spec.tsx +229 -0
- package/js/components/OpenEdxFullNameForm/index.tsx +7 -7
- package/js/components/PaymentInterfaces/LyraPopIn.tsx +2 -2
- package/js/components/PaymentInterfaces/PayplugLightbox.tsx +1 -1
- package/js/components/PaymentInterfaces/__mocks__/index.tsx +1 -4
- package/js/components/PaymentInterfaces/types.ts +5 -2
- package/js/components/PurchaseButton/index.spec.tsx +69 -37
- package/js/components/SaleTunnel/AddressSelector/index.spec.tsx +2 -1
- package/js/components/SaleTunnel/CertificateSaleTunnel/index.tsx +2 -2
- package/js/components/SaleTunnel/CredentialSaleTunnel/index.tsx +6 -10
- package/js/components/SaleTunnel/GenericSaleTunnel.tsx +75 -41
- package/js/components/SaleTunnel/SaleTunnelInformation/index.tsx +0 -30
- package/js/components/SaleTunnel/SaleTunnelSavePaymentMethod/_styles.scss +12 -0
- package/js/components/SaleTunnel/SaleTunnelSavePaymentMethod/index.tsx +160 -0
- package/js/components/SaleTunnel/SaleTunnelSuccess/index.tsx +15 -29
- package/js/components/SaleTunnel/Sponsors/SaleTunnelSponsors.tsx +5 -0
- package/js/components/SaleTunnel/SubscriptionButton/_styles.scss +7 -0
- package/js/components/SaleTunnel/SubscriptionButton/index.tsx +202 -0
- package/js/components/SaleTunnel/_styles.scss +10 -1
- package/js/components/SaleTunnel/hooks/useTerms.tsx +0 -77
- package/js/components/SaleTunnel/index.credential.spec.tsx +12 -21
- package/js/components/SaleTunnel/index.full-process.spec.tsx +110 -48
- package/js/components/SaleTunnel/index.spec.tsx +330 -779
- package/js/components/SignContractButton/index.omniscientOrders.spec.tsx +16 -11
- package/js/components/SignContractButton/index.spec.tsx +16 -20
- package/js/components/SignContractButton/index.tsx +3 -1
- package/js/hooks/useCreditCards/index.spec.tsx +70 -6
- package/js/hooks/useCreditCards/index.ts +49 -11
- package/js/hooks/useOrders/index.spec.tsx +322 -0
- package/js/hooks/{useOrders.ts → useOrders/index.ts} +40 -14
- package/js/hooks/useProductOrder/index.spec.tsx +77 -60
- package/js/hooks/useProductOrder/index.tsx +2 -2
- package/js/hooks/useResources/useResourcesRoot.ts +1 -0
- package/js/pages/DashboardCreditCardsManagement/CreditCardBrandLogo.spec.tsx +1 -1
- package/js/pages/DashboardCreditCardsManagement/CreditCardBrandLogo.tsx +4 -2
- package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.spec.tsx +8 -5
- package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.spec.tsx +8 -9
- package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.spec.tsx +1 -1
- package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.tsx +1 -6
- package/js/settings/settings.test.ts +11 -2
- package/js/translations/ar-SA.json +1 -1
- package/js/translations/es-ES.json +1 -1
- package/js/translations/fa-IR.json +1 -1
- package/js/translations/fr-CA.json +1 -1
- package/js/translations/fr-FR.json +1 -1
- package/js/translations/ko-KR.json +1 -1
- package/js/translations/pt-PT.json +1 -1
- package/js/translations/ru-RU.json +1 -1
- package/js/translations/vi-VN.json +1 -1
- package/js/types/Joanie.ts +49 -34
- package/js/utils/OrderHelper/index.ts +38 -42
- package/js/utils/search/getSuggestionsSection/index.spec.ts +3 -2
- package/js/utils/test/factories/joanie.ts +36 -51
- package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.tsx +8 -18
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +26 -32
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.tsx +11 -6
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.spec.tsx +7 -6
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +9 -10
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.spec.tsx +3 -1
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.useUnionResource.cache.spec.tsx +6 -7
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentDetailsModal/index.tsx +28 -8
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentRetryModal/index.tsx +4 -6
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.spec.tsx +18 -71
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.tsx +34 -35
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateMessage/index.tsx +27 -24
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.spec.tsx +18 -73
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.tsx +32 -16
- package/js/widgets/Dashboard/components/DashboardOrderLoader/index.tsx +3 -11
- package/js/widgets/Dashboard/components/Signature/SignatureDummy.tsx +25 -3
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/EnrollableCourseRunList.tsx +2 -6
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx +7 -14
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.spec.tsx +7 -5
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.tsx +5 -7
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +242 -332
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +12 -13
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.tsx +10 -21
- package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.joanie.spec.tsx +2 -2
- package/package.json +27 -27
- package/scss/components/_index.scss +2 -1
- package/js/components/PaymentButton/_styles.scss +0 -27
- package/js/components/SaleTunnel/GenericPaymentButton/index.tsx +0 -333
- package/js/components/SaleTunnel/SaleTunnelNotValidated/index.tsx +0 -70
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/ProductSignatureHeader/index.tsx +0 -41
|
@@ -4,6 +4,7 @@ import { defineMessages, FormattedMessage } from 'react-intl';
|
|
|
4
4
|
import { SignatureProps } from 'components/ContractFrame';
|
|
5
5
|
import { DummyContractPlaceholder } from 'widgets/Dashboard/components/Signature/DummyContractPlaceholder';
|
|
6
6
|
import { CONTRACT_SETTINGS } from 'settings';
|
|
7
|
+
import { getAPIEndpoint } from 'api/joanie';
|
|
7
8
|
|
|
8
9
|
const messages = defineMessages({
|
|
9
10
|
button: {
|
|
@@ -23,12 +24,31 @@ enum SignatureDummySteps {
|
|
|
23
24
|
SIGNING_LOADING,
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
export const SignatureDummy = ({ onDone }: SignatureProps) => {
|
|
27
|
+
export const SignatureDummy = ({ invitationLink, onDone }: SignatureProps) => {
|
|
27
28
|
const [step, setStep] = useState(SignatureDummySteps.SIGNING);
|
|
28
29
|
|
|
30
|
+
const baseUrl = getAPIEndpoint();
|
|
31
|
+
// eslint-disable-next-line compat/compat
|
|
32
|
+
const link = new URL(invitationLink);
|
|
33
|
+
const reference = link.searchParams.get('reference');
|
|
34
|
+
const event = link.searchParams.get('eventTarget');
|
|
35
|
+
const sendSignatureNotification = () => {
|
|
36
|
+
fetch(`${baseUrl}/signature/notifications/`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: {
|
|
39
|
+
'Content-Type': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
body: JSON.stringify({
|
|
42
|
+
event_type: event,
|
|
43
|
+
reference,
|
|
44
|
+
}),
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
29
48
|
const sign = () => {
|
|
30
49
|
setStep(SignatureDummySteps.SIGNING_LOADING);
|
|
31
50
|
setTimeout(() => {
|
|
51
|
+
sendSignatureNotification();
|
|
32
52
|
onDone();
|
|
33
53
|
}, CONTRACT_SETTINGS.dummySignatureSignTimeout);
|
|
34
54
|
};
|
|
@@ -44,11 +64,13 @@ export const SignatureDummy = ({ onDone }: SignatureProps) => {
|
|
|
44
64
|
</div>
|
|
45
65
|
)}
|
|
46
66
|
{step === SignatureDummySteps.SIGNING_LOADING && (
|
|
47
|
-
<div className="
|
|
67
|
+
<div className="ContractFrame__container">
|
|
48
68
|
<h3 className="ContractFrame__caption">
|
|
49
69
|
<FormattedMessage {...messages.signing} />
|
|
50
70
|
</h3>
|
|
51
|
-
<
|
|
71
|
+
<div className="ContractFrame__footer">
|
|
72
|
+
<Loader />
|
|
73
|
+
</div>
|
|
52
74
|
</div>
|
|
53
75
|
)}
|
|
54
76
|
</>
|
|
@@ -11,7 +11,6 @@ import useDateFormat from 'hooks/useDateFormat';
|
|
|
11
11
|
import { IntlHelper } from 'utils/IntlHelper';
|
|
12
12
|
import WebAnalyticsAPIHandler from 'api/web-analytics';
|
|
13
13
|
import EnrollmentDate from 'components/EnrollmentDate';
|
|
14
|
-
import { Product } from 'types/Joanie';
|
|
15
14
|
import { OrderHelper } from 'utils/OrderHelper';
|
|
16
15
|
import { messages as sharedMessages } from '../CourseRunItem';
|
|
17
16
|
import CourseRunSection, { messages as sectionMessages } from './CourseRunSection';
|
|
@@ -53,16 +52,13 @@ const messages = defineMessages({
|
|
|
53
52
|
interface Props {
|
|
54
53
|
courseRuns: Joanie.CourseRun[];
|
|
55
54
|
order: Joanie.Order;
|
|
56
|
-
product: Product;
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
const EnrollableCourseRunList = ({ courseRuns, order
|
|
57
|
+
const EnrollableCourseRunList = ({ courseRuns, order }: Props) => {
|
|
60
58
|
const intl = useIntl();
|
|
61
59
|
const formatDate = useDateFormat();
|
|
62
60
|
const formRef = useRef<HTMLFormElement>(null);
|
|
63
|
-
const needsSignature = order
|
|
64
|
-
? OrderHelper.orderNeedsSignature(order, product.contract_definition)
|
|
65
|
-
: false;
|
|
61
|
+
const needsSignature = order ? OrderHelper.orderNeedsSignature(order) : false;
|
|
66
62
|
|
|
67
63
|
const [selectedCourseRun, setSelectedCourseRun] = useState<Maybe<Joanie.CourseRun>>();
|
|
68
64
|
const [submitted, setSubmitted] = useState(false);
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
CredentialOrderFactory,
|
|
12
12
|
ProductFactory,
|
|
13
13
|
} from 'utils/test/factories/joanie';
|
|
14
|
-
import
|
|
14
|
+
import { CourseLight, CourseRun, Enrollment, OrderState } from 'types/Joanie';
|
|
15
15
|
import { Deferred } from 'utils/test/deferred';
|
|
16
16
|
import { CourseStateTextEnum, Priority } from 'types';
|
|
17
17
|
import { IntlHelper } from 'utils/IntlHelper';
|
|
@@ -114,10 +114,9 @@ describe('CourseProductCourseRuns', () => {
|
|
|
114
114
|
|
|
115
115
|
it('renders a warning message when no course runs are provided', () => {
|
|
116
116
|
const order = CredentialOrderFactory().one();
|
|
117
|
-
const product = ProductFactory().one();
|
|
118
117
|
|
|
119
118
|
fetchMock.get('https://joanie.endpoint/api/v1.0/enrollments/', []);
|
|
120
|
-
render(<EnrollableCourseRunList courseRuns={[]} order={order}
|
|
119
|
+
render(<EnrollableCourseRunList courseRuns={[]} order={order} />, {
|
|
121
120
|
wrapper: BaseJoanieAppWrapper,
|
|
122
121
|
});
|
|
123
122
|
|
|
@@ -127,12 +126,9 @@ describe('CourseProductCourseRuns', () => {
|
|
|
127
126
|
it('renders a list of course runs with a call to action to enroll', async () => {
|
|
128
127
|
const courseRuns: CourseRun[] = CourseRunFactory().many(2);
|
|
129
128
|
const order = CredentialOrderFactory().one();
|
|
130
|
-
const product = ProductFactory({
|
|
131
|
-
contract_definition: undefined,
|
|
132
|
-
}).one();
|
|
133
129
|
|
|
134
130
|
fetchMock.get('https://joanie.endpoint/api/v1.0/enrollments/', []);
|
|
135
|
-
render(<EnrollableCourseRunList courseRuns={courseRuns} order={order}
|
|
131
|
+
render(<EnrollableCourseRunList courseRuns={courseRuns} order={order} />, {
|
|
136
132
|
wrapper: BaseJoanieAppWrapper,
|
|
137
133
|
});
|
|
138
134
|
|
|
@@ -247,7 +243,7 @@ describe('CourseProductCourseRuns', () => {
|
|
|
247
243
|
fetchMock.get(`https://joanie.endpoint/api/v1.0/courses/${course.code}/`, HttpStatusCode.OK);
|
|
248
244
|
fetchMock.get('https://joanie.endpoint/api/v1.0/enrollments/', []);
|
|
249
245
|
|
|
250
|
-
render(<EnrollableCourseRunList courseRuns={courseRuns} order={order}
|
|
246
|
+
render(<EnrollableCourseRunList courseRuns={courseRuns} order={order} />, {
|
|
251
247
|
wrapper: BaseJoanieAppWrapper,
|
|
252
248
|
});
|
|
253
249
|
|
|
@@ -355,12 +351,10 @@ describe('CourseProductCourseRuns', () => {
|
|
|
355
351
|
text: CourseStateTextEnum.STARTING_ON,
|
|
356
352
|
},
|
|
357
353
|
}).one();
|
|
358
|
-
const product = ProductFactory().one();
|
|
359
|
-
product.contract_definition = undefined;
|
|
360
354
|
const order = CredentialOrderFactory().one();
|
|
361
355
|
|
|
362
356
|
fetchMock.get('https://joanie.endpoint/api/v1.0/enrollments/', []);
|
|
363
|
-
render(<EnrollableCourseRunList courseRuns={[courseRun]} order={order}
|
|
357
|
+
render(<EnrollableCourseRunList courseRuns={[courseRun]} order={order} />, {
|
|
364
358
|
wrapper: BaseJoanieAppWrapper,
|
|
365
359
|
});
|
|
366
360
|
|
|
@@ -438,11 +432,10 @@ describe('CourseProductCourseRuns', () => {
|
|
|
438
432
|
text: CourseStateTextEnum.STARTING_ON,
|
|
439
433
|
},
|
|
440
434
|
}).one();
|
|
441
|
-
const
|
|
442
|
-
const order = CredentialOrderFactory().one();
|
|
435
|
+
const order = CredentialOrderFactory({ state: OrderState.TO_SIGN }).one();
|
|
443
436
|
|
|
444
437
|
fetchMock.get('https://joanie.endpoint/api/v1.0/enrollments/', []);
|
|
445
|
-
render(<EnrollableCourseRunList courseRuns={[courseRun]} order={order}
|
|
438
|
+
render(<EnrollableCourseRunList courseRuns={[courseRun]} order={order} />, {
|
|
446
439
|
wrapper: BaseJoanieAppWrapper,
|
|
447
440
|
});
|
|
448
441
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { faker } from '@faker-js/faker';
|
|
2
2
|
import { screen, getByText } from '@testing-library/react';
|
|
3
|
-
import { CredentialOrderFactory
|
|
3
|
+
import { CredentialOrderFactory } from 'utils/test/factories/joanie';
|
|
4
4
|
import type { CourseRun, CredentialOrder } from 'types/Joanie';
|
|
5
5
|
import { OrderState } from 'types/Joanie';
|
|
6
6
|
import { render } from 'utils/test/render';
|
|
@@ -15,14 +15,16 @@ jest.mock('../CourseProductCourseRuns', () => ({
|
|
|
15
15
|
describe('CourseRunItem', () => {
|
|
16
16
|
it('does not allow user which purchase the product to enroll to course if order state is not validated', async () => {
|
|
17
17
|
const order: CredentialOrder = CredentialOrderFactory({
|
|
18
|
-
state: faker.helpers.arrayElement([
|
|
18
|
+
state: faker.helpers.arrayElement([
|
|
19
|
+
OrderState.CANCELED,
|
|
20
|
+
OrderState.PENDING,
|
|
21
|
+
OrderState.NO_PAYMENT,
|
|
22
|
+
]),
|
|
19
23
|
}).one();
|
|
20
|
-
const product = ProductFactory().one();
|
|
21
|
-
product.contract_definition = undefined;
|
|
22
24
|
|
|
23
25
|
const targetCourse = order.target_courses[0];
|
|
24
26
|
|
|
25
|
-
render(<CourseRunItem targetCourse={targetCourse} order={order}
|
|
27
|
+
render(<CourseRunItem targetCourse={targetCourse} order={order} />, {
|
|
26
28
|
wrapper: null,
|
|
27
29
|
});
|
|
28
30
|
|
|
@@ -2,8 +2,8 @@ import { useEffect, useRef } from 'react';
|
|
|
2
2
|
import { defineMessages } from 'react-intl';
|
|
3
3
|
import { Priority } from 'types';
|
|
4
4
|
import type * as Joanie from 'types/Joanie';
|
|
5
|
-
import { OrderState, Product } from 'types/Joanie';
|
|
6
5
|
import { CoursesHelper } from 'utils/CoursesHelper';
|
|
6
|
+
import { OrderHelper } from 'utils/OrderHelper';
|
|
7
7
|
import {
|
|
8
8
|
CourseRunList,
|
|
9
9
|
EnrollableCourseRunList,
|
|
@@ -26,13 +26,12 @@ other {Languages:}
|
|
|
26
26
|
interface Props {
|
|
27
27
|
targetCourse: Joanie.TargetCourse;
|
|
28
28
|
order?: Joanie.CredentialOrder;
|
|
29
|
-
product: Product;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
const CourseRunItem = ({ targetCourse, order
|
|
33
|
-
const isEnrollable = order
|
|
31
|
+
const CourseRunItem = ({ targetCourse, order }: Props) => {
|
|
32
|
+
const isEnrollable = OrderHelper.allowEnrollment(order);
|
|
34
33
|
const courseRunEnrollment = isEnrollable
|
|
35
|
-
? CoursesHelper.findActiveCourseEnrollmentInOrder(targetCourse, order)
|
|
34
|
+
? CoursesHelper.findActiveCourseEnrollmentInOrder(targetCourse, order!)
|
|
36
35
|
: undefined;
|
|
37
36
|
const isEnrolled = !!courseRunEnrollment?.is_active;
|
|
38
37
|
|
|
@@ -92,8 +91,7 @@ const CourseRunItem = ({ targetCourse, order, product }: Props) => {
|
|
|
92
91
|
{isEnrollable && !isEnrolled && (
|
|
93
92
|
<EnrollableCourseRunList
|
|
94
93
|
courseRuns={targetCourse.course_runs.filter(isOpenedCourseRun)}
|
|
95
|
-
order={order}
|
|
96
|
-
product={product}
|
|
94
|
+
order={order!}
|
|
97
95
|
/>
|
|
98
96
|
)}
|
|
99
97
|
{isEnrollable && isEnrolled && <EnrolledCourseRun enrollment={courseRunEnrollment} />}
|