From 89305e402de3dbcf6e9e2aba169d4929f2fc395c Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Fri, 7 Jul 2023 18:01:14 +0200 Subject: [PATCH 001/394] switch to style based three pane view --- .../Navigation/AppNavigator/AuthScreens.js | 188 ++++++++--------- .../Navigators/FullScreenNavigator.js | 21 -- .../AppNavigator/Navigators/Overlay.js | 40 ++++ .../Navigators/RightModalNavigator.js | 195 ++++++++++-------- .../CustomRouter.js | 2 +- .../index.js | 23 +-- .../ThreePaneView.js | 88 -------- .../getRootNavigatorScreenOptions.js | 64 ++++++ .../modalCardStyleInterpolator.js | 16 +- src/libs/Navigation/NavigationRoot.js | 16 +- src/libs/Navigation/linkingConfig.js | 6 +- src/styles/cardStyles/index.js | 7 +- src/styles/styles.js | 10 +- 13 files changed, 326 insertions(+), 350 deletions(-) delete mode 100644 src/libs/Navigation/AppNavigator/Navigators/FullScreenNavigator.js create mode 100644 src/libs/Navigation/AppNavigator/Navigators/Overlay.js rename src/libs/Navigation/AppNavigator/{createResponsiveStackNavigator => createCustomStackNavigator}/CustomRouter.js (97%) rename src/libs/Navigation/AppNavigator/{createResponsiveStackNavigator => createCustomStackNavigator}/index.js (77%) delete mode 100644 src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/ThreePaneView.js create mode 100644 src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index c2fe7d3475e0..2367a665c4b1 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import moment from 'moment'; import _ from 'underscore'; import lodashGet from 'lodash/get'; +import {View} from 'react-native'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; import CONST from '../../../CONST'; import compose from '../../compose'; @@ -20,8 +21,7 @@ import Navigation from '../Navigation'; import * as User from '../../actions/User'; import * as Modal from '../../actions/Modal'; import * as Report from '../../actions/Report'; -import modalCardStyleInterpolator from './modalCardStyleInterpolator'; -import createResponsiveStackNavigator from './createResponsiveStackNavigator'; +import createCustomStackNavigator from './createCustomStackNavigator'; import SCREENS from '../../../SCREENS'; import defaultScreenOptions from './defaultScreenOptions'; import * as App from '../../actions/App'; @@ -30,9 +30,10 @@ import * as Session from '../../actions/Session'; import RightModalNavigator from './Navigators/RightModalNavigator'; import CentralPaneNavigator from './Navigators/CentralPaneNavigator'; import NAVIGATORS from '../../../NAVIGATORS'; -import FullScreenNavigator from './Navigators/FullScreenNavigator'; -import styles from '../../../styles/styles'; import * as SessionUtils from '../../SessionUtils'; +import variables from '../../../styles/variables'; +import NotFoundPage from '../../../pages/ErrorPage/NotFoundPage'; +import getRootNavigatorScreenOptions from './getRootNavigatorScreenOptions'; let currentUserEmail; Onyx.connect({ @@ -67,7 +68,7 @@ Onyx.connect({ }, }); -const RootStack = createResponsiveStackNavigator(); +const RootStack = createCustomStackNavigator(); // We want to delay the re-rendering for components(e.g. ReportActionCompose) // that depends on modal visibility until Modal is completely closed and its focused @@ -190,109 +191,84 @@ class AuthScreens extends React.Component { } render() { - const commonScreenOptions = { - headerShown: false, - gestureDirection: 'horizontal', - animationEnabled: true, - cardStyleInterpolator: (props) => modalCardStyleInterpolator(this.props.isSmallScreenWidth, false, props), - cardOverlayEnabled: true, - animationTypeForReplace: 'push', - }; - - const rightModalNavigatorScreenOptions = { - ...commonScreenOptions, - // we want pop in RHP since there are some flows that would work weird otherwise - animationTypeForReplace: 'pop', - cardStyle: styles.navigationModalCard(this.props.isSmallScreenWidth), - }; + const screenOptions = getRootNavigatorScreenOptions(this.props.isSmallScreenWidth); return ( - - { - const SidebarScreen = require('../../../pages/home/sidebar/SidebarScreen').default; - return SidebarScreen; - }} - /> - modalCardStyleInterpolator(this.props.isSmallScreenWidth, false, props), - }} - component={CentralPaneNavigator} - /> - { - const ValidateLoginPage = require('../../../pages/ValidateLoginPage').default; - return ValidateLoginPage; - }} - /> - { - const LogOutPreviousUserPage = require('../../../pages/LogOutPreviousUserPage').default; - return LogOutPreviousUserPage; - }} - /> - { - const ConciergePage = require('../../../pages/ConciergePage').default; - return ConciergePage; - }} - /> - { - const ReportAttachments = require('../../../pages/home/report/ReportAttachments').default; - return ReportAttachments; - }} - listeners={modalScreenListeners} - /> - - - + + + { + const SidebarScreen = require('../../../pages/home/sidebar/SidebarScreen').default; + return SidebarScreen; + }} + /> + + { + const ValidateLoginPage = require('../../../pages/ValidateLoginPage').default; + return ValidateLoginPage; + }} + /> + { + const LogOutPreviousUserPage = require('../../../pages/LogOutPreviousUserPage').default; + return LogOutPreviousUserPage; + }} + /> + { + const ConciergePage = require('../../../pages/ConciergePage').default; + return ConciergePage; + }} + /> + { + const ReportAttachments = require('../../../pages/home/report/ReportAttachments').default; + return ReportAttachments; + }} + listeners={modalScreenListeners} + /> + + + + ); } } diff --git a/src/libs/Navigation/AppNavigator/Navigators/FullScreenNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/FullScreenNavigator.js deleted file mode 100644 index 4ff19e6307b1..000000000000 --- a/src/libs/Navigation/AppNavigator/Navigators/FullScreenNavigator.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import {createStackNavigator} from '@react-navigation/stack'; - -import SCREENS from '../../../../SCREENS'; -import NotFoundPage from '../../../../pages/ErrorPage/NotFoundPage'; - -const Stack = createStackNavigator(); - -function FullScreenNavigator() { - return ( - - - - ); -} - -export default FullScreenNavigator; diff --git a/src/libs/Navigation/AppNavigator/Navigators/Overlay.js b/src/libs/Navigation/AppNavigator/Navigators/Overlay.js new file mode 100644 index 000000000000..a5f7e3206473 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/Navigators/Overlay.js @@ -0,0 +1,40 @@ +import React from 'react'; +import {Pressable, StyleSheet, Animated} from 'react-native'; +import {useCardAnimation} from '@react-navigation/stack'; + +import PropTypes from 'prop-types'; +import variables from '../../../../styles/variables'; +import themeColors from '../../../../styles/themes/default'; +import styles from '../../../../styles/styles'; + +const propTypes = { + /* Callback to close the modal */ + onPress: PropTypes.func.isRequired, +}; + +function Overlay(props) { + const {current} = useCardAnimation(); + + const overlayStyles = { + ...StyleSheet.absoluteFillObject, + backgroundColor: themeColors.overlay, + opacity: current.progress.interpolate({ + inputRange: [0, 1], + outputRange: [0, variables.overlayOpacity], + extrapolate: 'clamp', + }), + }; + return ( + + + + ); +} + +Overlay.propTypes= propTypes; +Overlay.displayName = 'Overlay'; + +export default Overlay; diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js index 7b22475bc623..d21a65768a0e 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js +++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js @@ -1,96 +1,123 @@ import React from 'react'; +import {View} from 'react-native'; import {createStackNavigator} from '@react-navigation/stack'; import * as ModalStackNavigators from '../ModalStackNavigators'; import RHPScreenOptions from '../RHPScreenOptions'; +import useWindowDimensions from '../../../../hooks/useWindowDimensions'; +import variables from '../../../../styles/variables'; +import {withNavigationPropTypes} from '../../../../components/withNavigation'; +import styles from '../../../../styles/styles'; +import Overlay from './Overlay'; const Stack = createStackNavigator(); -function RigthModalNavigator() { +const propTypes = { + ...withNavigationPropTypes, +}; + +function RightModalNavigator(props) { + const {isSmallScreenWidth} = useWindowDimensions(); + return ( - - - - - - - - - - - - - - - - - - - - - - + <> + {!isSmallScreenWidth && } + + + + + + + + + + + + + + + + + + + + + + + + + ); } -export default RigthModalNavigator; +RightModalNavigator.propTypes = propTypes; +RightModalNavigator.displayName = 'RightModalNavigator'; + +export default RightModalNavigator; diff --git a/src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/CustomRouter.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.js similarity index 97% rename from src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/CustomRouter.js rename to src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.js index 369d5061c445..a3d8398a22b0 100644 --- a/src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/CustomRouter.js +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.js @@ -27,7 +27,7 @@ function CustomRouter(options) { ...stackRouter, getRehydratedState(partialState, {routeNames, routeParamList}) { // Make sure that there is at least one CentralPaneNavigator (ReportScreen by default) in the state if this is a wide layout - if (!isAtLeastOneCentralPaneNavigatorInState(partialState) && !options.isSmallScreenWidth) { + if (!isAtLeastOneCentralPaneNavigatorInState(partialState) && !options.getIsSmallScreenWidth()) { // If we added a route we need to make sure that the state.stale is true to generate new key for this route // eslint-disable-next-line no-param-reassign partialState.stale = true; diff --git a/src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/index.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js similarity index 77% rename from src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/index.js rename to src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js index fa2c2d6b0558..80586ed35ddd 100644 --- a/src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/index.js +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js @@ -1,8 +1,7 @@ -import * as React from 'react'; +import React, {useRef, useEffect} from 'react'; import PropTypes from 'prop-types'; import {useNavigationBuilder, createNavigatorFactory} from '@react-navigation/native'; import {StackView} from '@react-navigation/stack'; -import ThreePaneView from './ThreePaneView'; import CustomRouter from './CustomRouter'; const propTypes = { @@ -25,15 +24,21 @@ const defaultProps = { screenOptions: undefined, }; + function ResponsiveStackNavigator(props) { + const isSmallScreenWidthRef = useRef(props.isSmallScreenWidth); const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder(CustomRouter, { children: props.children, screenOptions: props.screenOptions, initialRouteName: props.initialRouteName, - isSmallScreenWidth: props.isSmallScreenWidth, + getIsSmallScreenWidth: () => isSmallScreenWidthRef.current, }); - return props.isSmallScreenWidth ? ( + useEffect(() => { + isSmallScreenWidthRef.current = props.isSmallScreenWidth; + }, [props.isSmallScreenWidth, isSmallScreenWidthRef]); + + return ( - ) : ( - - - ); } diff --git a/src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/ThreePaneView.js b/src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/ThreePaneView.js deleted file mode 100644 index d5555b83ea94..000000000000 --- a/src/libs/Navigation/AppNavigator/createResponsiveStackNavigator/ThreePaneView.js +++ /dev/null @@ -1,88 +0,0 @@ -import * as React from 'react'; -import _ from 'underscore'; -import {View, Pressable} from 'react-native'; -import PropTypes from 'prop-types'; -import SCREENS from '../../../../SCREENS'; -import themeColors from '../../../../styles/themes/default'; -import NAVIGATORS from '../../../../NAVIGATORS'; -import * as StyleUtils from '../../../../styles/StyleUtils'; -import {withNavigationPropTypes} from '../../../../components/withNavigation'; -import styles from '../../../../styles/styles'; -import CONST from '../../../../CONST'; - -const propTypes = { - /* State from useNavigationBuilder */ - // eslint-disable-next-line react/forbid-prop-types - state: PropTypes.object.isRequired, - - /* Descriptors from useNavigationBuilder */ - // eslint-disable-next-line react/forbid-prop-types - descriptors: PropTypes.object.isRequired, - - ...withNavigationPropTypes, -}; - -function ThreePaneView(props) { - const lastCentralPaneIndex = _.findLastIndex(props.state.routes, {name: NAVIGATORS.CENTRAL_PANE_NAVIGATOR}); - - return ( - - {_.map(props.state.routes, (route, i) => { - if (route.name === SCREENS.HOME) { - return ( - - {props.descriptors[route.key].render()} - - ); - } - if (route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR) { - return ( - - {props.descriptors[route.key].render()} - - ); - } - if (route.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR) { - return ( - - props.navigation.goBack()} - /> - {props.descriptors[route.key].render()} - - ); - } - return ( - - {props.descriptors[route.key].render()} - - ); - })} - - ); -} - -ThreePaneView.propTypes = propTypes; -ThreePaneView.displayName = 'ThreePaneView'; - -export default ThreePaneView; diff --git a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js new file mode 100644 index 000000000000..eaf68b8993f0 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js @@ -0,0 +1,64 @@ +import modalCardStyleInterpolator from './modalCardStyleInterpolator'; +import styles from '../../../styles/styles'; +import variables from '../../../styles/variables'; + +const commonScreenOptions = { + headerShown: false, + gestureDirection: 'horizontal', + animationEnabled: true, + cardOverlayEnabled: true, + animationTypeForReplace: 'push', +}; + +export default (isSmallScreenWidth) => ({ + rightModalNavigator: { + ...commonScreenOptions, + cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, false, props), + presentation: 'transparentModal', + + // we want pop in RHP since there are some flows that would work weird otherwise + animationTypeForReplace: 'pop', + cardStyle: { + ...styles.cardStyleNavigator, + + // This is necessary to cover translated sidebar with overlay. + marginLeft: isSmallScreenWidth ? 0 : -2 * variables.sideBarWidth, + }, + }, + + homeScreen: { + title: 'New Expensify', + ...commonScreenOptions, + cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, false, props), + + // Prevent unnecessary scrolling + cardStyle: { + ...styles.cardStyleNavigator, + width: isSmallScreenWidth ? '100%' : variables.sideBarWidth, + + // We need to translate the sidebar to not be covered by the StackNavigator so it can be clickable. + transform: [{translateX: isSmallScreenWidth ? 0 : -variables.sideBarWidth}], + ...(isSmallScreenWidth ? {} : styles.borderRight), + }, + }, + // eslint-disable-next-line rulesdir/no-negated-variables + notFoundScreen: { + ...commonScreenOptions, + cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, true, props), + cardStyle: { + ...styles.cardStyleNavigator, + + // This is necessary to cover whole screen. Including translated sidebar. + marginLeft: isSmallScreenWidth ? 0 : -variables.sideBarWidth, + }, + }, + + centralPaneNavigator: { + title: 'New Expensify', + ...commonScreenOptions, + cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, true, props), + + // Prevent unnecessary scrolling + cardStyle: styles.cardStyleNavigator, + }, +}); diff --git a/src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.js b/src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.js index d2de1ba23a01..ec442efbba86 100644 --- a/src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.js +++ b/src/libs/Navigation/AppNavigator/modalCardStyleInterpolator.js @@ -1,7 +1,6 @@ import {Animated} from 'react-native'; import variables from '../../../styles/variables'; import getCardStyles from '../../../styles/cardStyles'; -import themeColors from '../../../styles/themes/default'; export default (isSmallScreenWidth, isFullScreenModal, {current: {progress}, inverted, layouts: {screen}}) => { const translateX = Animated.multiply( @@ -13,12 +12,9 @@ export default (isSmallScreenWidth, isFullScreenModal, {current: {progress}, inv inverted, ); - const opacity = Animated.multiply(progress, inverted); - const cardStyle = getCardStyles(isSmallScreenWidth, screen.width); + const cardStyle = getCardStyles(screen.width); - if (isFullScreenModal && !isSmallScreenWidth) { - cardStyle.opacity = opacity; - } else { + if (!isFullScreenModal || isSmallScreenWidth) { cardStyle.transform = [{translateX}]; } @@ -27,13 +23,5 @@ export default (isSmallScreenWidth, isFullScreenModal, {current: {progress}, inv overflow: 'hidden', }, cardStyle, - overlayStyle: { - backgroundColor: themeColors.overlay, - opacity: progress.interpolate({ - inputRange: [0, 1], - outputRange: [0, variables.overlayOpacity], - extrapolate: 'clamp', - }), - }, }; }; diff --git a/src/libs/Navigation/NavigationRoot.js b/src/libs/Navigation/NavigationRoot.js index 23c320eb991c..42d6627d6699 100644 --- a/src/libs/Navigation/NavigationRoot.js +++ b/src/libs/Navigation/NavigationRoot.js @@ -52,7 +52,6 @@ function parseAndLogRoute(state) { function NavigationRoot(props) { useFlipper(navigationRef); - const navigationStateRef = useRef(undefined); const firstRenderRef = useRef(true); const {updateCurrentReportID} = useCurrentReportID(); @@ -72,6 +71,14 @@ function NavigationRoot(props) { Navigation.setShouldPopAllStateOnUP(); }, [isSmallScreenWidth]); + useEffect(() => { + if (!navigationRef.isReady()) { + return; + } + // We need to force state rehydration so the CustomRouter can add the CentralPaneNavigator route if necessary. + navigationRef.resetRoot(navigationRef.getRootState()); + }, [isSmallScreenWidth]); + const prevStatusBarBackgroundColor = useRef(themeColors.appBG); const statusBarBackgroundColor = useRef(themeColors.appBG); const statusBarAnimation = useSharedValue(0); @@ -105,11 +112,10 @@ function NavigationRoot(props) { ); }; - const updateSavedNavigationStateAndLogRoute = (state) => { + const handleStateChange = (state) => { if (!state) { return; } - navigationStateRef.current = state; updateCurrentReportID(state); parseAndLogRoute(state); animateStatusBarBackgroundColor(); @@ -117,9 +123,7 @@ function NavigationRoot(props) { return ( Date: Fri, 7 Jul 2023 18:27:32 +0200 Subject: [PATCH 002/394] add temporary patch to never detach HomeScreen --- patches/@react-navigation+stack+6.3.16.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 patches/@react-navigation+stack+6.3.16.patch diff --git a/patches/@react-navigation+stack+6.3.16.patch b/patches/@react-navigation+stack+6.3.16.patch new file mode 100644 index 000000000000..2cd7f5a30a46 --- /dev/null +++ b/patches/@react-navigation+stack+6.3.16.patch @@ -0,0 +1,19 @@ +diff --git a/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js b/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js +index 95e6871..18bb14d 100644 +--- a/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js ++++ b/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js +@@ -353,6 +353,14 @@ export default class CardStack extends React.Component { + extrapolate: 'clamp' + }) : STATE_TRANSITIONING_OR_BELOW_TOP; + } ++ ++ if (route.name === 'Home' && isScreenActive !== STATE_ON_TOP) { ++ isScreenActive = STATE_TRANSITIONING_OR_BELOW_TOP; ++ } ++ ++ ++ ++ + const { + headerShown = true, + headerTransparent, From c7e411bb5ff240f74375949a842900972696a971 Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Fri, 7 Jul 2023 18:28:49 +0200 Subject: [PATCH 003/394] add prettier adjustments --- src/libs/Navigation/AppNavigator/Navigators/Overlay.js | 2 +- .../Navigation/AppNavigator/createCustomStackNavigator/index.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/Navigators/Overlay.js b/src/libs/Navigation/AppNavigator/Navigators/Overlay.js index a5f7e3206473..e17576ef2897 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/Overlay.js +++ b/src/libs/Navigation/AppNavigator/Navigators/Overlay.js @@ -34,7 +34,7 @@ function Overlay(props) { ); } -Overlay.propTypes= propTypes; +Overlay.propTypes = propTypes; Overlay.displayName = 'Overlay'; export default Overlay; diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js index 80586ed35ddd..59c4f3650c97 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js @@ -24,7 +24,6 @@ const defaultProps = { screenOptions: undefined, }; - function ResponsiveStackNavigator(props) { const isSmallScreenWidthRef = useRef(props.isSmallScreenWidth); const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder(CustomRouter, { From 35a1a5d42af047a54bde7b8933329cfae9c5b1ab Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Mon, 10 Jul 2023 18:02:33 +0200 Subject: [PATCH 004/394] update comments --- .../Navigation/AppNavigator/createCustomStackNavigator/index.js | 1 + .../Navigation/AppNavigator/getRootNavigatorScreenOptions.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js index 59c4f3650c97..e213f0873dd7 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js @@ -33,6 +33,7 @@ function ResponsiveStackNavigator(props) { getIsSmallScreenWidth: () => isSmallScreenWidthRef.current, }); + // Options for useNavigationBuilder won't update on prop change, so we need to pass a getter for the router to have the current state of isSmallScreenWidth. useEffect(() => { isSmallScreenWidthRef.current = props.isSmallScreenWidth; }, [props.isSmallScreenWidth, isSmallScreenWidthRef]); diff --git a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js index eaf68b8993f0..4c88819009fe 100644 --- a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js +++ b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js @@ -16,7 +16,7 @@ export default (isSmallScreenWidth) => ({ cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, false, props), presentation: 'transparentModal', - // we want pop in RHP since there are some flows that would work weird otherwise + // We want pop in RHP since there are some flows that would work weird otherwise animationTypeForReplace: 'pop', cardStyle: { ...styles.cardStyleNavigator, From 36914d53b045c6816a98c06129860966b00c706f Mon Sep 17 00:00:00 2001 From: Adam Grzybowski <67908363+adamgrzybowski@users.noreply.github.com> Date: Tue, 11 Jul 2023 12:45:47 +0200 Subject: [PATCH 005/394] Update patches/@react-navigation+stack+6.3.16.patch Co-authored-by: Vit Horacek <36083550+mountiny@users.noreply.github.com> --- patches/@react-navigation+stack+6.3.16.patch | 3 --- 1 file changed, 3 deletions(-) diff --git a/patches/@react-navigation+stack+6.3.16.patch b/patches/@react-navigation+stack+6.3.16.patch index 2cd7f5a30a46..cfd8f60a9917 100644 --- a/patches/@react-navigation+stack+6.3.16.patch +++ b/patches/@react-navigation+stack+6.3.16.patch @@ -10,9 +10,6 @@ index 95e6871..18bb14d 100644 + if (route.name === 'Home' && isScreenActive !== STATE_ON_TOP) { + isScreenActive = STATE_TRANSITIONING_OR_BELOW_TOP; + } -+ -+ -+ + const { headerShown = true, From 17248f5512409c3587590d62a908584b59fd703f Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Tue, 11 Jul 2023 12:49:18 +0200 Subject: [PATCH 006/394] change name for style object --- .../Navigation/AppNavigator/Navigators/RightModalNavigator.js | 2 +- src/styles/styles.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js index 9c6e4643246f..95c32523b362 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js +++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js @@ -24,7 +24,7 @@ function RightModalNavigator(props) { {!isSmallScreenWidth && } Date: Wed, 12 Jul 2023 12:28:43 +0200 Subject: [PATCH 007/394] fix patch --- patches/@react-navigation+stack+6.3.16.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/@react-navigation+stack+6.3.16.patch b/patches/@react-navigation+stack+6.3.16.patch index cfd8f60a9917..fe0f735cd325 100644 --- a/patches/@react-navigation+stack+6.3.16.patch +++ b/patches/@react-navigation+stack+6.3.16.patch @@ -1,12 +1,12 @@ diff --git a/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js b/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js -index 95e6871..18bb14d 100644 +index 95e6871..c87c0f6 100644 --- a/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js +++ b/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js -@@ -353,6 +353,14 @@ export default class CardStack extends React.Component { +@@ -353,6 +353,11 @@ export default class CardStack extends React.Component { extrapolate: 'clamp' }) : STATE_TRANSITIONING_OR_BELOW_TOP; } -+ ++ + if (route.name === 'Home' && isScreenActive !== STATE_ON_TOP) { + isScreenActive = STATE_TRANSITIONING_OR_BELOW_TOP; + } From a897f6281e8e01124f0ecd011216623c4e6350f2 Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Thu, 13 Jul 2023 17:59:49 +0200 Subject: [PATCH 008/394] improve patch for stack --- patches/@react-navigation+stack+6.3.16.patch | 28 +++++++++++++++---- .../getRootNavigatorScreenOptions.js | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/patches/@react-navigation+stack+6.3.16.patch b/patches/@react-navigation+stack+6.3.16.patch index fe0f735cd325..7e63e0f1b45c 100644 --- a/patches/@react-navigation+stack+6.3.16.patch +++ b/patches/@react-navigation+stack+6.3.16.patch @@ -1,16 +1,32 @@ diff --git a/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js b/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js -index 95e6871..c87c0f6 100644 +index 95e6871..5483c93 100644 --- a/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js +++ b/node_modules/@react-navigation/stack/lib/module/views/Stack/CardStack.js -@@ -353,6 +353,11 @@ export default class CardStack extends React.Component { +@@ -353,6 +353,9 @@ export default class CardStack extends React.Component { extrapolate: 'clamp' }) : STATE_TRANSITIONING_OR_BELOW_TOP; } -+ -+ if (route.name === 'Home' && isScreenActive !== STATE_ON_TOP) { -+ isScreenActive = STATE_TRANSITIONING_OR_BELOW_TOP; -+ } ++ ++ const isHomeScreenAndNotOnTop = route.name === 'Home' && isScreenActive !== STATE_ON_TOP; + const { headerShown = true, headerTransparent, +@@ -386,7 +389,7 @@ export default class CardStack extends React.Component { + key: route.key, + style: StyleSheet.absoluteFill, + enabled: detachInactiveScreens, +- active: isScreenActive, ++ active: isHomeScreenAndNotOnTop ? STATE_TRANSITIONING_OR_BELOW_TOP : isScreenActive, + freezeOnBlur: freezeOnBlur, + pointerEvents: "box-none" + }, /*#__PURE__*/React.createElement(CardContainer, { +@@ -420,7 +423,7 @@ export default class CardStack extends React.Component { + onTransitionStart: onTransitionStart, + onTransitionEnd: onTransitionEnd, + isNextScreenTransparent: isNextScreenTransparent, +- detachCurrentScreen: detachCurrentScreen ++ detachCurrentScreen: isHomeScreenAndNotOnTop ? false : detachCurrentScreen + })); + })), isFloatHeaderAbsolute ? floatingHeader : null); + } diff --git a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js index 4c88819009fe..8cddc863cc5f 100644 --- a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js +++ b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js @@ -56,6 +56,7 @@ export default (isSmallScreenWidth) => ({ centralPaneNavigator: { title: 'New Expensify', ...commonScreenOptions, + animationEnabled: isSmallScreenWidth ? true : false, cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, true, props), // Prevent unnecessary scrolling From 59650dc7cd44593d06b560d590af2d1bf5cf7f87 Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Thu, 13 Jul 2023 18:04:25 +0200 Subject: [PATCH 009/394] use better syntax --- .../Navigation/AppNavigator/getRootNavigatorScreenOptions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js index 8cddc863cc5f..56f7e5bea203 100644 --- a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js +++ b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.js @@ -56,7 +56,7 @@ export default (isSmallScreenWidth) => ({ centralPaneNavigator: { title: 'New Expensify', ...commonScreenOptions, - animationEnabled: isSmallScreenWidth ? true : false, + animationEnabled: isSmallScreenWidth, cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, true, props), // Prevent unnecessary scrolling From 59af4db7669ebeb90b57fe854bdb1850256d8bc3 Mon Sep 17 00:00:00 2001 From: dhairyasenjaliya Date: Tue, 18 Jul 2023 14:42:52 +0530 Subject: [PATCH 010/394] Added Save the world route --- src/ROUTES.js | 1 + src/languages/en.js | 6 ++ src/languages/es.js | 6 ++ .../AppNavigator/ModalStackNavigators.js | 11 +++ .../Navigators/RightModalNavigator.js | 4 ++ src/libs/Navigation/linkingConfig.js | 5 ++ src/pages/TeachersUnite/SaveTheWorld.js | 71 +++++++++++++++++++ .../FloatingActionButtonAndPopover.js | 5 ++ 8 files changed, 109 insertions(+) create mode 100644 src/pages/TeachersUnite/SaveTheWorld.js diff --git a/src/ROUTES.js b/src/ROUTES.js index b853c42248c6..6e49d91e833c 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -113,6 +113,7 @@ export default { FLAG_COMMENT: `flag/:reportID/:reportActionID`, getFlagCommentRoute: (reportID, reportActionID) => `flag/${reportID}/${reportActionID}`, SEARCH: 'search', + SAVE_THE_WORLD: 'saveTheWorld', DETAILS: 'details', getDetailsRoute: (login) => `details?login=${encodeURIComponent(login)}`, PROFILE: 'a/:accountID', diff --git a/src/languages/en.js b/src/languages/en.js index 064e4aa08c26..56caf75efde7 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -340,6 +340,7 @@ export default { draftedMessage: 'Drafted message', listOfChatMessages: 'List of chat messages', listOfChats: 'List of chats', + saveTheWorld: 'Save the world', }, iou: { amount: 'Amount', @@ -1484,4 +1485,9 @@ export default { levelTwoResult: 'Message hidden from channel, plus anonymous warning and message is reported for review.', levelThreeResult: 'Message removed from channel plus anonymous warning and message is reported for review.', }, + teachersUnitePage: { + teachersUnite: 'Teachers unite!', + iKnowATeacher: 'I know a teacher', + iAmATeacher: 'I am a teacher', + }, }; diff --git a/src/languages/es.js b/src/languages/es.js index b05c74b26222..cb56b54b5e39 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -339,6 +339,7 @@ export default { draftedMessage: 'Mensaje borrador', listOfChatMessages: 'Lista de mensajes del chat', listOfChats: 'lista de chats', + saveTheWorld: 'Salvar el mundo', }, iou: { amount: 'Importe', @@ -1955,4 +1956,9 @@ export default { levelTwoResult: 'Mensaje ocultado del canal, más advertencia anónima y mensaje reportado para revisión.', levelThreeResult: 'Mensaje eliminado del canal, más advertencia anónima y mensaje reportado para revisión.', }, + teachersUnitePage: { + teachersUnite: '¡Las maestras se unen!', + iKnowATeacher: 'yo conozco a un maestro', + iAmATeacher: 'Soy profesora', + }, }; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 732ec938e8ae..4d745d95964f 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -296,6 +296,16 @@ const NewTaskModalStackNavigator = createModalStackNavigator([ }, ]); +const NewTeachersUniteNavigator = createModalStackNavigator([ + { + getComponent: () => { + const SaveTheWorldPage = require('../../../pages/TeachersUnite/SaveTheWorld').default; + return SaveTheWorldPage; + }, + name: 'SaveTheWorld_Root', + }, +]); + const SettingsModalStackNavigator = createModalStackNavigator([ { getComponent: () => { @@ -739,4 +749,5 @@ export { WalletStatementStackNavigator, FlagCommentStackNavigator, EditRequestStackNavigator, + NewTeachersUniteNavigator, }; diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js index 7d6d4cb2709c..3e8cf0b5ebd4 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js +++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js @@ -65,6 +65,10 @@ function RigthModalNavigator() { name="NewTask" component={ModalStackNavigators.NewTaskModalStackNavigator} /> + Navigation.goBack()} + backgroundColor={themeColors.PAGE_BACKGROUND_COLORS[SCREENS.SETTINGS.PREFERENCES]} + illustration={LottieAnimations.PreferencesDJ} + > + + + + {translate('preferencesPage.receiveRelevantFeatureUpdatesAndExpensifyNews')} + + + Navigation.navigate(ROUTES)} + /> + + Navigation.navigate(ROUTES)} + /> + + + ); +} + +SaveTheWorldPage.propTypes = propTypes; +SaveTheWorldPage.defaultProps = defaultProps; +SaveTheWorldPage.displayName = 'SaveTheWorldPage'; + +export default withOnyx({ + user: { + key: ONYXKEYS.USER, + }, +})(SaveTheWorldPage); diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js index 3e95818c1137..5b475394f8ca 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.js @@ -216,6 +216,11 @@ function FloatingActionButtonAndPopover(props) { text: props.translate('iou.requestMoney'), onSelected: () => interceptAnonymousUser(() => IOU.startMoneyRequest(CONST.IOU.MONEY_REQUEST_TYPE.REQUEST)), }, + { + icon: Expensicons.Hashtag, + text: props.translate('sidebarScreen.saveTheWorld'), + onSelected: () => interceptAnonymousUser(() => Navigation.navigate(ROUTES.SAVE_THE_WORLD)), + }, { icon: Expensicons.Receipt, text: props.translate('iou.splitBill'), From bdbba2fdb15e23d87b09408da71122bb980c0a31 Mon Sep 17 00:00:00 2001 From: dhairyasenjaliya Date: Tue, 18 Jul 2023 15:34:02 +0530 Subject: [PATCH 011/394] Improve Save the world route & add translate --- src/languages/en.js | 1 + src/languages/es.js | 1 + .../AppNavigator/ModalStackNavigators.js | 2 +- .../{SaveTheWorld.js => SaveTheWorldPage.js} | 31 +++++++++---------- 4 files changed, 17 insertions(+), 18 deletions(-) rename src/pages/TeachersUnite/{SaveTheWorld.js => SaveTheWorldPage.js} (68%) diff --git a/src/languages/en.js b/src/languages/en.js index 56caf75efde7..7c10801a262e 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1487,6 +1487,7 @@ export default { }, teachersUnitePage: { teachersUnite: 'Teachers unite!', + joinExpensifyOrg: 'Join Expensify.org in eliminating injustice around the world and help teachers split their expenses for classrooms in need!', iKnowATeacher: 'I know a teacher', iAmATeacher: 'I am a teacher', }, diff --git a/src/languages/es.js b/src/languages/es.js index cb56b54b5e39..f0938e2211e5 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -1958,6 +1958,7 @@ export default { }, teachersUnitePage: { teachersUnite: '¡Las maestras se unen!', + joinExpensifyOrg: '¡Únase a Expensify.org para eliminar la injusticia en todo el mundo y ayude a los maestros a dividir sus gastos para las aulas necesitadas!', iKnowATeacher: 'yo conozco a un maestro', iAmATeacher: 'Soy profesora', }, diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 4d745d95964f..21bfcd77cdc0 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -299,7 +299,7 @@ const NewTaskModalStackNavigator = createModalStackNavigator([ const NewTeachersUniteNavigator = createModalStackNavigator([ { getComponent: () => { - const SaveTheWorldPage = require('../../../pages/TeachersUnite/SaveTheWorld').default; + const SaveTheWorldPage = require('../../../pages/TeachersUnite/SaveTheWorldPage').default; return SaveTheWorldPage; }, name: 'SaveTheWorld_Root', diff --git a/src/pages/TeachersUnite/SaveTheWorld.js b/src/pages/TeachersUnite/SaveTheWorldPage.js similarity index 68% rename from src/pages/TeachersUnite/SaveTheWorld.js rename to src/pages/TeachersUnite/SaveTheWorldPage.js index 846f54a0e7ef..c7af26d33197 100644 --- a/src/pages/TeachersUnite/SaveTheWorld.js +++ b/src/pages/TeachersUnite/SaveTheWorldPage.js @@ -38,24 +38,21 @@ function SaveTheWorldPage(props) { backgroundColor={themeColors.PAGE_BACKGROUND_COLORS[SCREENS.SETTINGS.PREFERENCES]} illustration={LottieAnimations.PreferencesDJ} > - - - - {translate('preferencesPage.receiveRelevantFeatureUpdatesAndExpensifyNews')} - - - Navigation.navigate(ROUTES)} - /> - - Navigation.navigate(ROUTES)} - /> + + {translate('teachersUnitePage.teachersUnite')} + {translate('teachersUnitePage.joinExpensifyOrg')} + Navigation.navigate(ROUTES)} + /> + + Navigation.navigate(ROUTES)} + /> ); } From e482d3c77ad4c7b1b8b59cfc93371f6cc9e8baea Mon Sep 17 00:00:00 2001 From: dhairyasenjaliya Date: Tue, 18 Jul 2023 17:15:17 +0530 Subject: [PATCH 012/394] Added I know a teacher route with form validation --- src/ONYXKEYS.js | 1 + src/ROUTES.js | 1 + src/languages/en.js | 6 + src/languages/es.js | 6 + .../AppNavigator/ModalStackNavigators.js | 7 + src/libs/Navigation/linkingConfig.js | 1 + src/pages/TeachersUnite/KnowATeacherPage.js | 135 ++++++++++++++++++ src/pages/TeachersUnite/SaveTheWorldPage.js | 2 +- 8 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/pages/TeachersUnite/KnowATeacherPage.js diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 4ca270518fd1..b413f048bab2 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -211,6 +211,7 @@ export default { EDIT_TASK_FORM: 'editTaskForm', MONEY_REQUEST_DESCRIPTION_FORM: 'moneyRequestDescriptionForm', NEW_CONTACT_METHOD_FORM: 'newContactMethodForm', + I_KNOW_A_TEACHER: 'iKnowTeacherForm', }, // Whether we should show the compose input or not diff --git a/src/ROUTES.js b/src/ROUTES.js index 6e49d91e833c..24e188bcbbed 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -114,6 +114,7 @@ export default { getFlagCommentRoute: (reportID, reportActionID) => `flag/${reportID}/${reportActionID}`, SEARCH: 'search', SAVE_THE_WORLD: 'saveTheWorld', + I_Know_A_TEACHER: 'saveTheWorld/i-know-a-teacher', DETAILS: 'details', getDetailsRoute: (login) => `details?login=${encodeURIComponent(login)}`, PROFILE: 'a/:accountID', diff --git a/src/languages/en.js b/src/languages/en.js index 7c10801a262e..7fe808da49c8 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -149,6 +149,7 @@ export default { someone: 'Someone', total: 'Total', edit: 'Edit', + letsDoThis: `Let's do this!`, }, anonymousReportFooter: { logoTagline: 'Join in on the discussion.', @@ -1490,5 +1491,10 @@ export default { joinExpensifyOrg: 'Join Expensify.org in eliminating injustice around the world and help teachers split their expenses for classrooms in need!', iKnowATeacher: 'I know a teacher', iAmATeacher: 'I am a teacher', + getInTouch: 'Excellent! Please share their information so we can get in touch with them.', + error: { + enterName: 'Enter a name', + enterPhoneEmail: 'Enter a valid email or phone number', + }, }, }; diff --git a/src/languages/es.js b/src/languages/es.js index f0938e2211e5..a4ff1face656 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -148,6 +148,7 @@ export default { someone: 'Alguien', total: 'Total', edit: 'Editar', + letsDoThis: '¡Hagámoslo!', }, anonymousReportFooter: { logoTagline: 'Únete a la discussion.', @@ -1961,5 +1962,10 @@ export default { joinExpensifyOrg: '¡Únase a Expensify.org para eliminar la injusticia en todo el mundo y ayude a los maestros a dividir sus gastos para las aulas necesitadas!', iKnowATeacher: 'yo conozco a un maestro', iAmATeacher: 'Soy profesora', + getInTouch: '¡Excelente! Por favor, comparta su información para que podamos ponernos en contacto con ellos.', + error: { + enterName: 'Ingresa un nombre', + enterPhoneEmail: 'Ingrese un correo electrónico o número de teléfono válido', + }, }, }; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 21bfcd77cdc0..9b61c83e2d96 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -304,6 +304,13 @@ const NewTeachersUniteNavigator = createModalStackNavigator([ }, name: 'SaveTheWorld_Root', }, + { + getComponent: () => { + const KnowATeacherPage = require('../../../pages/TeachersUnite/KnowATeacherPage').default; + return KnowATeacherPage; + }, + name: 'I_Know_A_Teacher', + }, ]); const SettingsModalStackNavigator = createModalStackNavigator([ diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 042b1e8ab561..c269f923d290 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -275,6 +275,7 @@ export default { TeachersUnite: { screens: { SaveTheWorld_Root: ROUTES.SAVE_THE_WORLD, + I_Know_A_Teacher: ROUTES.I_Know_A_TEACHER, }, }, Search: { diff --git a/src/pages/TeachersUnite/KnowATeacherPage.js b/src/pages/TeachersUnite/KnowATeacherPage.js new file mode 100644 index 000000000000..41087f85695e --- /dev/null +++ b/src/pages/TeachersUnite/KnowATeacherPage.js @@ -0,0 +1,135 @@ +import lodashGet from 'lodash/get'; +import React from 'react'; +import {View} from 'react-native'; +import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; +import ScreenWrapper from '../../components/ScreenWrapper'; +import {parsePhoneNumber} from 'awesome-phonenumber'; +import Str from 'expensify-common/lib/str'; +import HeaderWithBackButton from '../../components/HeaderWithBackButton'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import Form from '../../components/Form'; +import ONYXKEYS from '../../ONYXKEYS'; +import _ from 'underscore'; +import CONST from '../../CONST'; +import * as LoginUtils from '../../libs/LoginUtils'; +import TextInput from '../../components/TextInput'; +import Text from '../../components/Text'; +import styles from '../../styles/styles'; +import compose from '../../libs/compose'; +import * as ErrorUtils from '../../libs/ErrorUtils'; +import ROUTES from '../../ROUTES'; +import Navigation from '../../libs/Navigation/Navigation'; + +const propTypes = { + ...withLocalizePropTypes, + ...withCurrentUserPersonalDetailsPropTypes, +}; + +const defaultProps = { + ...withCurrentUserPersonalDetailsDefaultProps, +}; + +/** + * Submit form to update user's first and last name (and display name) + * @param {Object} values + * @param {String} values.firstName + * @param {String} values.lastName + * @param {String} values.phoneOrEmail + */ +const updateDisplayName = (values) => { + // PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); //ref +}; + +const getPhoneLogin = (phoneOrEmail) => { + if (_.isEmpty(phoneOrEmail)) { + return ''; + } + + return LoginUtils.appendCountryCode(LoginUtils.getPhoneNumberWithoutSpecialChars(phoneOrEmail)); +}; + +function KnowATeacherPage(props) { + const currentUserDetails = props.currentUserPersonalDetails || {}; + + /** + * @param {Object} values + * @param {String} values.firstName + * @param {String} values.phoneOrEmail + * @returns {Object} - An object containing the errors for each inputID + */ + const validate = (values) => { + const errors = {}; + const phoneLogin = getPhoneLogin(values.phoneOrEmail); + + if (_.isEmpty(values.firstName)) { + ErrorUtils.addErrorMessage(errors, 'firstName', props.translate('teachersUnitePage.error.enterName')); + } + if (_.isEmpty(values.phoneOrEmail)) { + ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', props.translate('teachersUnitePage.error.enterPhoneEmail')); + } + if (!_.isEmpty(values.phoneOrEmail) && !((parsePhoneNumber(phoneLogin).possible && Str.isValidPhone(phoneLogin.slice(0))) || Str.isValidEmail(values.phoneOrEmail))) { + ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', 'contacts.genericFailureMessages.invalidContactMethod'); + } + + return errors; + }; + + return ( + + Navigation.goBack(ROUTES.SAVE_THE_WORLD)} + /> +
+ {props.translate('teachersUnitePage.getInTouch')} + + + + + + + + + +
+
+ ); +} + +KnowATeacherPage.propTypes = propTypes; +KnowATeacherPage.defaultProps = defaultProps; +KnowATeacherPage.displayName = 'DisplayNamePage'; + +export default KnowATeacherPage; diff --git a/src/pages/TeachersUnite/SaveTheWorldPage.js b/src/pages/TeachersUnite/SaveTheWorldPage.js index c7af26d33197..9aa0bca9e192 100644 --- a/src/pages/TeachersUnite/SaveTheWorldPage.js +++ b/src/pages/TeachersUnite/SaveTheWorldPage.js @@ -45,7 +45,7 @@ function SaveTheWorldPage(props) { Navigation.navigate(ROUTES)} + onPress={() => Navigation.navigate(ROUTES.I_Know_A_TEACHER)} /> Date: Tue, 18 Jul 2023 17:16:56 +0530 Subject: [PATCH 013/394] Crash fix --- src/pages/TeachersUnite/KnowATeacherPage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/TeachersUnite/KnowATeacherPage.js b/src/pages/TeachersUnite/KnowATeacherPage.js index 41087f85695e..fd55cf05dc76 100644 --- a/src/pages/TeachersUnite/KnowATeacherPage.js +++ b/src/pages/TeachersUnite/KnowATeacherPage.js @@ -37,7 +37,7 @@ const defaultProps = { * @param {String} values.phoneOrEmail */ const updateDisplayName = (values) => { - // PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); //ref + PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); }; const getPhoneLogin = (phoneOrEmail) => { @@ -132,4 +132,4 @@ KnowATeacherPage.propTypes = propTypes; KnowATeacherPage.defaultProps = defaultProps; KnowATeacherPage.displayName = 'DisplayNamePage'; -export default KnowATeacherPage; +export default compose(withLocalize)(KnowATeacherPage); From b077a12dfb0d6224c65562ab5340ccba1e39ee4f Mon Sep 17 00:00:00 2001 From: dhairyasenjaliya Date: Tue, 18 Jul 2023 20:49:42 +0530 Subject: [PATCH 014/394] Added new route for intro principal --- src/ONYXKEYS.js | 1 + src/ROUTES.js | 1 + src/languages/en.js | 4 + src/languages/es.js | 4 + .../AppNavigator/ModalStackNavigators.js | 7 + src/libs/Navigation/linkingConfig.js | 1 + .../TeachersUnite/IntroSchoolPrincipalPage.js | 135 ++++++++++++++++++ src/pages/TeachersUnite/KnowATeacherPage.js | 12 +- src/pages/TeachersUnite/SaveTheWorldPage.js | 2 +- 9 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 src/pages/TeachersUnite/IntroSchoolPrincipalPage.js diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index b413f048bab2..69ef054a4dc4 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -212,6 +212,7 @@ export default { MONEY_REQUEST_DESCRIPTION_FORM: 'moneyRequestDescriptionForm', NEW_CONTACT_METHOD_FORM: 'newContactMethodForm', I_KNOW_A_TEACHER: 'iKnowTeacherForm', + INTRO_SCHOOL_PRINCIPAL: 'introSchoolPrincipal', }, // Whether we should show the compose input or not diff --git a/src/ROUTES.js b/src/ROUTES.js index 24e188bcbbed..c2c522ffba43 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -115,6 +115,7 @@ export default { SEARCH: 'search', SAVE_THE_WORLD: 'saveTheWorld', I_Know_A_TEACHER: 'saveTheWorld/i-know-a-teacher', + Intro_School_Principal: 'saveTheWorld/intro-school-principal', DETAILS: 'details', getDetailsRoute: (login) => `details?login=${encodeURIComponent(login)}`, PROFILE: 'a/:accountID', diff --git a/src/languages/en.js b/src/languages/en.js index 7fe808da49c8..f2b7931d53d6 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -150,6 +150,7 @@ export default { total: 'Total', edit: 'Edit', letsDoThis: `Let's do this!`, + letsStart: `Let's start`, }, anonymousReportFooter: { logoTagline: 'Join in on the discussion.', @@ -1492,6 +1493,9 @@ export default { iKnowATeacher: 'I know a teacher', iAmATeacher: 'I am a teacher', getInTouch: 'Excellent! Please share their information so we can get in touch with them.', + introSchoolPrincipal: 'Intro to your school principal', + schoolPrincipalVerfiyExpense: + 'Expensify.org splits the cost of essential school supplies so that students from low-income households can have a better learning experience. Your principal will be asked to verify your expenses.', error: { enterName: 'Enter a name', enterPhoneEmail: 'Enter a valid email or phone number', diff --git a/src/languages/es.js b/src/languages/es.js index a4ff1face656..e3f79920d05c 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -149,6 +149,7 @@ export default { total: 'Total', edit: 'Editar', letsDoThis: '¡Hagámoslo!', + letsStart: 'Empecemos', }, anonymousReportFooter: { logoTagline: 'Únete a la discussion.', @@ -1963,6 +1964,9 @@ export default { iKnowATeacher: 'yo conozco a un maestro', iAmATeacher: 'Soy profesora', getInTouch: '¡Excelente! Por favor, comparta su información para que podamos ponernos en contacto con ellos.', + introSchoolPrincipal: 'Introducción a la directora de tu escuela', + schoolPrincipalVerfiyExpense: + 'Expensify.org divide el costo de la escuela esencial insumos para que estudiantes de escasos recursos los hogares pueden tener una mejor experiencia de aprendizaje. Se le pedirá a su director que verifique su gastos.', error: { enterName: 'Ingresa un nombre', enterPhoneEmail: 'Ingrese un correo electrónico o número de teléfono válido', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 9b61c83e2d96..937b4b43d6f0 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -311,6 +311,13 @@ const NewTeachersUniteNavigator = createModalStackNavigator([ }, name: 'I_Know_A_Teacher', }, + { + getComponent: () => { + const IntroSchoolPrincipalPage = require('../../../pages/TeachersUnite/IntroSchoolPrincipalPage').default; + return IntroSchoolPrincipalPage; + }, + name: 'Intro_School_Principal', + }, ]); const SettingsModalStackNavigator = createModalStackNavigator([ diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index c269f923d290..1bc64982066e 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -276,6 +276,7 @@ export default { screens: { SaveTheWorld_Root: ROUTES.SAVE_THE_WORLD, I_Know_A_Teacher: ROUTES.I_Know_A_TEACHER, + Intro_School_Principal: ROUTES.Intro_School_Principal, }, }, Search: { diff --git a/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js b/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js new file mode 100644 index 000000000000..94be849361ce --- /dev/null +++ b/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js @@ -0,0 +1,135 @@ +import lodashGet from 'lodash/get'; +import React from 'react'; +import {View} from 'react-native'; +import {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; +import ScreenWrapper from '../../components/ScreenWrapper'; +import {parsePhoneNumber} from 'awesome-phonenumber'; +import Str from 'expensify-common/lib/str'; +import HeaderWithBackButton from '../../components/HeaderWithBackButton'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import Form from '../../components/Form'; +import ONYXKEYS from '../../ONYXKEYS'; +import _ from 'underscore'; +import CONST from '../../CONST'; +import * as LoginUtils from '../../libs/LoginUtils'; +import TextInput from '../../components/TextInput'; +import Text from '../../components/Text'; +import styles from '../../styles/styles'; +import compose from '../../libs/compose'; +import * as ErrorUtils from '../../libs/ErrorUtils'; +import ROUTES from '../../ROUTES'; +import Navigation from '../../libs/Navigation/Navigation'; + +const propTypes = { + ...withLocalizePropTypes, + ...withCurrentUserPersonalDetailsPropTypes, +}; + +const defaultProps = { + ...withCurrentUserPersonalDetailsDefaultProps, +}; + +/** + * Submit form to update user's first and last name (and display name) + * @param {Object} values + * @param {String} values.firstName + * @param {String} values.lastName + * @param {String} values.phoneOrEmail + */ +const updateDisplayName = (values) => { + // PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); +}; + +const getPhoneLogin = (phoneOrEmail) => { + if (_.isEmpty(phoneOrEmail)) { + return ''; + } + + return LoginUtils.appendCountryCode(LoginUtils.getPhoneNumberWithoutSpecialChars(phoneOrEmail)); +}; + +function IntroSchoolPrincipalPage(props) { + const currentUserDetails = props.currentUserPersonalDetails || {}; + + /** + * @param {Object} values + * @param {String} values.firstName + * @param {String} values.phoneOrEmail + * @returns {Object} - An object containing the errors for each inputID + */ + const validate = (values) => { + const errors = {}; + const phoneLogin = getPhoneLogin(values.phoneOrEmail); + + if (_.isEmpty(values.firstName)) { + ErrorUtils.addErrorMessage(errors, 'firstName', props.translate('teachersUnitePage.error.enterName')); + } + if (_.isEmpty(values.phoneOrEmail)) { + ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', props.translate('teachersUnitePage.error.enterPhoneEmail')); + } + if (!_.isEmpty(values.phoneOrEmail) && !((parsePhoneNumber(phoneLogin).possible && Str.isValidPhone(phoneLogin.slice(0))) || Str.isValidEmail(values.phoneOrEmail))) { + ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', 'contacts.genericFailureMessages.invalidContactMethod'); + } + + return errors; + }; + + return ( + + Navigation.goBack(ROUTES.SAVE_THE_WORLD)} + /> +
+ {props.translate('teachersUnitePage.schoolPrincipalVerfiyExpense')} + + + + + + + + + +
+
+ ); +} + +IntroSchoolPrincipalPage.propTypes = propTypes; +IntroSchoolPrincipalPage.defaultProps = defaultProps; +IntroSchoolPrincipalPage.displayName = 'IntroSchoolPrincipalPage'; + +export default compose(withLocalize)(IntroSchoolPrincipalPage); diff --git a/src/pages/TeachersUnite/KnowATeacherPage.js b/src/pages/TeachersUnite/KnowATeacherPage.js index fd55cf05dc76..4bc791c370d6 100644 --- a/src/pages/TeachersUnite/KnowATeacherPage.js +++ b/src/pages/TeachersUnite/KnowATeacherPage.js @@ -1,15 +1,15 @@ import lodashGet from 'lodash/get'; import React from 'react'; import {View} from 'react-native'; -import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; -import ScreenWrapper from '../../components/ScreenWrapper'; import {parsePhoneNumber} from 'awesome-phonenumber'; import Str from 'expensify-common/lib/str'; +import _ from 'underscore'; +import {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; +import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; import Form from '../../components/Form'; import ONYXKEYS from '../../ONYXKEYS'; -import _ from 'underscore'; import CONST from '../../CONST'; import * as LoginUtils from '../../libs/LoginUtils'; import TextInput from '../../components/TextInput'; @@ -37,7 +37,7 @@ const defaultProps = { * @param {String} values.phoneOrEmail */ const updateDisplayName = (values) => { - PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); + // PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); }; const getPhoneLogin = (phoneOrEmail) => { @@ -130,6 +130,6 @@ function KnowATeacherPage(props) { KnowATeacherPage.propTypes = propTypes; KnowATeacherPage.defaultProps = defaultProps; -KnowATeacherPage.displayName = 'DisplayNamePage'; +KnowATeacherPage.displayName = 'KnowATeacherPage'; -export default compose(withLocalize)(KnowATeacherPage); +export default withLocalize(KnowATeacherPage); diff --git a/src/pages/TeachersUnite/SaveTheWorldPage.js b/src/pages/TeachersUnite/SaveTheWorldPage.js index 9aa0bca9e192..f9459f91e1e2 100644 --- a/src/pages/TeachersUnite/SaveTheWorldPage.js +++ b/src/pages/TeachersUnite/SaveTheWorldPage.js @@ -51,7 +51,7 @@ function SaveTheWorldPage(props) { Navigation.navigate(ROUTES)} + onPress={() => Navigation.navigate(ROUTES.Intro_School_Principal)} /> ); From 2eb7e7c009036ae209a563fdda2751c821c3a46b Mon Sep 17 00:00:00 2001 From: dhairyasenjaliya Date: Tue, 18 Jul 2023 21:00:15 +0530 Subject: [PATCH 015/394] Eslint fix --- src/pages/TeachersUnite/IntroSchoolPrincipalPage.js | 11 +++++------ src/pages/TeachersUnite/KnowATeacherPage.js | 3 +-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js b/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js index 94be849361ce..348247157983 100644 --- a/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js +++ b/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js @@ -1,21 +1,20 @@ import lodashGet from 'lodash/get'; import React from 'react'; import {View} from 'react-native'; -import {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; -import ScreenWrapper from '../../components/ScreenWrapper'; import {parsePhoneNumber} from 'awesome-phonenumber'; import Str from 'expensify-common/lib/str'; +import _ from 'underscore'; +import {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; +import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; import Form from '../../components/Form'; import ONYXKEYS from '../../ONYXKEYS'; -import _ from 'underscore'; import CONST from '../../CONST'; import * as LoginUtils from '../../libs/LoginUtils'; import TextInput from '../../components/TextInput'; import Text from '../../components/Text'; import styles from '../../styles/styles'; -import compose from '../../libs/compose'; import * as ErrorUtils from '../../libs/ErrorUtils'; import ROUTES from '../../ROUTES'; import Navigation from '../../libs/Navigation/Navigation'; @@ -36,7 +35,7 @@ const defaultProps = { * @param {String} values.lastName * @param {String} values.phoneOrEmail */ -const updateDisplayName = (values) => { +const updateDisplayName = () => { // PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); }; @@ -132,4 +131,4 @@ IntroSchoolPrincipalPage.propTypes = propTypes; IntroSchoolPrincipalPage.defaultProps = defaultProps; IntroSchoolPrincipalPage.displayName = 'IntroSchoolPrincipalPage'; -export default compose(withLocalize)(IntroSchoolPrincipalPage); +export default withLocalize(IntroSchoolPrincipalPage); diff --git a/src/pages/TeachersUnite/KnowATeacherPage.js b/src/pages/TeachersUnite/KnowATeacherPage.js index 4bc791c370d6..0531f9ffbdd2 100644 --- a/src/pages/TeachersUnite/KnowATeacherPage.js +++ b/src/pages/TeachersUnite/KnowATeacherPage.js @@ -15,7 +15,6 @@ import * as LoginUtils from '../../libs/LoginUtils'; import TextInput from '../../components/TextInput'; import Text from '../../components/Text'; import styles from '../../styles/styles'; -import compose from '../../libs/compose'; import * as ErrorUtils from '../../libs/ErrorUtils'; import ROUTES from '../../ROUTES'; import Navigation from '../../libs/Navigation/Navigation'; @@ -36,7 +35,7 @@ const defaultProps = { * @param {String} values.lastName * @param {String} values.phoneOrEmail */ -const updateDisplayName = (values) => { +const updateDisplayName = () => { // PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); }; From 18273b77d5c1915cd0e1f7745a8cfaffa618ca07 Mon Sep 17 00:00:00 2001 From: dhairyasenjaliya Date: Tue, 18 Jul 2023 21:34:08 +0530 Subject: [PATCH 016/394] Added Validation --- src/languages/en.js | 5 ++ src/languages/es.js | 5 ++ .../TeachersUnite/IntroSchoolPrincipalPage.js | 50 +++++++------------ src/pages/TeachersUnite/KnowATeacherPage.js | 4 -- src/pages/TeachersUnite/SaveTheWorldPage.js | 3 +- 5 files changed, 28 insertions(+), 39 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index f2b7931d53d6..f3fd820424b3 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1496,9 +1496,14 @@ export default { introSchoolPrincipal: 'Intro to your school principal', schoolPrincipalVerfiyExpense: 'Expensify.org splits the cost of essential school supplies so that students from low-income households can have a better learning experience. Your principal will be asked to verify your expenses.', + principalFirstName: 'Principal first name', + principalLastName: 'Principal last name', + principalWorkEmail: 'Principal work email', error: { enterName: 'Enter a name', enterPhoneEmail: 'Enter a valid email or phone number', + enterEmail: 'Enter an email', + enterValidEmail: 'Enter a valid email', }, }, }; diff --git a/src/languages/es.js b/src/languages/es.js index e3f79920d05c..190ac89880f3 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -1967,9 +1967,14 @@ export default { introSchoolPrincipal: 'Introducción a la directora de tu escuela', schoolPrincipalVerfiyExpense: 'Expensify.org divide el costo de la escuela esencial insumos para que estudiantes de escasos recursos los hogares pueden tener una mejor experiencia de aprendizaje. Se le pedirá a su director que verifique su gastos.', + principalFirstName: 'Nombre principal', + principalLastName: 'Apellido principal', + principalWorkEmail: 'Correo electrónico de trabajo del director', error: { enterName: 'Ingresa un nombre', enterPhoneEmail: 'Ingrese un correo electrónico o número de teléfono válido', + enterEmail: 'Introduce un correo electrónico', + enterValidEmail: 'Introduzca un correo electrónico válido', }, }, }; diff --git a/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js b/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js index 348247157983..87a44fcb2992 100644 --- a/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js +++ b/src/pages/TeachersUnite/IntroSchoolPrincipalPage.js @@ -1,7 +1,5 @@ -import lodashGet from 'lodash/get'; import React from 'react'; import {View} from 'react-native'; -import {parsePhoneNumber} from 'awesome-phonenumber'; import Str from 'expensify-common/lib/str'; import _ from 'underscore'; import {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; @@ -11,7 +9,6 @@ import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize import Form from '../../components/Form'; import ONYXKEYS from '../../ONYXKEYS'; import CONST from '../../CONST'; -import * as LoginUtils from '../../libs/LoginUtils'; import TextInput from '../../components/TextInput'; import Text from '../../components/Text'; import styles from '../../styles/styles'; @@ -39,35 +36,24 @@ const updateDisplayName = () => { // PersonalDetails.updateDisplayName(values.firstName.trim(), values.lastName.trim()); }; -const getPhoneLogin = (phoneOrEmail) => { - if (_.isEmpty(phoneOrEmail)) { - return ''; - } - - return LoginUtils.appendCountryCode(LoginUtils.getPhoneNumberWithoutSpecialChars(phoneOrEmail)); -}; - function IntroSchoolPrincipalPage(props) { - const currentUserDetails = props.currentUserPersonalDetails || {}; - /** * @param {Object} values - * @param {String} values.firstName - * @param {String} values.phoneOrEmail + * @param {String} values.principalFirstName + * @param {String} values.principalEmail * @returns {Object} - An object containing the errors for each inputID */ const validate = (values) => { const errors = {}; - const phoneLogin = getPhoneLogin(values.phoneOrEmail); - if (_.isEmpty(values.firstName)) { - ErrorUtils.addErrorMessage(errors, 'firstName', props.translate('teachersUnitePage.error.enterName')); + if (_.isEmpty(values.principalFirstName)) { + ErrorUtils.addErrorMessage(errors, 'principalFirstName', props.translate('teachersUnitePage.error.enterName')); } - if (_.isEmpty(values.phoneOrEmail)) { - ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', props.translate('teachersUnitePage.error.enterPhoneEmail')); + if (_.isEmpty(values.principalEmail)) { + ErrorUtils.addErrorMessage(errors, 'principalEmail', props.translate('teachersUnitePage.error.enterEmail')); } - if (!_.isEmpty(values.phoneOrEmail) && !((parsePhoneNumber(phoneLogin).possible && Str.isValidPhone(phoneLogin.slice(0))) || Str.isValidEmail(values.phoneOrEmail))) { - ErrorUtils.addErrorMessage(errors, 'phoneOrEmail', 'contacts.genericFailureMessages.invalidContactMethod'); + if (!_.isEmpty(values.principalEmail) && !Str.isValidEmail(values.principalEmail)) { + ErrorUtils.addErrorMessage(errors, 'principalEmail', props.translate('teachersUnitePage.error.enterValidEmail')); } return errors; @@ -90,35 +76,33 @@ function IntroSchoolPrincipalPage(props) { {props.translate('teachersUnitePage.schoolPrincipalVerfiyExpense')} diff --git a/src/pages/TeachersUnite/KnowATeacherPage.js b/src/pages/TeachersUnite/KnowATeacherPage.js index 0531f9ffbdd2..baf862b98b3b 100644 --- a/src/pages/TeachersUnite/KnowATeacherPage.js +++ b/src/pages/TeachersUnite/KnowATeacherPage.js @@ -48,8 +48,6 @@ const getPhoneLogin = (phoneOrEmail) => { }; function KnowATeacherPage(props) { - const currentUserDetails = props.currentUserPersonalDetails || {}; - /** * @param {Object} values * @param {String} values.firstName @@ -95,7 +93,6 @@ function KnowATeacherPage(props) { label={props.translate('common.firstName')} accessibilityLabel={props.translate('common.firstName')} accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT} - defaultValue={lodashGet(currentUserDetails, 'firstName', '')} maxLength={CONST.DISPLAY_NAME.MAX_LENGTH} autoCapitalize="words" /> @@ -107,7 +104,6 @@ function KnowATeacherPage(props) { label={props.translate('common.lastName')} accessibilityLabel={props.translate('common.lastName')} accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT} - defaultValue={lodashGet(currentUserDetails, 'lastName', '')} maxLength={CONST.DISPLAY_NAME.MAX_LENGTH} autoCapitalize="words" /> diff --git a/src/pages/TeachersUnite/SaveTheWorldPage.js b/src/pages/TeachersUnite/SaveTheWorldPage.js index f9459f91e1e2..1a94ffd4688b 100644 --- a/src/pages/TeachersUnite/SaveTheWorldPage.js +++ b/src/pages/TeachersUnite/SaveTheWorldPage.js @@ -1,4 +1,3 @@ -import lodashGet from 'lodash/get'; import React from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; @@ -27,7 +26,7 @@ const defaultProps = { user: {}, }; -function SaveTheWorldPage(props) { +function SaveTheWorldPage() { const {translate} = useLocalize(); return ( From 65cc03822c85d0c92b5fa71eed47ed42d3ecd56a Mon Sep 17 00:00:00 2001 From: dhairyasenjaliya Date: Tue, 18 Jul 2023 21:39:10 +0530 Subject: [PATCH 017/394] remove unused import --- src/pages/TeachersUnite/KnowATeacherPage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/TeachersUnite/KnowATeacherPage.js b/src/pages/TeachersUnite/KnowATeacherPage.js index baf862b98b3b..3cd4d326a8eb 100644 --- a/src/pages/TeachersUnite/KnowATeacherPage.js +++ b/src/pages/TeachersUnite/KnowATeacherPage.js @@ -1,4 +1,3 @@ -import lodashGet from 'lodash/get'; import React from 'react'; import {View} from 'react-native'; import {parsePhoneNumber} from 'awesome-phonenumber'; From 491017317dbaa0c3831278d2c8edeae59c6a7fa6 Mon Sep 17 00:00:00 2001 From: dhairyasenjaliya Date: Tue, 18 Jul 2023 22:37:15 +0530 Subject: [PATCH 018/394] Added I am a teacher page --- src/ROUTES.js | 1 + src/languages/en.js | 2 + src/languages/es.js | 2 + .../AppNavigator/ModalStackNavigators.js | 7 +++ src/libs/Navigation/linkingConfig.js | 1 + src/pages/TeachersUnite/ImTeacherPage.js | 58 +++++++++++++++++++ src/pages/TeachersUnite/SaveTheWorldPage.js | 3 +- 7 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/pages/TeachersUnite/ImTeacherPage.js diff --git a/src/ROUTES.js b/src/ROUTES.js index c2c522ffba43..14331089e86c 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -116,6 +116,7 @@ export default { SAVE_THE_WORLD: 'saveTheWorld', I_Know_A_TEACHER: 'saveTheWorld/i-know-a-teacher', Intro_School_Principal: 'saveTheWorld/intro-school-principal', + I_Am_A_Teacher: 'saveTheWorld/i-am-a-teacher', DETAILS: 'details', getDetailsRoute: (login) => `details?login=${encodeURIComponent(login)}`, PROFILE: 'a/:accountID', diff --git a/src/languages/en.js b/src/languages/en.js index f3fd820424b3..cf91559bccda 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1499,6 +1499,8 @@ export default { principalFirstName: 'Principal first name', principalLastName: 'Principal last name', principalWorkEmail: 'Principal work email', + updateYourEmail: 'Update your email address', + updateEmail: 'Update email address', error: { enterName: 'Enter a name', enterPhoneEmail: 'Enter a valid email or phone number', diff --git a/src/languages/es.js b/src/languages/es.js index 190ac89880f3..a84bf2b36e24 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -1970,6 +1970,8 @@ export default { principalFirstName: 'Nombre principal', principalLastName: 'Apellido principal', principalWorkEmail: 'Correo electrónico de trabajo del director', + updateYourEmail: 'Actualiza tu dirección de correo electrónico', + updateEmail: 'Actualización de la dirección de correo electrónico', error: { enterName: 'Ingresa un nombre', enterPhoneEmail: 'Ingrese un correo electrónico o número de teléfono válido', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 937b4b43d6f0..86dfce4f7de0 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -318,6 +318,13 @@ const NewTeachersUniteNavigator = createModalStackNavigator([ }, name: 'Intro_School_Principal', }, + { + getComponent: () => { + const ImTeacherPage = require('../../../pages/TeachersUnite/ImTeacherPage').default; + return ImTeacherPage; + }, + name: 'I_Am_A_Teacher', + }, ]); const SettingsModalStackNavigator = createModalStackNavigator([ diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 1bc64982066e..599da439217d 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -277,6 +277,7 @@ export default { SaveTheWorld_Root: ROUTES.SAVE_THE_WORLD, I_Know_A_Teacher: ROUTES.I_Know_A_TEACHER, Intro_School_Principal: ROUTES.Intro_School_Principal, + I_Am_A_Teacher: ROUTES.I_Am_A_Teacher, }, }, Search: { diff --git a/src/pages/TeachersUnite/ImTeacherPage.js b/src/pages/TeachersUnite/ImTeacherPage.js new file mode 100644 index 000000000000..658b1a40519b --- /dev/null +++ b/src/pages/TeachersUnite/ImTeacherPage.js @@ -0,0 +1,58 @@ +import React from 'react'; +import _ from 'underscore'; +import {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; +import ScreenWrapper from '../../components/ScreenWrapper'; +import HeaderWithBackButton from '../../components/HeaderWithBackButton'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import ROUTES from '../../ROUTES'; +import Navigation from '../../libs/Navigation/Navigation'; +import FixedFooter from '../../components/FixedFooter'; +import BlockingView from '../../components/BlockingViews/BlockingView'; +import styles from '../../styles/styles'; +import Button from '../../components/Button'; +import * as Illustrations from '../../components/Icon/Illustrations'; +import variables from '../../styles/variables'; + +const propTypes = { + ...withLocalizePropTypes, + ...withCurrentUserPersonalDetailsPropTypes, +}; + +const defaultProps = { + ...withCurrentUserPersonalDetailsDefaultProps, +}; + +function ImTeacherPage(props) { + return ( + + Navigation.goBack(ROUTES.SAVE_THE_WORLD)} + /> + Profile > `} + shouldShowLink + link={'Contact Methods.'} + onLinkPress={() => Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHODS)} + iconWidth={variables.modalTopIconWidth} + iconHeight={variables.modalTopIconHeight} + /> + +