Skip to content

Commit

Permalink
Merge pull request #19508 from Expensify/nikki-emaildeliveryissue
Browse files Browse the repository at this point in the history
Add EmailDeliveryFailure view
  • Loading branch information
PauloGasparSv authored Jul 12, 2023
2 parents a3404b1 + 019e919 commit 089cf7e
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 8 deletions.
10 changes: 10 additions & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,16 @@ export default {
linkSent: 'Link sent!',
succesfullyUnlinkedLogin: 'Secondary login successfully unlinked!',
},
emailDeliveryFailurePage: {
ourEmailProvider: ({login}) => `Our email provider has temporarily suspended emails to ${login} due to delivery issues. To unblock your login, please follow these steps:`,
confirmThat: ({login}) => `Confirm that ${login} is spelled correctly and is a real, deliverable email address. `,
emailAliases: 'Email aliases such as "[email protected]" must have access to their own email inbox for it to be a valid Expensify login.',
ensureYourEmailClient: 'Ensure your email client allows expensify.com emails. ',
youCanFindDirections: 'You can find directions on how to complete this step ',
helpConfigure: ' but you may need your IT department to help configure your email settings.',
onceTheAbove: 'Once the above steps are completed, please reach out to ',
toUnblock: ' to unblock your login.',
},
detailsPage: {
localTime: 'Local time',
},
Expand Down
12 changes: 12 additions & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,18 @@ export default {
linkSent: '¡Enlace enviado!',
succesfullyUnlinkedLogin: '¡Nombre de usuario secundario desvinculado correctamente!',
},
emailDeliveryFailurePage: {
ourEmailProvider: ({login}) =>
`Nuestro proveedor de correo electrónico ha suspendido temporalmente los correos electrónicos a ${login} debido a problemas de entrega. Para desbloquear el inicio de sesión, sigue estos pasos:`,
confirmThat: ({login}) => `Confirma que ${login} está escrito correctamente y que es una dirección de correo electrónico real que puede recibir correos. `,
emailAliases:
'Los alias de correo electrónico como "[email protected]" deben tener acceso a su propia bandeja de entrada de correo electrónico para que sea un inicio de sesión válido de Expensify.',
ensureYourEmailClient: 'Asegúrese de que su cliente de correo electrónico permita correos electrónicos de expensify.com. ',
youCanFindDirections: 'Puedes encontrar instrucciones sobre cómo completar este paso ',
helpConfigure: ', pero es posible que necesites que el departamento de informática te ayude a configurar los ajustes de correo electrónico.',
onceTheAbove: 'Una vez completados los pasos anteriores, ponte en contacto con ',
toUnblock: ' para desbloquear el inicio de sesión.',
},
detailsPage: {
localTime: 'Hora local',
},
Expand Down
97 changes: 97 additions & 0 deletions src/pages/signin/EmailDeliveryFailurePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React, {useEffect} from 'react';
import {Keyboard, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import Str from 'expensify-common/lib/str';
import styles from '../../styles/styles';
import Text from '../../components/Text';
import TextLink from '../../components/TextLink';
import ONYXKEYS from '../../ONYXKEYS';
import useLocalize from '../../hooks/useLocalize';
import useKeyboardState from '../../hooks/useKeyboardState';
import redirectToSignIn from '../../libs/actions/SignInRedirect';
import CONST from '../../CONST';
import PressableWithFeedback from '../../components/Pressable/PressableWithFeedback';

const propTypes = {
/* Onyx Props */

/** The credentials of the logged in person */
credentials: PropTypes.shape({
/** The email/phone the user logged in with */
login: PropTypes.string,
}),
};

const defaultProps = {
credentials: {},
};

function EmailDeliveryFailurePage(props) {
const {isKeyboardShown} = useKeyboardState();
const {translate} = useLocalize();
const login = Str.isSMSLogin(props.credentials.login) ? Str.removeSMSDomain(props.credentials.login) : props.credentials.login;

// This view doesn't have a field for user input, so dismiss the device keyboard if shown
useEffect(() => {
if (!isKeyboardShown) {
return;
}
Keyboard.dismiss();
}, [isKeyboardShown]);

return (
<>
<View style={[styles.mv3, styles.flexRow, styles.justifyContentetween]}>
<View style={[styles.flex1]}>
<Text>{translate('emailDeliveryFailurePage.ourEmailProvider', {login})}</Text>
<Text style={[styles.mt5]}>
<Text style={[styles.textStrong]}>{translate('emailDeliveryFailurePage.confirmThat', {login})}</Text>
{translate('emailDeliveryFailurePage.emailAliases')}
</Text>
<Text style={[styles.mt5]}>
<Text style={[styles.textStrong]}>{translate('emailDeliveryFailurePage.ensureYourEmailClient')}</Text>
{translate('emailDeliveryFailurePage.youCanFindDirections')}
<TextLink
href="https://community.expensify.com/discussion/5651/deep-dive-best-practices-when-youre-running-into-trouble-receiving-emails-from-expensify/p1?new=1"
style={[styles.link]}
>
{translate('common.here')}
</TextLink>
{translate('emailDeliveryFailurePage.helpConfigure')}
</Text>
<Text style={styles.mt5}>
{translate('emailDeliveryFailurePage.onceTheAbove')}
<TextLink
href={`mailto:${CONST.EMAIL.CONCIERGE}`}
style={[styles.link]}
>
{CONST.EMAIL.CONCIERGE}
</TextLink>
{translate('emailDeliveryFailurePage.toUnblock')}
</Text>
</View>
</View>
<View style={[styles.mv4, styles.flexRow, styles.justifyContentBetween, styles.alignItemsCenter]}>
<PressableWithFeedback
onPress={() => redirectToSignIn()}
accessibilityRole="button"
accessibilityLabel={translate('common.back')}
// disable hover dim for switch
hoverDimmingValue={1}
pressDimmingValue={0.2}
>
<Text style={[styles.link]}>{translate('common.back')}</Text>
</PressableWithFeedback>
</View>
</>
);
}

EmailDeliveryFailurePage.propTypes = propTypes;
EmailDeliveryFailurePage.defaultProps = defaultProps;
EmailDeliveryFailurePage.displayName = 'EmailDeliveryFailurePage';

export default withOnyx({
credentials: {key: ONYXKEYS.CREDENTIALS},
})(EmailDeliveryFailurePage);
33 changes: 25 additions & 8 deletions src/pages/signin/SignInPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ResendValidationForm from './ResendValidationForm';
import Performance from '../../libs/Performance';
import * as App from '../../libs/actions/App';
import UnlinkLoginForm from './UnlinkLoginForm';
import EmailDeliveryFailurePage from './EmailDeliveryFailurePage';
import * as Localize from '../../libs/Localize';
import * as StyleUtils from '../../styles/StyleUtils';
import useLocalize from '../../hooks/useLocalize';
Expand All @@ -39,6 +40,9 @@ const propTypes = {

/** Does this account require 2FA? */
requiresTwoFactorAuth: PropTypes.bool,

/** Is this account having trouble receiving emails */
hasEmailDeliveryFailure: PropTypes.bool,
}),

