Skip to content

Commit

Permalink
[FEATURE] Ajout du nouveau formulaire de connexion Pix App (PIX-14002)
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Sep 30, 2024
2 parents 01cea95 + c4ed980 commit 65acc35
Show file tree
Hide file tree
Showing 16 changed files with 679 additions and 146 deletions.
21 changes: 13 additions & 8 deletions mon-pix/app/components/authentication-layout/index.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ import Header from './header';

<template>
<section class="authentication-layout">
<img
class="authentication-layout__image"
alt=""
role="presentation"
src="/images/illustrations/authentication.svg"
/>
<div class="authentication-layout__side" role="presentation">
<div class="authentication-layout__image">
<img alt="" src="/images/illustrations/authentication.svg" />
</div>
</div>

<div class="authentication-layout__main">
<Header>{{yield to="header"}}</Header>
{{yield to="content"}}
<Header>
{{yield to="header"}}
</Header>

<main ...attributes>
{{yield to="content"}}
</main>

<Footer />
</div>
</section>
Expand Down
63 changes: 45 additions & 18 deletions mon-pix/app/components/authentication-layout/index.scss
Original file line number Diff line number Diff line change
@@ -1,36 +1,54 @@
.authentication-layout {
display: flex;
gap: 8rem;
height: 100vh;
width: 100vw;
min-height: 100vh;
background-color: var(--pix-neutral-0);

.authentication-layout__image {
.authentication-layout__side {
display: none;
}

.authentication-layout__main {
display: flex;
flex-direction: column;
width: 100%;
margin: var(--pix-spacing-4x);
padding: var(--pix-spacing-4x);
}
}

@include device-is('desktop') {
.authentication-layout {
height: auto;
margin: var(--pix-spacing-6x) var(--pix-spacing-4x);

.authentication-layout__image {
display: block;
width: 31rem;
padding: var(--pix-spacing-6x);
background: var(--pix-primary-500);
border-radius: 24px;
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: var(--pix-spacing-6x);
padding: var(--pix-spacing-6x);

.authentication-layout__side {
position: fixed;
top: var(--pix-spacing-6x);
z-index: 0;
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: var(--pix-spacing-6x);
width: calc(100% - 2 * var(--pix-spacing-6x));
height: calc(100% - 2 * var(--pix-spacing-6x));
text-align: center;

.authentication-layout__image {
grid-column: 1 / span 5;
padding: var(--pix-spacing-4x);
background: var(--pix-primary-500);
border-radius: var(--pix-spacing-6x);

> img {
height: 100%;
}
}
}

.authentication-layout__main {
width: 31rem;
margin: 0;
z-index: 10;
grid-column: 7 / span 5;
padding: 0;
}
}
}
Expand All @@ -42,15 +60,24 @@
justify-content: space-between;

.authentication-layout-header__pix-logo {
width: 5rem;
width: 5rem;
}
}

.authentication-layout-footer {
margin-top: auto;
width: 100%;
margin-top: var(--pix-spacing-10x);

.footer-container-content__navigation {
margin-top: var(--pix-spacing-2x);
margin-left: 0;
line-height: 1rem;

a {
@extend %pix-body-xs;

text-decoration: underline;
}
}

.footer-navigation__item{
Expand Down
5 changes: 0 additions & 5 deletions mon-pix/app/components/authentication/login-form.gjs

This file was deleted.

167 changes: 167 additions & 0 deletions mon-pix/app/components/authentication/signin-form.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import PixButton from '@1024pix/pix-ui/components/pix-button';
import PixInput from '@1024pix/pix-ui/components/pix-input';
import PixInputPassword from '@1024pix/pix-ui/components/pix-input-password';
import PixMessage from '@1024pix/pix-ui/components/pix-message';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import { LinkTo } from '@ember/routing';
import { service } from '@ember/service';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { t } from 'ember-intl';
import get from 'lodash/get';
import ENV from 'mon-pix/config/environment';

export default class SigninForm extends Component {
@service url;
@service session;
@service store;
@service router;

@tracked login = null;
@tracked password = null;
@tracked error = null;
@tracked isLoading = false;

@action
async signin(event) {
if (event) event.preventDefault();
this.isLoading = true;

try {
await this.session.authenticateUser(this.login, this.password);
} catch (responseError) {
this._handleApiError(responseError);
} finally {
this.isLoading = false;
}
}

get isFormDisabled() {
return !this.login || !this.password;
}

@action
updateLogin(event) {
this.login = event.target.value?.trim();
}

@action
updatePassword(event) {
this.password = event.target.value?.trim();
}

async _handleApiError(responseError) {
const errors = get(responseError, 'responseJSON.errors');
const error = Array.isArray(errors) && errors.length > 0 && errors[0];

switch (error?.code) {
case 'INVALID_LOCALE_FORMAT':
this.error = {
key: 'pages.sign-up.errors.invalid-locale-format',
values: { invalidLocale: error.meta.locale },
};
break;
case 'LOCALE_NOT_SUPPORTED':
this.error = {
key: 'pages.sign-up.errors.locale-not-supported',
values: { localeNotSupported: error.meta.locale },
};
break;
case 'SHOULD_CHANGE_PASSWORD': {
const passwordResetToken = error.meta;
await this._updateExpiredPassword(passwordResetToken);
break;
}
case 'USER_IS_TEMPORARY_BLOCKED':
this.error = {
key: ENV.APP.API_ERROR_MESSAGES.USER_IS_TEMPORARY_BLOCKED.I18N_KEY,
values: {
url: '/mot-de-passe-oublie',
htmlSafe: true,
},
};
break;
case 'USER_IS_BLOCKED':
this.error = {
key: ENV.APP.API_ERROR_MESSAGES.USER_IS_BLOCKED.I18N_KEY,
values: {
url: 'https://support.pix.org/support/tickets/new',
htmlSafe: true,
},
};
break;
default:
this.error = this._getI18nKeyByStatus(responseError.status);
}
}

async _updateExpiredPassword(passwordResetToken) {
this.store.createRecord('reset-expired-password-demand', { passwordResetToken });
return this.router.replaceWith('update-expired-password');
}

_getI18nKeyByStatus(status) {
switch (status) {
case 400:
return { key: ENV.APP.API_ERROR_MESSAGES.BAD_REQUEST.I18N_KEY };
case 401:
return { key: ENV.APP.API_ERROR_MESSAGES.LOGIN_UNAUTHORIZED.I18N_KEY };
case 422:
return { key: ENV.APP.API_ERROR_MESSAGES.BAD_REQUEST.I18N_KEY };
case 504:
return { key: ENV.APP.API_ERROR_MESSAGES.GATEWAY_TIMEOUT.I18N_KEY };
default:
return { key: 'pages.sign-in.error.unexpected', values: { htmlSafe: true } };
}
}

<template>
<form {{on "submit" this.signin}} class="signin-form">
{{#if this.error}}
<PixMessage id="sign-in-error-message" @type="error" @withIcon="true" role="alert">
{{t this.error.key this.error.values}}
</PixMessage>
{{/if}}

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

<fieldset>
<legend class="sr-only">{{t "pages.sign-in.fields.legend"}}</legend>

<PixInput
@id="login"
name="login"
{{on "input" this.updateLogin}}
placeholder={{t "pages.sign-in.fields.login.placeholder"}}
autocomplete="email"
required
>
<:label>{{t "pages.sign-in.fields.login.label"}}</:label>
</PixInput>

<div class="signin-form__password">
<PixInputPassword
@id="password"
name="password"
{{on "input" this.updatePassword}}
autocomplete="current-password"
required
>
<:label>{{t "pages.sign-in.fields.password.label"}}</:label>
</PixInputPassword>

<LinkTo @route="password-reset-demand" class="link link--grey pix-body-s">
{{t "pages.sign-in.forgotten-password"}}
</LinkTo>
</div>
</fieldset>

<PixButton @type="submit" @isLoading={{this.isLoading}} @isDisabled={{this.isFormDisabled}} @size="large">
{{t "pages.sign-in.actions.submit"}}
</PixButton>
</form>
</template>
}
37 changes: 37 additions & 0 deletions mon-pix/app/components/authentication/signin-form.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.signin-form {
display: flex;
flex-direction: column;
gap: var(--pix-spacing-4x);

input {
width: 100%;
padding: var(--pix-spacing-3x);
}

a {
text-decoration: underline;
}

fieldset {
display: flex;
flex-direction: column;
gap: var(--pix-spacing-4x);
}

&__mandatory-fields-message {
@extend %pix-body-xs;

color: var(--pix-neutral-500);
}

&__password {
display: flex;
flex-direction: column;
gap: var(--pix-spacing-2x);
align-items: end;

.pix-input-password {
width: 100%;
}
}
}
2 changes: 1 addition & 1 deletion mon-pix/app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ of an adaptative/mobile-first approach — refactoring is welcome here */

/* Styles for colocated components */
@import 'authentication-layout';
@import 'authentication/signin-form';

/* pages */
@import 'pages/assessment-results';
Expand All @@ -150,7 +151,6 @@ of an adaptative/mobile-first approach — refactoring is welcome here */
@import 'pages/fill-in-participant-external-id';
@import 'pages/inscription';
@import 'pages/join-restricted-campaign';
@import 'pages/authentication';
@import 'pages/module';
@import 'pages/module-preview';
@import 'pages/student-sco';
Expand Down
10 changes: 0 additions & 10 deletions mon-pix/app/styles/pages/_authentication.scss

This file was deleted.

8 changes: 8 additions & 0 deletions mon-pix/app/styles/pages/_sign-form.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.signin-page-layout {
display: flex;
flex-direction: column;
gap: var(--pix-spacing-4x);
padding-top: var(--pix-spacing-6x);
}

// Legacy signin page styles
.sign-form-page {
display: flex;
align-items: center;
Expand Down
Loading

0 comments on commit 65acc35

Please sign in to comment.