richie-education 3.2.2-dev56 → 3.2.2-dev60

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.
@@ -134,7 +134,10 @@ const OpenEdxFullNameForm = () => {
134
134
  return (
135
135
  <FormProvider {...form}>
136
136
  <Form name="openedx-fullname-form" noValidate>
137
- <Alert type={formState.errors.name?.message ? VariantType.ERROR : VariantType.WARNING}>
137
+ <Alert
138
+ className="mt-s"
139
+ type={formState.errors.name?.message ? VariantType.ERROR : VariantType.WARNING}
140
+ >
138
141
  <FormattedMessage {...messages.fullNameInputDescription} />
139
142
  </Alert>
140
143
  <Input
@@ -268,7 +268,7 @@ const BatchOrderForm = () => {
268
268
  }
269
269
  }}
270
270
  hidden={activeStep === 0}
271
- color="secondary"
271
+ color="tertiary"
272
272
  >
273
273
  <FormattedMessage {...messages.previousButton} />
274
274
  </Button>
@@ -112,6 +112,16 @@ const messages = defineMessages({
112
112
  description: 'Discount description',
113
113
  defaultMessage: 'Discount applied',
114
114
  },
115
+ noPaymentSchedule: {
116
+ id: 'components.SaleTunnel.Information.noPaymentSchedule',
117
+ description: 'Message displayed representing the payment schedule when the order is free.',
118
+ defaultMessage: 'No payment required. This order is fully covered.',
119
+ },
120
+ noBillingInformation: {
121
+ id: 'components.SaleTunnel.Information.noBillingInformation',
122
+ description: 'Message displayed when the order is part of a batch order',
123
+ defaultMessage: 'No billing information required. This order is covered by your organization.',
124
+ },
115
125
  });
116
126
 
