Skip to content

Commit

Permalink
Merge pull request #17982 from mozilla/FXA-10210
Browse files Browse the repository at this point in the history
feat(ux): Update 2fa signin screens/reset PW copy, create HeadingPrimary
  • Loading branch information
LZoog authored Nov 14, 2024
2 parents 448265b + d722c1f commit 6a04b30
Show file tree
Hide file tree
Showing 20 changed files with 144 additions and 150 deletions.
6 changes: 2 additions & 4 deletions packages/functional-tests/pages/resetPassword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export class ResetPasswordPage extends BaseLayout {
}

async fillOutTotpForm(code: string) {
await this.page.getByLabel('Enter code').fill(code);
await this.page.getByLabel('Enter 6-digit code').fill(code);
return this.page.getByRole('button', { name: 'Confirm' }).click();
}

Expand All @@ -203,9 +203,7 @@ export class ResetPasswordPage extends BaseLayout {
}

async fillOurRecoveryCodeForm(code: string) {
await this.page
.getByLabel('Enter 10-digit backup authentication code')
.fill(code);
await this.page.getByLabel('Enter 10-character code').fill(code);
return this.page.getByRole('button', { name: 'Confirm' }).click();
}

Expand Down
2 changes: 1 addition & 1 deletion packages/functional-tests/pages/signinRecoveryCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class SigninRecoveryCodePage extends BaseTokenCodePage {
get codeInput() {
this.checkPath();
return this.page
.getByLabel('Enter 10-digit backup') // React
.getByLabel('Enter 10-character code') // React
.or(this.page.getByPlaceholder('Enter 10-digit backup')); //Backbone
}
}
2 changes: 1 addition & 1 deletion packages/functional-tests/pages/signinTotpCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class SigninTotpCodePage extends BaseTokenCodePage {
get codeInput() {
this.checkPath();
return this.page
.getByLabel('Enter code') // React
.getByLabel('Enter 6-digit code') // React
.or(this.page.getByPlaceholder('Enter 6-digit code')); //Backbone
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import React from 'react';
import { HeadingPrimary } from '.';
import { Meta } from '@storybook/react';

export default {
title: 'Components/HeadingPrimary',
component: HeadingPrimary,
} as Meta;

export const Default = <HeadingPrimary>Primary heading text</HeadingPrimary>;
13 changes: 13 additions & 0 deletions packages/fxa-settings/src/components/HeadingPrimary/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import React from 'react';

export const HeadingPrimary = ({
children,
marginClass = 'mb-5',
}: {
children: React.ReactNode;
marginClass?: string;
}) => <h1 className={`${marginClass} text-grey-400 text-base`}>{children}</h1>;
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { FtlMsg } from 'fxa-react/lib/utils';
import { CreateRecoveryKeyHandler } from '../../pages/InlineRecoveryKeySetup/interfaces';
import Banner from '../Banner';
import { useFtlMsgResolver } from '../../models';
import { HeadingPrimary } from '../HeadingPrimary';

export const InlineRecoveryKeySetupCreate = ({
createRecoveryKeyHandler,
Expand Down Expand Up @@ -50,11 +51,9 @@ export const InlineRecoveryKeySetupCreate = ({
content={{ localizedHeading: localizedErrorBannerMessage }}
/>
)}
<h1 className="text-grey-400 mb-3 mt-5">
<FtlMsg id="inline-recovery-key-setup-create-header">
Secure your account
</FtlMsg>
</h1>
<FtlMsg id="inline-recovery-key-setup-create-header">
<HeadingPrimary>Secure your account</HeadingPrimary>
</FtlMsg>

<RecoveryKeyImage className="my-6 mx-auto" />

Expand Down
17 changes: 7 additions & 10 deletions packages/fxa-settings/src/pages/InlineRecoveryKeySetup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { InlineRecoveryKeySetupProps } from './interfaces';
import RecoveryKeySetupHint from '../../components/RecoveryKeySetupHint';
import Banner from '../../components/Banner';
import { useFtlMsgResolver } from '../../models';
import { HeadingPrimary } from '../../components/HeadingPrimary';

const viewName = 'inline-recovery-key-setup';

Expand Down Expand Up @@ -43,11 +44,9 @@ export const InlineRecoveryKeySetup = ({
case 3:
return (
<>
<h1 className="text-grey-400">
<FtlMsg id="inline-recovery-key-setup-hint-header">
Security recommendation
</FtlMsg>
</h1>
<FtlMsg id="inline-recovery-key-setup-hint-header">
<HeadingPrimary>Security recommendation</HeadingPrimary>
</FtlMsg>
<RecoveryKeySetupHint
{...{ viewName }}
navigateForward={() => {
Expand All @@ -69,11 +68,9 @@ export const InlineRecoveryKeySetup = ({
),
}}
/>
<h1 className="text-grey-400 mb-3 mt-5">
<FtlMsg id="inline-recovery-key-setup-download-header">
Secure your account
</FtlMsg>
</h1>
<FtlMsg id="inline-recovery-key-setup-download-header">
<HeadingPrimary>Secure your account</HeadingPrimary>
</FtlMsg>
<RecoveryKeyImage className="my-6 mx-auto" />

<h2 className="font-bold text-xl mb-5">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { getLocalizedErrorMessage } from '../../../lib/error-utils';
import { RecoveryKeyImage } from '../../../components/images';
import { Constants } from '../../../lib/constants';
import Banner from '../../../components/Banner';
import { HeadingPrimary } from '../../../components/HeadingPrimary';

// TODO in FXA-7894 use sensitive data client to pass sensitive data
// Depends on FXA-7400
Expand Down Expand Up @@ -138,23 +139,19 @@ const AccountRecoveryConfirmKey = ({
};

return (
<AppLayout>
<AppLayout cardClass="card-base">
<FtlMsg id="password-reset-flow-heading">
<h1 className="text-start text-grey-400 text-sm">
Reset your password
</h1>
<HeadingPrimary>Reset your password</HeadingPrimary>
</FtlMsg>
{errorMessage && (
<Banner type="error" content={{ localizedHeading: errorMessage }} />
)}
<RecoveryKeyImage className="mx-auto my-2" />
<FtlMsg id="account-recovery-confirm-key-heading">
<h2 className="card-header text-start mb-2">
Enter your account recovery key
</h2>
<h2 className="card-header mb-2">Enter your account recovery key</h2>
</FtlMsg>
<FtlMsg id="account-recovery-confirm-key-instruction">
<p className="text-start text-sm">
<p className="text-sm">
This key recovers your encrypted browsing data, such as passwords and
bookmarks, from Firefox servers.
</p>
Expand Down Expand Up @@ -190,7 +187,7 @@ const AccountRecoveryConfirmKey = ({
</FtlMsg>

{recoveryKeyHint && (
<div className="bg-grey-50 p-4 text-start text-sm rounded-md">
<div className="bg-grey-50 p-4 text-sm rounded-md">
<FtlMsg id="account-recovery-confirm-key-hint">
<p className="text-grey-500">Your storage hint is:</p>
</FtlMsg>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { FtlMsg } from 'fxa-react/lib/utils';
import ResetPasswordWarning from '../../../components/ResetPasswordWarning';
import { Link, useLocation } from '@reach/router';
import Banner from '../../../components/Banner';
import { HeadingPrimary } from '../../../components/HeadingPrimary';

const CompleteResetPassword = ({
email,
Expand Down Expand Up @@ -63,11 +64,9 @@ const CompleteResetPassword = ({
};

return (
<AppLayout>
<AppLayout cardClass="card-base">
<FtlMsg id="password-reset-flow-heading">
<p className="text-start text-grey-400 text-sm mb-6">
Reset your password
</p>
<HeadingPrimary>Reset your password</HeadingPrimary>
</FtlMsg>

{/*
Expand All @@ -92,11 +91,9 @@ const CompleteResetPassword = ({
<input type="email" value={email} className="hidden" readOnly />

<FtlMsg id="complete-reset-pw-header-v2">
<h1 className="font-semibold text-xl text-start mt-6">
Create a new password
</h1>
<h1 className="font-semibold text-xl mt-6">Create a new password</h1>
</FtlMsg>
<section className="text-start mt-2">
<section className="mt-2">
<FormPasswordWithInlineCriteria
{...{
email,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ResendStatus } from '../../../lib/types';
import { EmailCodeImage } from '../../../components/images';
import GleanMetrics from '../../../lib/glean';
import Banner, { ResendCodeSuccessBanner } from '../../../components/Banner';
import { HeadingPrimary } from '../../../components/HeadingPrimary';

const ConfirmResetPassword = ({
clearBanners,
Expand Down Expand Up @@ -43,9 +44,9 @@ const ConfirmResetPassword = ({
};

return (
<AppLayout>
<AppLayout cardClass="card-base">
<FtlMsg id="password-reset-flow-heading">
<p className="text-start text-grey-400 text-sm">Reset your password</p>
<HeadingPrimary marginClass="">Reset your password</HeadingPrimary>
</FtlMsg>
{resendStatus === ResendStatus.sent && !hasResendError && (
<ResendCodeSuccessBanner />
Expand All @@ -61,16 +62,14 @@ const ConfirmResetPassword = ({
)}
<EmailCodeImage className="mx-auto" />
<FtlMsg id="confirm-reset-password-with-code-heading">
<h2 className="card-header text-start my-4">Check your email</h2>
<h2 className="card-header my-4">Check your email</h2>
</FtlMsg>
<FtlMsg
id="confirm-reset-password-with-code-instruction"
vars={{ email }}
elems={{ span: spanElement }}
>
<p className="text-start">
We sent a confirmation code to {spanElement}.
</p>
<p>We sent a confirmation code to {spanElement}.</p>
</FtlMsg>
<FormVerifyTotp
codeLength={8}
Expand All @@ -91,7 +90,7 @@ const ConfirmResetPassword = ({
}}
/>
<LinkRememberPassword {...{ email }} clickHandler={signinClickHandler} />
<div className="flex justify-between mt-4 text-sm">
<div className="flex justify-between mt-5 text-sm">
<FtlMsg id="confirm-reset-password-otp-resend-code-button">
<button type="button" className="link-blue" onClick={resendCode}>
Resend code
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
## PasswordResetConfirmTotp Page

confirm-totp-reset-password-header = Reset your password
confirm-totp-reset-password-subheader = Enter your two-factor authentication security code (2FA)
confirm-totp-reset-password-instruction = Check your authenticator app to reset your password.
confirm-totp-reset-password-subheader-v2 = Enter two-step authentication code
confirm-totp-reset-password-instruction-v2 = Check your <strong>authenticator app</strong> to reset your password.
confirm-totp-reset-password-trouble-code = Trouble entering code?
confirm-totp-reset-password-confirm-button = Confirm
confirm-totp-reset-password-input-label = Enter code
confirm-totp-reset-password-use-different-account = Use a different account
confirm-totp-reset-password-input-label-v2 = Enter 6-digit code
confirm-totp-reset-password-use-different-account = Use a different account
confirm-recovery-code-reset-password-input-label = Enter 10-character code
confirm-recovery-code-reset-password-trouble-code = Back
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ describe('ConfirmTotpResetPassword', () => {
).toBeVisible();

expect(screen.getByRole('heading', { level: 2 })).toHaveTextContent(
'Enter your two-factor authentication security code (2FA)'
'Enter two-step authentication code'
);

expect(screen.getByRole('textbox', { name: 'Enter code' })).toBeVisible();

expect(
screen.getByText('Check your authenticator app to reset your password.')
screen.getByRole('textbox', { name: 'Enter 6-digit code' })
).toBeVisible();

screen.getByText('authenticator app', { exact: false });
screen.getByText('to reset your password', { exact: false });
expect(screen.getByRole('button', { name: 'Confirm' })).toBeVisible();
expect(screen.getByText('Trouble entering code?')).toBeVisible();
});
Expand All @@ -47,7 +48,7 @@ describe('ConfirmTotpResetPassword', () => {
renderWithLocalizationProvider(<Subject verifyCode={mockVerifyCode} />);

await waitFor(() =>
screen.getByRole('textbox', { name: 'Enter code' }).click()
screen.getByRole('textbox', { name: 'Enter 6-digit code' }).click()
);
await waitFor(() => {
user.paste('123456');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import FormVerifyCode, {
commonBackupCodeFormAttributes,
FormAttributes,
} from '../../../components/FormVerifyCode';
import { HeadingPrimary } from '../../../components/HeadingPrimary';

export type ConfirmTotpResetPasswordProps = {
verifyCode: (code: string) => Promise<void>;
Expand All @@ -29,8 +30,8 @@ const ConfirmTotpResetPassword = ({
const [showRecoveryCode, setShowRecoveryCode] = useState<boolean>(false);

const totpFormAttributes: FormAttributes = {
inputFtlId: 'confirm-totp-reset-password-input-label',
inputLabelText: 'Enter code',
inputFtlId: 'confirm-totp-reset-password-input-label-v2',
inputLabelText: 'Enter 6-digit code',
pattern: '[0-9]{6}',
maxLength: 6,
submitButtonFtlId: 'confirm-totp-reset-password-confirm-button',
Expand All @@ -39,7 +40,7 @@ const ConfirmTotpResetPassword = ({

const recoveryCodeFormAttributes: FormAttributes = {
inputFtlId: 'confirm-recovery-code-reset-password-input-label',
inputLabelText: 'Enter 10-digit backup authentication code',
inputLabelText: 'Enter 10-character code',
submitButtonFtlId: 'confirm-totp-reset-password-confirm-button',
submitButtonText: 'Confirm',
...commonBackupCodeFormAttributes,
Expand All @@ -54,21 +55,19 @@ const ConfirmTotpResetPassword = ({
<>
{showRecoveryCode ? (
<AppLayout cardClass="card-base">
<h1 className="text-grey-400 mb-6 text-start">
<FtlMsg id="confirm-totp-reset-password-header">
Reset your password
</FtlMsg>
</h1>
<FtlMsg id="confirm-totp-reset-password-header">
<HeadingPrimary>Reset your password</HeadingPrimary>
</FtlMsg>

<h2 className="font-bold text-xl text-start">
<h2 className="font-bold text-xl">
<FtlMsg id="confirm-totp-reset-password-subheader">
Enter your backup recovery code
</FtlMsg>
</h2>

<div className="flex space-x-4">
<img src={protectionShieldIcon} alt="" />
<p className="my-5 text-md text-start">
<p className="my-5 text-md">
<FtlMsg id="confirm-totp-reset-password-instruction">
Check your download or saved backup recovery code.
</FtlMsg>
Expand Down Expand Up @@ -103,25 +102,24 @@ const ConfirmTotpResetPassword = ({
</AppLayout>
) : (
<AppLayout cardClass="card-base">
<h1 className="text-grey-400 mb-6 text-start">
<FtlMsg id="confirm-totp-reset-password-header">
Reset your password
</FtlMsg>
</h1>
<FtlMsg id="confirm-totp-reset-password-header">
<HeadingPrimary>Reset your password</HeadingPrimary>
</FtlMsg>

<h2 className="font-bold text-xl text-start">
<FtlMsg id="confirm-totp-reset-password-subheader">
Enter your two-factor authentication security code (2FA)
<h2 className="font-bold text-xl">
<FtlMsg id="confirm-totp-reset-password-subheader-v2">
Enter two-step authentication code
</FtlMsg>
</h2>

<div className="flex space-x-4">
<img src={protectionShieldIcon} alt="" />
<p className="my-5 text-md text-start">
<FtlMsg id="confirm-totp-reset-password-instruction">
Check your authenticator app to reset your password.
</FtlMsg>
</p>
<FtlMsg id="confirm-totp-reset-password-instruction-v2">
<p className="my-5 text-md">
Check your <strong>authenticator app</strong> to reset your
password.
</p>
</FtlMsg>
</div>

<FormVerifyCode
Expand Down
Loading

0 comments on commit 6a04b30

Please sign in to comment.