Skip to content

Commit

Permalink
✨(frontend) display specific message to waive withdrawal right
Browse files Browse the repository at this point in the history
According to the product type, messages related to the withdrawal waiver
checkbox must be adapted.
  • Loading branch information
jbpenrath committed Nov 20, 2024
1 parent 4c3e2bd commit d069a60
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Versioning](https://semver.org/spec/v2.0.0.html).

- Changed `multiple-columns` CSS component so its columns include a padding
- Changed `CKEditorPlugin` for new field `variant` to choose a variant style;
- Customize withdrawal waiver checkbox messages according to the product type

## [2.30.0] - 2024-10-16

Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,72 @@
import { Alert, Checkbox, VariantType } from '@openfun/cunningham-react';
import { useCallback, useEffect, useState } from 'react';
import { defineMessages, FormattedMessage } from 'react-intl/lib';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { useSaleTunnelContext } from 'components/SaleTunnel/GenericSaleTunnel';
import { ProductType } from 'types/Joanie';

const messages = defineMessages({
waiveCheckboxLabel: {
defaultMessage: 'By checking this box:',
description: 'Label of the checkbox to waive the withdrawal right.',
id: 'components.SaleTunnel.WithdrawRightCheckbox.waiveCheckboxLabel',
},
});

const credentialProductMessages = defineMessages({
waiveCheckboxExplanation: {
defaultMessage:
'This training will start before the end of your withdrawal period. You must waive it to subscribe.',
'The training program you wish to enroll in begins before the end of the 14-day withdrawal period mentioned in Article L221-18 of the French Consumer Code. You must check the box below to proceed with your registration.',
description: 'Text to explain why the user has to waive to its withdrawal right.',
id: 'components.SaleTunnel.WithdrawRightCheckbox.waiverLabel',
id: 'components.SaleTunnel.WithdrawRightCheckbox.credential.waiverLabel',
},
waiveCheckboxLabel: {
defaultMessage: 'I waive my right of withdrawal',
description: 'Label of the checkbox to waive the withdrawal right.',
id: 'components.SaleTunnel.WithdrawRightCheckbox.waiveCheckboxLabel',
waiveCheckboxHelperClause1: {
defaultMessage:
'I acknowledge that I have expressly requested to begin the training before the expiration date of the withdrawal period.',
description: 'First clause item for the waiver checkbox.',
id: 'components.SaleTunnel.WithdrawRightCheckbox.credential.waiveCheckboxHelperClause1',
},
waiveCheckboxHelperClause2: {
defaultMessage:
'I expressly waive my right of withdrawal in order to begin the training before the expiration of the withdrawal period.',
description: 'Second clause item for the waiver checkbox.',
id: 'components.SaleTunnel.WithdrawRightCheckbox.credential.waiveCheckboxHelperClause2',
},
});

const certificateProductMessages = defineMessages({
waiveCheckboxExplanation: {
defaultMessage:
'If the examination period begins before the end of the 14-day withdrawal period mentioned in Article L221-18 of the French Consumer Code, you must check the box below to proceed with your registration.',
description: 'Text to explain why the user has to waive to its withdrawal right.',
id: 'components.SaleTunnel.WithdrawRightCheckbox.certificate.waiverLabel',
},
waiveCheckboxHelperClause1: {
defaultMessage:
'I acknowledge that I have expressly requested my registration for the examination before the expiration date of the withdrawal period.',
description: 'First clause item for the waiver checkbox.',
id: 'components.SaleTunnel.WithdrawRightCheckbox.certificate.waiveCheckboxHelperClause1',
},
waiveCheckboxHelperClause2: {
defaultMessage:
'I expressly waive my right of withdrawal in order to register for the examination before the expiration of the withdrawal period.',
description: 'Second clause item for the waiver checkbox.',
id: 'components.SaleTunnel.WithdrawRightCheckbox.certificate.waiveCheckboxHelperClause2',
},
});

const WithdrawRightCheckbox = () => {
const {
props: { isWithdrawable },
props: { isWithdrawable, product },
registerSubmitCallback,
unregisterSubmitCallback,
hasWaivedWithdrawalRight,
setHasWaivedWithdrawalRight,
} = useSaleTunnelContext();
const intl = useIntl();
const clauseMessages =
product.type === ProductType.CERTIFICATE
? certificateProductMessages
: credentialProductMessages;
const [hasErrorState, setHasError] = useState(false);
const setError = useCallback(async () => {
setHasError(!isWithdrawable && !hasWaivedWithdrawalRight);
Expand All @@ -44,13 +86,17 @@ const WithdrawRightCheckbox = () => {
data-testid="withdraw-right-checkbox"
>
<Alert type={hasErrorState ? VariantType.ERROR : VariantType.WARNING} className="mb-s">
<FormattedMessage {...messages.waiveCheckboxExplanation} />
<FormattedMessage {...clauseMessages.waiveCheckboxExplanation} />
</Alert>
<Checkbox
className="waiveCheckbox__input"
label={<FormattedMessage {...messages.waiveCheckboxLabel} />}
label={intl.formatMessage(messages.waiveCheckboxLabel)}
checked={hasWaivedWithdrawalRight}
onChange={(e) => setHasWaivedWithdrawalRight(e.target.checked)}
textItems={[
intl.formatMessage(clauseMessages.waiveCheckboxHelperClause1),
intl.formatMessage(clauseMessages.waiveCheckboxHelperClause2),
]}
/>
</section>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ describe('SaleTunnel', () => {
/**
* Make sure the checkbox to waive withdrawal right is displayed
*/
const $waiveCheckbox = screen.getByLabelText('I waive my right of withdrawal');
const $waiveCheckbox = within(screen.getByTestId('withdraw-right-checkbox')).getByRole(
'checkbox',
);

/**
* Subscribe
Expand Down
37 changes: 37 additions & 0 deletions src/frontend/js/components/SaleTunnel/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -493,4 +493,41 @@ describe.each([

expect(screen.queryByTestId('withdraw-right-checkbox')).toBeNull();
});

it('should show a specific checkbox to waive withdrawal right according to the product type', async () => {
const product = ProductFactory().one();
const schedule = PaymentInstallmentFactory().many(2);
fetchMock
.get(
`https://joanie.endpoint/api/v1.0/orders/?${queryString.stringify(getFetchOrderQueryParams(product))}`,
[],
)
.get(
`https://joanie.endpoint/api/v1.0/courses/${course.code}/products/${product.id}/payment-schedule/`,
schedule,
);

render(<Wrapper product={product} isWithdrawable={false} />, {
queryOptions: { client: createTestQueryClient({ user: richieUser }) },
});

screen.getByTestId('withdraw-right-checkbox');

const expectedMessages =
productType === ProductType.CERTIFICATE
? [
'If the examination period begins before the end of the 14-day withdrawal period mentioned in Article L221-18 of the French Consumer Code, you must check the box below to proceed with your registration.',
'I acknowledge that I have expressly requested my registration for the examination before the expiration date of the withdrawal period.',
'I expressly waive my right of withdrawal in order to register for the examination before the expiration of the withdrawal period.',
]
: [
'The training program you wish to enroll in begins before the end of the 14-day withdrawal period mentioned in Article L221-18 of the French Consumer Code. You must check the box below to proceed with your registration.',
'I acknowledge that I have expressly requested to begin the training before the expiration date of the withdrawal period.',
'I expressly waive my right of withdrawal in order to begin the training before the expiration of the withdrawal period.',
];

expectedMessages.forEach((message) => {
screen.getByText(message);
});
});
});

0 comments on commit d069a60

Please sign in to comment.