117
127
  export const SaleTunnelInformationSingular = () => {
@@ -162,14 +172,6 @@ export const SaleTunnelInformationSingular = () => {
162
172
 
163
173
  return (
164
174
  <>
165
- <div>
166
- <Voucher
167
- discount={discount}
168
- voucherError={voucherError}
169
- setVoucherError={setVoucherError}
170
- />
171
- <Total price={price} discountedPrice={discountedPrice} />
172
- </div>
173
175
  {needsPayment && (
174
176
  <div>
175
177
  <h3 className="block-title mb-t">
@@ -178,7 +180,6 @@ export const SaleTunnelInformationSingular = () => {
178
180
  <div className="description mb-s">
179
181
  <FormattedMessage {...messages.description} />
180
182
  </div>
181
- <AddressSelector />
182
183
  {isKeycloakBackend ? (
183
184
  <KeycloakAccountEdit />
184
185
  ) : (
@@ -189,10 +190,38 @@ export const SaleTunnelInformationSingular = () => {
189
190
  </div>
190
191
  </>
191
192
  )}
193
+ <AddressSelector />
194
+ </div>
195
+ )}
196
+ {!needsPayment && (
197
+ <div>
198
+ <h3 className="block-title">
199
+ <FormattedMessage {...messages.title} />
200
+ </h3>
201
+ <Alert type={VariantType.NEUTRAL}>
202
+ <FormattedMessage {...messages.noBillingInformation} />
203
+ </Alert>
192
204
  </div>
193
205
  )}
194
206
  <div>
195
- {showPaymentSchedule && <PaymentScheduleBlock schedule={schedule} />}
207
+ {showPaymentSchedule ? (
208
+ <PaymentScheduleBlock schedule={schedule!} />
209
+ ) : (
210
+ <div>
211
+ <h4 className="block-title">
212
+ <FormattedMessage {...messages.paymentSchedule} />
213
+ </h4>
214
+ <Alert type={VariantType.NEUTRAL}>
215
+ <FormattedMessage {...messages.noPaymentSchedule} />
216
+ </Alert>
217
+ </div>
218
+ )}
219
+ <Voucher
220
+ discount={discount}
221
+ voucherError={voucherError}
222
+ setVoucherError={setVoucherError}
223
+ />
224
+ <Total price={price} discountedPrice={discountedPrice} />
196
225
  {needsPayment && <WithdrawRightCheckbox />}
197
226
  </div>
198
227
  </>
@@ -216,7 +216,9 @@ export const StepContent = ({
216
216
  return (
217
217
  <div className="step-content">
218
218
  <div className="step organization" hidden={activeStep !== 0}>
219
- <FormattedMessage {...messages.stepCompanyTitle} />
219
+ <h4 className="title">
220
+ <FormattedMessage {...messages.stepCompanyTitle} />
221
+ </h4>
220
222
  <Input
221
223
  className="field"
222
224
  label={intl.formatMessage(messages.companyName)}
@@ -294,7 +296,9 @@ export const StepContent = ({
294
296
  </div>
295
297
  {otherBillingAddress && (
296
298
  <div className="step billing" hidden={activeStep !== 0}>
297
- <FormattedMessage {...messages.stepBillingTitle} />
299
+ <h4 className="title">
300
+ <FormattedMessage {...messages.stepBillingTitle} />
301
+ </h4>
298
302
  <Input
299
303
  className="field"
300
304
  {...register('billing_address.contact_name')}
@@ -347,7 +351,9 @@ export const StepContent = ({
347
351
  </div>
348
352
  )}
349
353
  <div className="step admin" hidden={activeStep !== 1}>
350
- <FormattedMessage {...messages.stepAdminTitle} />
354
+ <h4 className="title">
355
+ <FormattedMessage {...messages.stepAdminTitle} />
356
+ </h4>
351
357
  <Input
352
358
  className="field"
353
359
  {...register('administrative_lastname')}
@@ -411,7 +417,9 @@ export const StepContent = ({
411
417
  />
412
418
  </div>
413
419
  <div className="step signatory" hidden={activeStep !== 2}>
414
- <FormattedMessage {...messages.stepSignatoryTitle} />
420
+ <h4 className="title">
421
+ <FormattedMessage {...messages.stepSignatoryTitle} />
422
+ </h4>
415
423
  <Input
416
424
  className="field"
417
425
  {...register('signatory_lastname')}
@@ -467,7 +475,9 @@ export const StepContent = ({
467
475
  />
468
476
  </div>
469
477
  <div className="step seats" hidden={activeStep !== 3}>
470
- <FormattedMessage {...messages.stepParticipantsTitle} />
478
+ <h4 className="title">
479
+ <FormattedMessage {...messages.stepParticipantsTitle} />
480
+ </h4>
471
481
  <Input
472
482
  className="field"
473
483
  type="number"
@@ -479,7 +489,9 @@ export const StepContent = ({
479
489
  />
480
490
  </div>
481
491
  <div className="step financing" hidden={activeStep !== 4}>
482
- <FormattedMessage {...messages.stepFinancingTitle} />
492
+ <h4 className="title">
493
+ <FormattedMessage {...messages.stepFinancingTitle} />
494
+ </h4>
483
495
  <RadioGroup fullWidth={true} className="payment-block">
484
496
  <Radio
485
497
  {...register('payment_method')}
@@ -512,7 +524,10 @@ export const StepContent = ({
512
524
  }
513
525
  />
514
526
  </RadioGroup>
515
- <FormattedMessage {...messages.fundingEntity} />
527
+
528
+ <h4 className="title">
529
+ <FormattedMessage {...messages.fundingEntity} />
530
+ </h4>
516
531
  <div className="organism-block">
517
532
  <Input
518
533
  {...register('funding_entity')}
@@ -524,7 +539,10 @@ export const StepContent = ({
524
539
  label={intl.formatMessage(messages.fundingEntityAmount)}
525
540
  />
526
541
  </div>
527
- <FormattedMessage {...messages.recommandation} />
542
+
543
+ <h4 className="title">
544
+ <FormattedMessage {...messages.recommandation} />
545
+ </h4>
528
546
  <Select
529
547
  label={intl.formatMessage(messages.participatingOrganisations)}
530
548
  clearable
@@ -44,11 +44,11 @@ export const SaleTunnelInformation = () => {
44
44
  ];
45
45
  const [purchaseType, setPurchaseType] = useState(FormType.SINGULAR);
46
46
 
47
+ const isCertificate = productType === ProductType.CERTIFICATE;
48
+
47
49
  return (
48
50
  <div className="sale-tunnel__main__column sale-tunnel__information">
49
- {productType === ProductType.CERTIFICATE ? (
50
- <SaleTunnelInformationSingular />
51
- ) : (
51
+ {!isCertificate && (
52
52
  <div>
53
53
  <h3 className="block-title mb-t">
54
54
  <FormattedMessage {...messages.purchaseTypeTitle} />
@@ -65,10 +65,10 @@ export const SaleTunnelInformation = () => {
65
65
  setSchedule(undefined);
66
66
  }}
67
67
  />
68
- {purchaseType === FormType.SINGULAR && <SaleTunnelInformationSingular />}
69
- {purchaseType === FormType.GROUP && <SaleTunnelInformationGroup />}
70
68
  </div>
71
69
  )}
70
+ {purchaseType === FormType.SINGULAR && <SaleTunnelInformationSingular />}
71
+ {purchaseType === FormType.GROUP && !isCertificate && <SaleTunnelInformationGroup />}
72
72
  </div>
73
73
  );
74
74
  };
@@ -157,6 +157,13 @@
157
157
  align-items: center;
158
158
  margin: 1rem 0;
159
159
  gap: 0.5rem;
160
+
161
+ .title {
162
+ font-weight: var(--c--theme--font--weights--bold);
163
+ font-size: var(--c--theme--font--sizes--l);
164
+ margin: 0 0 0.5rem;
165
+ }
166
+
160
167
  .field {
161
168
  width: 90%;
162
169
  }
@@ -169,7 +176,7 @@
169
176
  }
170
177
  .payment-block {
171
178
  & > div {
172
- margin: 1rem 0;
179
+ margin: 0 0 1rem;
173
180
  flex-direction: row;
174
181
  }
175
182
  }
@@ -374,7 +374,8 @@ describe('SaleTunnel', () => {
374
374
  );
375
375
  await user.type(screen.getByLabelText('Voucher code'), 'DISCOUNT100');
376
376
  await user.click(screen.getByRole('button', { name: 'Validate' }));
377
- expect(screen.queryByRole('heading', { name: 'Payment schedule' })).not.toBeInTheDocument();
377
+ await screen.findByRole('heading', { level: 4, name: 'Payment schedule' });
378
+ screen.getByText('No payment required. This order is fully covered.');
378
379
  await screen.findByTestId('sale-tunnel__total__amount');
379
380
  const $totalAmountVoucher = screen.getByTestId('sale-tunnel__total__amount');
380
381
  expect($totalAmountVoucher).toHaveTextContent(
@@ -484,7 +484,8 @@ describe.each([
484
484
  });
485
485
  });
486
486
  } else {
487
- expect(screen.queryByRole('heading', { level: 4, name: 'Payment schedule' })).toBeNull();
487
+ await screen.findByRole('heading', { level: 4, name: 'Payment schedule' });
488
+ screen.getByText('No payment required. This order is fully covered.');
488
489
  expect(screen.queryByRole('table')).toBeNull();
489
490
  }
490
491
 
@@ -623,7 +624,8 @@ describe.each([
623
624
  });
624
625
  });
625
626
  } else {
626
- expect(screen.queryByRole('heading', { level: 4, name: 'Payment schedule' })).toBeNull();
627
+ await screen.findByRole('heading', { level: 4, name: 'Payment schedule' });
628
+ screen.getByText('No payment required. This order is fully covered.');
627
629
  expect(screen.queryByRole('table')).toBeNull();
628
630
  }
629
631
 
@@ -830,6 +832,16 @@ describe.each([
830
832
  ).not.toBeInTheDocument(),
831
833
  );
832
834
  expect(await screen.queryByTestId('withdraw-right-checkbox')).not.toBeInTheDocument();
835
+
836
+ expect(
837
+ screen.getByText(
838
+ 'No billing information required. This order is covered by your organization.',
839
+ ),
840
+ ).toBeInTheDocument();
841
+ expect(screen.getByRole('heading', { level: 4, name: 'Payment schedule' })).toBeInTheDocument();
842
+ expect(
843
+ screen.getByText('No payment required. This order is fully covered.'),
844
+ ).toBeInTheDocument();
833
845
  });
834
846
 
835
847
  it('should hide voucher code input when one is already used', async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "richie-education",
3
- "version": "3.2.2-dev56",
3
+ "version": "3.2.2-dev60",
4
4
  "description": "A CMS to build learning portals for Open Education",
5
5
  "main": "sandbox/manage.py",
6
6
  "scripts": {
@@ -157,7 +157,7 @@
157
157
  "workerDirectory": "../richie/static/richie/js"
158
158
  },
159
159
  "volta": {
160
- "node": "20.11.0",
160
+ "node": "20.19.0",
161
161
  "yarn": "1.22.22"
162
162
  },
163
163
  "devDependencies": {