/** The credentials of the person signing in */
Expand All @@ -63,18 +67,23 @@ const defaultProps = {
* @param {Boolean} isAccountValidated
* @param {Boolean} didForgetPassword
* @param {Boolean} canUsePasswordlessLogins
* @param {Boolean} hasEmailDeliveryFailure
* @returns {Object}
*/
function getRenderOptions({hasLogin, hasPassword, hasValidateCode, hasAccount, isPrimaryLogin, isAccountValidated, didForgetPassword, canUsePasswordlessLogins}) {
function getRenderOptions({hasLogin, hasPassword, hasValidateCode, hasAccount, isPrimaryLogin, isAccountValidated, didForgetPassword, canUsePasswordlessLogins, hasEmailDeliveryFailure}) {
const shouldShowLoginForm = !hasLogin && !hasValidateCode;
const isUnvalidatedSecondaryLogin = hasLogin && !isPrimaryLogin && !isAccountValidated;
const shouldShowPasswordForm = hasLogin && isAccountValidated && !hasPassword && !didForgetPassword && !isUnvalidatedSecondaryLogin && !canUsePasswordlessLogins;
const shouldShowValidateCodeForm = hasAccount && (hasLogin || hasValidateCode) && !isUnvalidatedSecondaryLogin && canUsePasswordlessLogins;
const shouldShowResendValidationForm = hasLogin && (!isAccountValidated || didForgetPassword) && !isUnvalidatedSecondaryLogin && !canUsePasswordlessLogins;
const shouldShowWelcomeHeader = shouldShowLoginForm || shouldShowPasswordForm || shouldShowValidateCodeForm || isUnvalidatedSecondaryLogin;
const shouldShowEmailDeliveryFailurePage = hasLogin && hasEmailDeliveryFailure;
const isUnvalidatedSecondaryLogin = hasLogin && !isPrimaryLogin && !isAccountValidated && !shouldShowEmailDeliveryFailurePage;
const shouldShowPasswordForm =
hasLogin && isAccountValidated && !hasPassword && !didForgetPassword && !isUnvalidatedSecondaryLogin && !canUsePasswordlessLogins && !shouldShowEmailDeliveryFailurePage;
const shouldShowValidateCodeForm = hasAccount && (hasLogin || hasValidateCode) && !isUnvalidatedSecondaryLogin && canUsePasswordlessLogins && !shouldShowEmailDeliveryFailurePage;
const shouldShowResendValidationForm =
hasLogin && (!isAccountValidated || didForgetPassword) && !isUnvalidatedSecondaryLogin && !canUsePasswordlessLogins && !shouldShowEmailDeliveryFailurePage;
const shouldShowWelcomeHeader = shouldShowLoginForm || shouldShowPasswordForm || shouldShowValidateCodeForm || isUnvalidatedSecondaryLogin || shouldShowEmailDeliveryFailurePage;
const shouldShowWelcomeText = shouldShowLoginForm || shouldShowPasswordForm || shouldShowValidateCodeForm;
return {
shouldShowLoginForm,
shouldShowEmailDeliveryFailurePage,
shouldShowUnlinkLoginForm: isUnvalidatedSecondaryLogin,
shouldShowPasswordForm,
shouldShowValidateCodeForm,
Expand All @@ -97,6 +106,7 @@ function SignInPage({credentials, account}) {

const {
shouldShowLoginForm,
shouldShowEmailDeliveryFailurePage,
shouldShowUnlinkLoginForm,
shouldShowPasswordForm,
shouldShowValidateCodeForm,
Expand All @@ -112,11 +122,12 @@ function SignInPage({credentials, account}) {
isAccountValidated: Boolean(account.validated),
didForgetPassword: Boolean(account.forgotPassword),
canUsePasswordlessLogins,
hasEmailDeliveryFailure: Boolean(account.hasEmailDeliveryFailure),
});

let welcomeHeader;
let welcomeText;
if (shouldShowValidateCodeForm) {
if (shouldShowValidateCodeForm || shouldShowResendValidationForm) {
if (account.requiresTwoFactorAuth) {
// We will only know this after a user signs in successfully, without their 2FA code
welcomeHeader = isSmallScreenWidth ? '' : translate('welcomeText.welcomeBack');
Expand All @@ -141,8 +152,13 @@ function SignInPage({credentials, account}) {
} else if (shouldShowPasswordForm) {
welcomeHeader = isSmallScreenWidth ? '' : translate('welcomeText.welcomeBack');
welcomeText = isSmallScreenWidth ? `${translate('welcomeText.welcomeBack')} ${translate('welcomeText.enterPassword')}` : translate('welcomeText.enterPassword');
} else if (shouldShowUnlinkLoginForm) {
} else if (shouldShowUnlinkLoginForm || shouldShowEmailDeliveryFailurePage) {
welcomeHeader = isSmallScreenWidth ? translate('login.hero.header') : translate('welcomeText.welcomeBack');

// Don't show any welcome text if we're showing the user the email delivery failed view
if (shouldShowEmailDeliveryFailurePage) {
welcomeText = '';
}
} else if (!shouldShowResendValidationForm) {
welcomeHeader = isSmallScreenWidth ? translate('login.hero.header') : translate('welcomeText.getStarted');
welcomeText = isSmallScreenWidth ? translate('welcomeText.getStarted') : '';
Expand All @@ -167,6 +183,7 @@ function SignInPage({credentials, account}) {
{shouldShowValidateCodeForm ? <ValidateCodeForm isVisible={shouldShowValidateCodeForm} /> : <PasswordForm isVisible={shouldShowPasswordForm} />}
{shouldShowResendValidationForm && <ResendValidationForm />}
{shouldShowUnlinkLoginForm && <UnlinkLoginForm />}
{shouldShowEmailDeliveryFailurePage && <EmailDeliveryFailurePage />}
</SignInPageLayout>
</View>
);
Expand Down

0 comments on commit 089cf7e

Please sign in to comment.