Skip to content

Commit

Permalink
Merge pull request #42339 from suneox/39965-set-error-when-click-outside
Browse files Browse the repository at this point in the history
set error when click outside onboarding flow
  • Loading branch information
mountiny authored May 27, 2024
2 parents 721d44d + 18367c1 commit b720ae6
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 14 deletions.
3 changes: 2 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,8 @@ export default {
whereYouWork: 'Where do you work?',
purpose: {
title: 'What do you want to do today?',
error: 'Please make a selection before continuing.',
errorSelection: 'Please make a selection to continue.',
errorContinue: 'Please press continue to get set up.',
[CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Get paid back by my employer',
[CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: "Manage my team's expenses",
[CONST.ONBOARDING_CHOICES.PERSONAL_SPEND]: 'Track and budget expenses',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,8 @@ export default {
whereYouWork: '¿Dónde trabajas?',
purpose: {
title: '¿Qué quieres hacer hoy?',
error: 'Por favor, haga una selección antes de continuar.',
errorSelection: 'Por favor selecciona una opción para continuar.',
errorContinue: 'Por favor, haz click en continuar para configurar tu cuenta.',
[CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Cobrar de mi empresa',
[CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Gestionar los gastos de mi equipo',
[CONST.ONBOARDING_CHOICES.PERSONAL_SPEND]: 'Controlar y presupuestar gastos',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import {createStackNavigator} from '@react-navigation/stack';
import React from 'react';
import React, {useCallback} from 'react';
import {View} from 'react-native';
import NoDropZone from '@components/DragAndDrop/NoDropZone';
import useKeyboardShortcut from '@hooks/useKeyboardShortcut';
import useOnboardingLayout from '@hooks/useOnboardingLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import OnboardingModalNavigatorScreenOptions from '@libs/Navigation/AppNavigator/OnboardingModalNavigatorScreenOptions';
import type {OnboardingModalNavigatorParamList} from '@libs/Navigation/types';
import OnboardingRefManager from '@libs/OnboardingRefManager';
import OnboardingPersonalDetails from '@pages/OnboardingPersonalDetails';
import OnboardingPurpose from '@pages/OnboardingPurpose';
import OnboardingWork from '@pages/OnboardingWork';
import CONST from '@src/CONST';
import SCREENS from '@src/SCREENS';
import Overlay from './Overlay';

Expand All @@ -18,11 +21,26 @@ function OnboardingModalNavigator() {
const styles = useThemeStyles();
const {shouldUseNarrowLayout} = useOnboardingLayout();

const outerViewRef = React.useRef<View>(null);

const handleOuterClick = useCallback(() => {
OnboardingRefManager.handleOuterClick();
}, []);

useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ESCAPE, handleOuterClick, {shouldBubble: true});

return (
<NoDropZone>
<Overlay />
<View style={styles.onboardingNavigatorOuterView}>
<View style={styles.OnboardingNavigatorInnerView(shouldUseNarrowLayout)}>
<View
ref={outerViewRef}
onClick={handleOuterClick}
style={styles.onboardingNavigatorOuterView}
>
<View
onClick={(e) => e.stopPropagation()}
style={styles.OnboardingNavigatorInnerView(shouldUseNarrowLayout)}
>
<Stack.Navigator screenOptions={OnboardingModalNavigatorScreenOptions()}>
<Stack.Screen
name={SCREENS.ONBOARDING.PURPOSE}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ function BaseOverlay({shouldUseNativeStyles, onPress, isModalOnTheLeft = false}:
const {translate} = useLocalize();

return (
<Animated.View style={shouldUseNativeStyles ? styles.nativeOverlayStyles(current) : styles.overlayStyles(current, isModalOnTheLeft)}>
<Animated.View
id="BaseOverlay"
style={shouldUseNativeStyles ? styles.nativeOverlayStyles(current) : styles.overlayStyles(current, isModalOnTheLeft)}
>
<View style={[styles.flex1, styles.flexColumn]}>
{/* In the latest Electron version buttons can't be both clickable and draggable.
That's why we added this workaround. Because of two Pressable components on the desktop app
Expand Down
17 changes: 17 additions & 0 deletions src/libs/OnboardingRefManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';

type TOnboardingRef = {
handleOuterClick: () => void;
};

const onboardingRef = React.createRef<TOnboardingRef>();

const OnboardingRefManager = {
ref: onboardingRef,
handleOuterClick: () => {
onboardingRef.current?.handleOuterClick();
},
};

export type {TOnboardingRef};
export default OnboardingRefManager;
30 changes: 22 additions & 8 deletions src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {useIsFocused} from '@react-navigation/native';
import React, {useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
import {ScrollView} from 'react-native-gesture-handler';
import {withOnyx} from 'react-native-onyx';
Expand All @@ -19,6 +20,8 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import Navigation from '@libs/Navigation/Navigation';
import OnboardingRefManager from '@libs/OnboardingRefManager';
import type {TOnboardingRef} from '@libs/OnboardingRefManager';
import variables from '@styles/variables';
import * as Welcome from '@userActions/Welcome';
import type {OnboardingPurposeType} from '@src/CONST';
Expand All @@ -41,7 +44,6 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
const {shouldUseNarrowLayout} = useOnboardingLayout();
const [selectedPurpose, setSelectedPurpose] = useState<OnboardingPurposeType | undefined>(undefined);
const {isSmallScreenWidth, windowHeight} = useWindowDimensions();
const [error, setError] = useState(false);
const theme = useTheme();

useDisableModalDismissOnEscape();
Expand All @@ -52,8 +54,6 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
setSelectedPurpose(onboardingPurposeSelected ?? undefined);
}, [onboardingPurposeSelected]);

const errorMessage = error ? 'onboarding.purpose.error' : '';

const maxHeight = shouldEnableMaxHeight ? windowHeight : undefined;

const paddingHorizontal = shouldUseNarrowLayout ? styles.ph8 : styles.ph5;
Expand Down Expand Up @@ -83,6 +83,8 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
Navigation.navigate(ROUTES.ONBOARDING_PERSONAL_DETAILS);
}, [selectedPurpose]);

const [errorMessage, setErrorMessage] = useState<'onboarding.purpose.errorSelection' | 'onboarding.purpose.errorContinue' | ''>('');

const menuItems: MenuItemProps[] = Object.values(CONST.ONBOARDING_CHOICES).map((choice) => {
const translationKey = `onboarding.purpose.${choice}` as const;
const isSelected = selectedPurpose === choice;
Expand All @@ -100,10 +102,22 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
shouldShowRightComponent: isSelected,
onPress: () => {
Welcome.setOnboardingPurposeSelected(choice);
setError(false);
setErrorMessage('');
},
};
});
const isFocused = useIsFocused();

const handleOuterClick = useCallback(() => {
if (!selectedPurpose) {
setErrorMessage('onboarding.purpose.errorSelection');
} else {
setErrorMessage('onboarding.purpose.errorContinue');
}
}, [selectedPurpose]);

const onboardingLocalRef = useRef<TOnboardingRef>(null);
useImperativeHandle(isFocused ? OnboardingRefManager.ref : onboardingLocalRef, () => ({handleOuterClick}), [handleOuterClick]);

return (
<SafeAreaConsumer>
Expand Down Expand Up @@ -133,14 +147,14 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
buttonText={translate('common.continue')}
onSubmit={() => {
if (!selectedPurpose) {
setError(true);
setErrorMessage('onboarding.purpose.errorSelection');
return;
}
setError(false);
setErrorMessage('');
saveAndNavigate();
}}
message={errorMessage}
isAlertVisible={error || Boolean(errorMessage)}
isAlertVisible={Boolean(errorMessage)}
containerStyles={[styles.w100, styles.mb5, styles.mh0, paddingHorizontal]}
/>
</View>
Expand Down

0 comments on commit b720ae6

Please sign in to comment.