Skip to content

Commit

Permalink
feat(mon-pix): add reset password success info
Browse files Browse the repository at this point in the history
  • Loading branch information
bpetetot committed Oct 24, 2024
1 parent 3c31d5e commit 1869d8a
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import PixButton from '@1024pix/pix-ui/components/pix-button';
import PixButtonLink from '@1024pix/pix-ui/components/pix-button-link';
import PixMessage from '@1024pix/pix-ui/components/pix-message';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
Expand All @@ -22,7 +23,7 @@ const HTTP_ERROR_MESSAGES = {
export default class PasswordResetForm extends Component {
@service intl;

@tracked hasSucceeded = false;
@tracked isPasswordResetSucceeded = false;
@tracked isLoading = false;
@tracked validation = new PasswordResetFormValidation(this.intl);
@tracked globalErrorMessage;
Expand All @@ -40,14 +41,14 @@ export default class PasswordResetForm extends Component {

if (!this.validation.isValid) return;

this.hasSucceeded = false;
this.globalErrorMessage = null;
this.isLoading = true;
this.isPasswordResetSucceeded = false;
try {
const { user, temporaryKey } = this.args;
await user.save({ adapterOptions: { updatePassword: true, temporaryKey } });
user.password = null;
this.hasSucceeded = true;
this.isPasswordResetSucceeded = true;
} catch (response) {
const status = get(response, 'errors[0].status');
this.globalErrorMessage = this.intl.t(HTTP_ERROR_MESSAGES[status] || HTTP_ERROR_MESSAGES['default']);
Expand All @@ -57,33 +58,55 @@ export default class PasswordResetForm extends Component {
}

<template>
<form class="password-reset-form" type="submit" {{on "submit" this.handleResetPassword}}>
{{#if this.globalErrorMessage}}
<PixMessage @type="error" @withIcon={{true}} role="alert">
{{this.globalErrorMessage}}
</PixMessage>
{{/if}}
{{#if this.isPasswordResetSucceeded}}
<PasswordResetSucceededInfo />
{{else}}
<form class="password-reset-form" type="submit" {{on "submit" this.handleResetPassword}}>
{{#if this.globalErrorMessage}}
<PixMessage @type="error" @withIcon={{true}} role="alert">
{{this.globalErrorMessage}}
</PixMessage>
{{/if}}

<p class="password-reset-form__mandatory-fields-message">
{{t "common.form.mandatory-all-fields"}}
</p>
<p class="password-reset-form__mandatory-fields-message">
{{t "common.form.mandatory-all-fields"}}
</p>

<NewPasswordInput
@id="password"
class="password-reset-form__password-input"
name="password"
{{on "change" this.handleInputChange}}
@validationStatus={{this.validation.password.status}}
@errorMessage={{this.validation.password.errorMessage}}
@rules={{PASSWORD_RULES}}
required
>
<:label>{{t "components.authentication.password-reset-form.fields.password.label"}}</:label>
</NewPasswordInput>
<NewPasswordInput
@id="password"
class="password-reset-form__password-input"
name="password"
{{on "change" this.handleInputChange}}
@validationStatus={{this.validation.password.status}}
@errorMessage={{this.validation.password.errorMessage}}
@rules={{PASSWORD_RULES}}
required
>
<:label>{{t "components.authentication.password-reset-form.fields.password.label"}}</:label>
</NewPasswordInput>

<PixButton class="password-reset-form__submit-button" @isLoading={{this.isLoading}} @size="large" @type="submit">
{{t "components.authentication.password-reset-form.actions.submit"}}
</PixButton>
</form>
<PixButton
class="password-reset-form__submit-button"
@isLoading={{this.isLoading}}
@size="large"
@type="submit"
>
{{t "components.authentication.password-reset-form.actions.submit"}}
</PixButton>
</form>
{{/if}}
</template>
}

const PasswordResetSucceededInfo = <template>
<div class="password-reset-succeeded-info" role="alert">
<img src="/images/success-check.svg" alt="" />
<h2 class="password-reset-succeeded-info__heading">
{{t "components.authentication.password-reset-form.success-info.message"}}
</h2>
</div>

<PixButtonLink @route="authentication.login" @size="large">
{{t "components.authentication.password-reset-form.actions.login"}}
</PixButtonLink>
</template>;
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,19 @@
width: 100%;
}
}

.password-reset-succeeded-info {
margin-top: var(--pix-spacing-6x);
margin-bottom: var(--pix-spacing-4x);
padding: var(--pix-spacing-6x);
color: var(--pix-neutral-900);
text-align: center;
background-color: var(--pix-success-50);
border-radius: var(--pix-spacing-4x);

&__heading {
@extend %pix-title-xs;

margin-top: var(--pix-spacing-8x);
}
}
6 changes: 6 additions & 0 deletions mon-pix/public/images/success-check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import sinon from 'sinon';
import setupIntlRenderingTest from '../../../../helpers/setup-intl-rendering';

const I18N_KEYS = {
loginButtonLink: 'components.authentication.password-reset-form.actions.login',
passwordInputErrorMessage: 'components.authentication.password-reset-form.fields.password.label',
passwordInputLabel: 'components.authentication.password-reset-form.fields.password.label',
mandatoryFieldsMessage: 'common.form.mandatory-all-fields',
resetPasswordButton: 'components.authentication.password-reset-form.actions.submit',
resetPasswordSuccess: 'components.authentication.password-reset-form.success-info.message',
};

const I18N_ERROR_KEYS = {
Expand Down Expand Up @@ -42,22 +44,28 @@ module('Integration | Component | Authentication | PasswordResetForm | PasswordR

test('resets password successfully', async function (assert) {
// given
const user = { save: sinon.stub().resolves() };
const validPassword = 'Pix12345';
const user = { save: sinon.stub() };
const temporaryKey = 'temporaryKey';

// when
await render(<template><PasswordResetForm @temporaryKey={{temporaryKey}} @user={{user}} /></template>);
const screen = await render(
<template><PasswordResetForm @temporaryKey={{temporaryKey}} @user={{user}} /></template>,
);

await fillByLabel(t(I18N_KEYS.passwordInputLabel), validPassword);
await clickByName(t(I18N_KEYS.resetPasswordButton));

// then
const userSavePayload = {
adapterOptions: { updatePassword: true, temporaryKey },
};
assert.strictEqual(user.password, null);
const userSavePayload = { adapterOptions: { updatePassword: true, temporaryKey } };
sinon.assert.calledWith(user.save, userSavePayload);
assert.strictEqual(user.password, null);

const successInfo = screen.getByRole('heading', { name: t(I18N_KEYS.resetPasswordSuccess) });
assert.dom(successInfo).exists();

const loginLinkElement = screen.getByRole('link', { name: t(I18N_KEYS.loginButtonLink) });
assert.dom(loginLinkElement).hasAttribute('href', '/connexion');
});

module('when there is a validationError on the password field', function () {
Expand Down
6 changes: 5 additions & 1 deletion mon-pix/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@
},
"password-reset-form": {
"actions": {
"submit": "Reset my password"
"submit": "Reset my password",
"login": "Log in"
},
"errors": {
"expired-demand": "We’re sorry, but your request to reset your password has already been used or has expired. Please start again.",
Expand All @@ -188,6 +189,9 @@
"password": {
"label": "Please enter your new password"
}
},
"success-info": {
"message": "Your password has been successfully reset."
}
},
"signup-form": {
Expand Down
6 changes: 5 additions & 1 deletion mon-pix/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@
},
"password-reset-form": {
"actions": {
"submit": "Reset my password"
"submit": "Reset my password",
"login": "Me conecto"
},
"errors": {
"expired-demand": "Lo sentimos, pero tu solicitud de restablecimiento de contraseña ya ha sido utilizada o ha caducado. Por favor, vuelve a intentarlo.",
Expand All @@ -157,6 +158,9 @@
"password": {
"label": "Please enter your new password"
}
},
"success-info": {
"message": "Your password has been successfully reset."
}
},
"signup-form": {
Expand Down
6 changes: 5 additions & 1 deletion mon-pix/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@
},
"password-reset-form": {
"actions": {
"submit": "Je réinitialise mon mot de passe"
"submit": "Je réinitialise mon mot de passe",
"login": "Je me connecte"
},
"errors": {
"expired-demand": "Nous sommes désolés, mais votre demande de réinitialisation de mot de passe a déjà été utilisée ou est expirée. Merci de recommencer.",
Expand All @@ -188,6 +189,9 @@
"password": {
"label": "Saisissez votre nouveau mot de passe"
}
},
"success-info": {
"message": "Votre mot de passe a bien été réinitialisé."
}
},
"signup-form": {
Expand Down
6 changes: 5 additions & 1 deletion mon-pix/translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@
},
"password-reset-form": {
"actions": {
"submit": "Reset my password"
"submit": "Reset my password",
"login": "Ik ben online."
},
"errors": {
"expired-demand": "Het spijt ons, maar uw wachtwoordaanvraag is al gebruikt of verlopen. Probeer het opnieuw.",
Expand All @@ -157,6 +158,9 @@
"password": {
"label": "Please enter your new password"
}
},
"success-info": {
"message": "Your password has been successfully reset."
}
},
"signup-form": {
Expand Down

0 comments on commit 1869d8a

Please sign in to comment.