diff --git a/mon-pix/app/components/authentication/other-authentication-providers.gjs b/mon-pix/app/components/authentication/other-authentication-providers.gjs new file mode 100644 index 00000000000..0083f875a71 --- /dev/null +++ b/mon-pix/app/components/authentication/other-authentication-providers.gjs @@ -0,0 +1,57 @@ +import PixButtonLink from '@1024pix/pix-ui/components/pix-button-link'; +import { service } from '@ember/service'; +import Component from '@glimmer/component'; +import { t } from 'ember-intl'; + +export default class OtherAuthenticationProviders extends Component { + @service oidcIdentityProviders; + @service router; + + +} diff --git a/mon-pix/app/components/authentication/other-authentication-providers.scss b/mon-pix/app/components/authentication/other-authentication-providers.scss new file mode 100644 index 00000000000..7dc7a34b734 --- /dev/null +++ b/mon-pix/app/components/authentication/other-authentication-providers.scss @@ -0,0 +1,36 @@ +.authentication-other-authentication-providers-section { + display: flex; + flex-direction: column; + gap: var(--pix-spacing-4x); + + &__heading { + display: flex; + gap: var(--pix-spacing-6x); + margin-top: var(--pix-spacing-10x); + margin-bottom: var(--pix-spacing-10x); + color: var(--pix-neutral-500); + } + + &__heading::before, + &__heading::after { + flex: 1 1; + margin: auto; + border-bottom: 1px solid var(--pix-neutral-100); + content: ""; + } + + &__button-link { + border: 1px solid; + } + + &__featured-identity-provider-logo { + width: var(--pix-spacing-6x); + margin-right: var(--pix-spacing-4x); + } + + // TODO: Use @iconAfter="chevronRight" when possible + &__chevron-right { + padding-left: var(--pix-spacing-6x); + font-weight: 1000; + } +} \ No newline at end of file diff --git a/mon-pix/app/styles/app.scss b/mon-pix/app/styles/app.scss index ff43c8a74c5..5433a278407 100644 --- a/mon-pix/app/styles/app.scss +++ b/mon-pix/app/styles/app.scss @@ -137,6 +137,7 @@ of an adaptative/mobile-first approach — refactoring is welcome here */ @import 'authentication/oidc-provider-selector'; @import 'authentication/signin-form'; @import 'authentication/sso-selection-form'; +@import 'authentication/other-authentication-providers'; @import 'authentication/password-input/password-checklist'; @import 'authentication/password-input/password-rule'; diff --git a/mon-pix/public/images/logo/pole-emploi-connect-logo.svg b/mon-pix/public/images/logo/pole-emploi-connect-logo.svg new file mode 100644 index 00000000000..c020b1e4132 --- /dev/null +++ b/mon-pix/public/images/logo/pole-emploi-connect-logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/mon-pix/tests/integration/components/authentication/other-authentication-providers-test.gjs b/mon-pix/tests/integration/components/authentication/other-authentication-providers-test.gjs new file mode 100644 index 00000000000..7cbdb5291f2 --- /dev/null +++ b/mon-pix/tests/integration/components/authentication/other-authentication-providers-test.gjs @@ -0,0 +1,149 @@ +import { render } from '@1024pix/ember-testing-library'; +import Service from '@ember/service'; +import { t } from 'ember-intl/test-support'; +import OtherAuthenticationProviders from 'mon-pix/components/authentication/other-authentication-providers'; +import { module, test } from 'qunit'; + +import setupIntlRenderingTest from '../../../helpers/setup-intl-rendering'; + +module('Integration | Component | Authentication | other-authentication-providers', function (hooks) { + setupIntlRenderingTest(hooks); + + module('when it’s for login', function () { + test('it displays a login heading', async function (assert) { + // when + const screen = await render(); + + // then + assert + .dom( + screen.getByRole('heading', { + name: t('components.authentication.other-authentication-providers.login-heading'), + }), + ) + .exists(); + }); + }); + + module('when it’s for signup', function () { + test('it displays a signup heading', async function (assert) { + // when + const screen = await render(); + + // then + assert + .dom( + screen.getByRole('heading', { + name: t('components.authentication.other-authentication-providers.signup-heading'), + }), + ) + .exists(); + }); + }); + + module('when there is a featured identity provider', function () { + test('it displays a continue featured identity provider link', async function (assert) { + // given + class OidcIdentityProvidersServiceStub extends Service { + get featuredIdentityProvider() { + return { organizationName: 'Some Identity Provider', slug: 'some-identity-provider' }; + } + } + this.owner.register('service:oidcIdentityProviders', OidcIdentityProvidersServiceStub); + + // when + const screen = await render(); + + // then + const link = await screen.findByRole('link', { + name: t( + 'components.authentication.other-authentication-providers.continue-with-featured-identity-provider-link', + { + featuredIdentityProvider: 'Some Identity Provider', + }, + ), + }); + assert.dom(link).exists(); + assert.strictEqual(link.getAttribute('href'), '/connexion/some-identity-provider'); + }); + }); + + module('when there isn’t any featured identity provider', function () { + test('it doesn’t display a continue featured identity provider link', async function (assert) { + // given + class OidcIdentityProvidersServiceStub extends Service { + get featuredIdentityProvider() { + return null; + } + } + this.owner.register('service:oidcIdentityProviders', OidcIdentityProvidersServiceStub); + + // when + const screen = await render(); + + // then + assert + .dom( + screen.queryByText( + t( + 'components.authentication.other-authentication-providers.continue-with-featured-identity-provider-link', + { + featuredIdentityProvider: 'Some Identity Provider', + }, + ), + ), + ) + .doesNotExist(); + }); + }); + + module('when there are other identity providers', function () { + test('it displays a select another organization link', async function (assert) { + // given + class OidcIdentityProvidersServiceStub extends Service { + get hasOtherIdentityProviders() { + return true; + } + + load() { + return Promise.resolve(); + } + } + this.owner.register('service:oidcIdentityProviders', OidcIdentityProvidersServiceStub); + + // when + const screen = await render(); + + // then + const link = await screen.findByRole('link', { + name: t('components.authentication.other-authentication-providers.select-another-organization-link'), + }); + assert.dom(link).exists(); + assert.strictEqual(link.getAttribute('href'), '/connexion/sso-selection'); + }); + }); + + module('when there aren’t any other identity providers', function () { + test('it doesn’t display a select another organization link', async function (assert) { + // given + class OidcIdentityProvidersServiceStub extends Service { + get hasOtherIdentityProviders() { + return false; + } + } + this.owner.register('service:oidcIdentityProviders', OidcIdentityProvidersServiceStub); + + // when + const screen = await render(); + + // then + assert + .dom( + screen.queryByText( + t('components.authentication.other-authentication-providers.select-another-organization-link'), + ), + ) + .doesNotExist(); + }); + }); +}); diff --git a/mon-pix/translations/en.json b/mon-pix/translations/en.json index 2d62350a173..10f994eda2c 100644 --- a/mon-pix/translations/en.json +++ b/mon-pix/translations/en.json @@ -125,6 +125,12 @@ "placeholder": "Select an organization", "searchLabel": "Keyword search" }, + "other-authentication-providers": { + "signup-heading": "Other ways to sign up", + "login-heading": "Other ways to log in", + "continue-with-featured-identity-provider-link": "Continue with {featuredIdentityProvider}", + "select-another-organization-link": "Choose another organisation" + }, "password-input": { "error-message": "You have entered the wrong password. Your password must be longer than 8 characters and contain at least one number, one lower case letter and one upper case letter.", "instructions-label": "Your password must comply with the following rules:", diff --git a/mon-pix/translations/es.json b/mon-pix/translations/es.json index 1f77d485772..114c432fe9c 100644 --- a/mon-pix/translations/es.json +++ b/mon-pix/translations/es.json @@ -118,6 +118,12 @@ "placeholder": "Select an organization", "searchLabel": "Keyword search" }, + "other-authentication-providers": { + "signup-heading": "Other ways to sign up", + "login-heading": "Other ways to log in", + "continue-with-featured-identity-provider-link": "Continue with {featuredIdentityProvider}", + "select-another-organization-link": "Choose another organisation" + }, "password-input": { "error-message": "You have entered the wrong password. Your password must be longer than 8 characters and contain at least one number, one lower case letter and one upper case letter.", "instructions-label": "Your password must comply with the following rules:", diff --git a/mon-pix/translations/fr.json b/mon-pix/translations/fr.json index f9eb621532c..b08126b060d 100644 --- a/mon-pix/translations/fr.json +++ b/mon-pix/translations/fr.json @@ -125,6 +125,12 @@ "placeholder": "Sélectionner un organisme", "searchLabel": "Recherche par mots-clés" }, + "other-authentication-providers": { + "signup-heading": "Autres moyens d’inscription", + "login-heading": "Autres moyens de connexion", + "continue-with-featured-identity-provider-link": "Continuer avec {featuredIdentityProvider}", + "select-another-organization-link": "Choisir une autre organisation" + }, "password-input": { "error-message": "Le mot de passe saisi est erroné. Votre mot de passe doit être supérieur à 8 caractères et contenir au minimum un chiffre, une minuscule et une majuscule.", "instructions-label": "Votre mot de passe doit respecter les règles suivantes :", diff --git a/mon-pix/translations/nl.json b/mon-pix/translations/nl.json index f23376c21b1..b791c38ac2d 100644 --- a/mon-pix/translations/nl.json +++ b/mon-pix/translations/nl.json @@ -118,6 +118,12 @@ "placeholder": "Select an organization", "searchLabel": "Keyword search" }, + "other-authentication-providers": { + "signup-heading": "Other ways to sign up", + "login-heading": "Other ways to log in", + "continue-with-featured-identity-provider-link": "Continue with {featuredIdentityProvider}", + "select-another-organization-link": "Choose another organisation" + }, "password-input": { "error-message": "You have entered the wrong password. Your password must be longer than 8 characters and contain at least one number, one lower case letter and one upper case letter.", "instructions-label": "Your password must comply with the following rules:",