Skip to content

Commit

Permalink
feat(ux): Update 2fa signin screens/reset PW copy, create HeadingPrimary
Browse files Browse the repository at this point in the history
Because:
* We are prepping for SMS work and want to make some small UX improvements

This commit:
* Creates HeadingPrimary for our grey h1 text at the top of our flows that we are moving towards
* Updates copy and styling for 2FA signin and reset password

closes FXA-10210
  • Loading branch information
LZoog committed Nov 6, 2024
1 parent 087f48a commit 4159965
Show file tree
Hide file tree
Showing 17 changed files with 126 additions and 124 deletions.
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 { CheckmarkCircleOutlineBlackIcon } from '../Icons';
import { FtlMsg } from 'fxa-react/lib/utils';
import Banner, { BannerType } from '../Banner';
import { CreateRecoveryKeyHandler } from '../../pages/InlineRecoveryKeySetup/interfaces';
import { HeadingPrimary } from '../HeadingPrimary';

export const InlineRecoveryKeySetupCreate = ({
createRecoveryKeyHandler,
Expand All @@ -32,7 +33,7 @@ export const InlineRecoveryKeySetupCreate = ({

return (
<>
<Banner type={BannerType.success} additionalClassNames="mt-0">
<Banner type={BannerType.success} additionalClassNames="mt-0 mb-5">
<p className="flex justify-center text-base">
<CheckmarkCircleOutlineBlackIcon className="me-3" mode="success" />
<span>
Expand All @@ -47,11 +48,9 @@ export const InlineRecoveryKeySetupCreate = ({
<p className="text-center">{bannerError}</p>
</Banner>
)}
<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
19 changes: 8 additions & 11 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 Banner, { BannerType } from '../../components/Banner';
import { Constants } from '../../lib/constants';
import { InlineRecoveryKeySetupProps } from './interfaces';
import RecoveryKeySetupHint from '../../components/RecoveryKeySetupHint';
import { HeadingPrimary } from '../../components/HeadingPrimary';

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

Expand Down Expand Up @@ -42,11 +43,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 @@ -59,7 +58,7 @@ export const InlineRecoveryKeySetup = ({
case 2:
return (
<>
<Banner type={BannerType.success} additionalClassNames="mt-0">
<Banner type={BannerType.success} additionalClassNames="mt-0 mb-5">
<p className="flex justify-center text-base">
<CheckmarkCircleOutlineBlackIcon
className="me-3"
Expand All @@ -72,11 +71,9 @@ export const InlineRecoveryKeySetup = ({
</span>
</p>
</Banner>
<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 {
import { getLocalizedErrorMessage } from '../../../lib/error-utils';
import { RecoveryKeyImage } from '../../../components/images';
import { Constants } from '../../../lib/constants';
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 @@ -137,21 +138,17 @@ 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={BannerType.error}>{errorMessage}</Banner>}
<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 @@ -187,7 +184,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 {
import { FtlMsg } from 'fxa-react/lib/utils';
import ResetPasswordWarning from '../../../components/ResetPasswordWarning';
import { Link, useLocation } from '@reach/router';
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 @@ -90,11 +89,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 @@ -17,6 +17,7 @@ import Banner, {
import { ResendStatus } from '../../../lib/types';
import { EmailCodeImage } from '../../../components/images';
import GleanMetrics from '../../../lib/glean';
import { HeadingPrimary } from '../../../components/HeadingPrimary';

const ConfirmResetPassword = ({
clearBanners,
Expand Down Expand Up @@ -46,27 +47,26 @@ 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 && <ResendEmailSuccessBanner />}
{hasResendError && (
<Banner type={BannerType.error}>{resendErrorMessage}</Banner>
)}
{errorMessage && <Banner type={BannerType.error}>{errorMessage}</Banner>}
<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 @@ -87,7 +87,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
Expand Up @@ -5,5 +5,7 @@ confirm-totp-reset-password-subheader = Enter your two-factor authentication sec
confirm-totp-reset-password-instruction = Check your authenticator app 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 @@ -33,7 +33,9 @@ describe('ConfirmTotpResetPassword', () => {
'Enter your two-factor authentication security code (2FA)'
);

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

expect(
screen.getByText('Check your authenticator app to reset your password.')
Expand All @@ -47,7 +49,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,21 +102,19 @@ 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">
<h2 className="font-bold text-xl">
<FtlMsg id="confirm-totp-reset-password-subheader">
Enter your two-factor authentication security code (2FA)
</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 authenticator app to reset your password.
</FtlMsg>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const ResetPassword = ({

<form
noValidate
className="flex flex-col gap-4 mb-4"
className="flex flex-col gap-4 mb-5"
onSubmit={handleSubmit(onSubmit)}
>
<FtlMsg id="password-reset-email-input" attrs={{ label: true }}>
Expand Down
13 changes: 4 additions & 9 deletions packages/fxa-settings/src/pages/Signin/SigninRecoveryCode/en.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@
## (provided to the user when they first set up two-step authentication)
## when they are unable to sign in with two-step authentication (e.g., Authy, Duo, etc.)

# String within the <span> element appears on a separate line
# If more appropriate in a locale, the string within the <span>, "to continue to account settings" can stand alone as "Continue to account settings"
signin-recovery-code-heading-w-default-service = Enter backup authentication code <span>to continue to account settings</span>
# String within the <span> element appears on a separate line
# If more appropriate in a locale, the string within the <span>, "to continue to { $serviceName }" can stand alone as "Continue to { $serviceName }"
# { $serviceName } represents a product name (e.g., Mozilla VPN) that will be passed in as a variable
signin-recovery-code-heading-w-custom-service = Enter backup authentication code <span>to continue to { $serviceName }</span>
signin-recovery-code-instruction = Please enter a backup authentication code that was provided to you during two step authentication setup.
signin-recovery-code-input-label = Enter 10-digit backup authentication code
signin-recovery-code-heading = Sign in
signin-recovery-code-sub-heading = Enter backup code
signin-recovery-code-instruction-v2 = Enter one of the one-time use backup codes you saved during two-step authentication setup.
signin-recovery-code-input-label-v2 = Enter 10-character code
# Form button to confirm if the backup authentication code entered by the user is valid
signin-recovery-code-confirm-button = Confirm
# Link to return to signin with two-step authentication code
Expand Down
Loading

0 comments on commit 4159965

Please sign in to comment.