diff --git a/assets/images/expensify-footer-logo-vertical.svg b/assets/images/expensify-footer-logo-vertical.svg new file mode 100644 index 000000000000..58dc05ad2944 --- /dev/null +++ b/assets/images/expensify-footer-logo-vertical.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + diff --git a/assets/images/expensify-footer-logo.svg b/assets/images/expensify-footer-logo.svg new file mode 100644 index 000000000000..e664651b84fd --- /dev/null +++ b/assets/images/expensify-footer-logo.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + diff --git a/assets/images/social-facebook.svg b/assets/images/social-facebook.svg new file mode 100644 index 000000000000..3a966653e688 --- /dev/null +++ b/assets/images/social-facebook.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/assets/images/social-instagram.svg b/assets/images/social-instagram.svg new file mode 100644 index 000000000000..79d4aadf374a --- /dev/null +++ b/assets/images/social-instagram.svg @@ -0,0 +1,17 @@ + + + + + + + diff --git a/assets/images/social-linkedin.svg b/assets/images/social-linkedin.svg new file mode 100644 index 000000000000..97a1da8962f4 --- /dev/null +++ b/assets/images/social-linkedin.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/assets/images/social-podcast.svg b/assets/images/social-podcast.svg new file mode 100644 index 000000000000..1366699b6823 --- /dev/null +++ b/assets/images/social-podcast.svg @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/assets/images/social-twitter.svg b/assets/images/social-twitter.svg new file mode 100644 index 000000000000..6a90f95032bb --- /dev/null +++ b/assets/images/social-twitter.svg @@ -0,0 +1,9 @@ + + + + + diff --git a/assets/images/social-youtube.svg b/assets/images/social-youtube.svg new file mode 100644 index 000000000000..834314d27d27 --- /dev/null +++ b/assets/images/social-youtube.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ed9cdc3f6850..75ceab1d5286 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -177,29 +177,29 @@ PODS: - GoogleUtilities/Network (~> 7.4) - "GoogleUtilities/NSData+zlib (~> 7.4)" - nanopb (~> 2.30908.0) - - GoogleDataTransport (9.2.0): + - GoogleDataTransport (9.2.1): - GoogleUtilities/Environment (~> 7.7) - nanopb (< 2.30910.0, >= 2.30908.0) - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/AppDelegateSwizzler (7.10.0): + - GoogleUtilities/AppDelegateSwizzler (7.11.0): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (7.10.0): + - GoogleUtilities/Environment (7.11.0): - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/ISASwizzler (7.10.0) - - GoogleUtilities/Logger (7.10.0): + - GoogleUtilities/ISASwizzler (7.11.0) + - GoogleUtilities/Logger (7.11.0): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (7.10.0): + - GoogleUtilities/MethodSwizzler (7.11.0): - GoogleUtilities/Logger - - GoogleUtilities/Network (7.10.0): + - GoogleUtilities/Network (7.11.0): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (7.10.0)" - - GoogleUtilities/Reachability (7.10.0): + - "GoogleUtilities/NSData+zlib (7.11.0)" + - GoogleUtilities/Reachability (7.11.0): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (7.10.0): + - GoogleUtilities/UserDefaults (7.11.0): - GoogleUtilities/Logger - hermes-engine (0.70.4) - libevent (2.1.12) @@ -969,8 +969,8 @@ SPEC CHECKSUMS: fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b GoogleAppMeasurement: 5ba1164e3c844ba84272555e916d0a6d3d977e91 - GoogleDataTransport: 1c8145da7117bd68bbbed00cf304edb6a24de00f - GoogleUtilities: bad72cb363809015b1f7f19beb1f1cd23c589f95 + GoogleDataTransport: ea169759df570f4e37bdee1623ec32a7e64e67c4 + GoogleUtilities: c2bdc4cf2ce786c4d2e6b3bcfd599a25ca78f06f hermes-engine: 3623325e0d0676a45fbc544d72c57dd79fce7446 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef diff --git a/src/CONST.js b/src/CONST.js index accd263483f4..1749c52bd2ec 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -895,6 +895,38 @@ const CONST = { LEAVE_ROOM: 'leaveRoom', }, + FOOTER: { + EXPENSE_MANAGEMENT_URL: `${USE_EXPENSIFY_URL}/expense-management`, + SPEND_MANAGEMENT_URL: `${USE_EXPENSIFY_URL}/spend-management`, + EXPENSE_REPORTS_URL: `${USE_EXPENSIFY_URL}/expense-reports`, + COMPANY_CARD_URL: `${USE_EXPENSIFY_URL}/company-credit-card`, + RECIEPT_SCANNING_URL: `${USE_EXPENSIFY_URL}/receipt-scanning-app`, + BILL_PAY_URL: `${USE_EXPENSIFY_URL}/bills`, + INVOICES_URL: `${USE_EXPENSIFY_URL}/invoices`, + CPA_CARD_URL: `${USE_EXPENSIFY_URL}/cpa-card`, + PAYROLL_URL: `${USE_EXPENSIFY_URL}/payroll`, + TRAVEL_URL: `${USE_EXPENSIFY_URL}/travel`, + EXPENSIFY_APPROVED_URL: `${USE_EXPENSIFY_URL}/accountants`, + PRESS_KIT_URL: 'https://we.are.expensify.com/press-kit', + SUPPORT_URL: `${USE_EXPENSIFY_URL}/support`, + HELP_URL: 'https://help.expensify.com/', + COMMUNITY_URL: 'https://community.expensify.com/', + PRIVACY_URL: `${USE_EXPENSIFY_URL}/privacy`, + ABOUT_URL: 'https://we.are.expensify.com/', + BLOG_URL: 'https://blog.expensify.com/', + JOBS_URL: 'https://we.are.expensify.com/apply', + ORG_URL: 'https://expensify.org/', + INVESTOR_RELATIONS_URL: 'https://ir.expensify.com/', + }, + + SOCIALS: { + PODCAST: 'https://we.are.expensify.com/podcast', + TWITTER: 'https://www.twitter.com/expensify', + INSTAGRAM: 'http://www.instagram.com/expensify', + FACEBOOK: 'https://www.facebook.com/expensify', + LINKEDIN: 'http://www.linkedin.com/company/expensify', + }, + // These split the maximum decimal value of a signed 64-bit number (9,223,372,036,854,775,807) into parts where none of them are too big to fit into a 32-bit number, so that we can // generate them each with a random number generator with only 32-bits of precision. MAX_64BIT_LEFT_PART: 92233, diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js index 5b562d790ae1..864ae755b15f 100644 --- a/src/components/Icon/Expensicons.js +++ b/src/components/Icon/Expensicons.js @@ -98,6 +98,14 @@ import Zoom from '../../../assets/images/zoom.svg'; import FallbackAvatar from '../../../assets/images/avatars/fallback-avatar.svg'; import FallbackWorkspaceAvatar from '../../../assets/images/avatars/fallback-workspace-avatar.svg'; import DragAndDrop from '../../../assets/images/drag-and-drop.svg'; +import ExpensifyFooterLogo from '../../../assets/images/expensify-footer-logo.svg'; +import ExpensifyFooterLogoVertical from '../../../assets/images/expensify-footer-logo-vertical.svg'; +import Twitter from '../../../assets/images/social-twitter.svg'; +import Youtube from '../../../assets/images/social-youtube.svg'; +import Facebook from '../../../assets/images/social-facebook.svg'; +import Podcast from '../../../assets/images/social-podcast.svg'; +import Linkedin from '../../../assets/images/social-linkedin.svg'; +import Instagram from '../../../assets/images/social-instagram.svg'; export { ActiveRoomAvatar, @@ -140,6 +148,8 @@ export { Exit, ExpensifyCard, ExpensifyWordmark, + ExpensifyFooterLogo, + ExpensifyFooterLogoVertical, Expand, Eye, EyeDisabled, @@ -200,4 +210,10 @@ export { Wallet, Workspace, Zoom, + Twitter, + Youtube, + Facebook, + Podcast, + Linkedin, + Instagram, }; diff --git a/src/components/LocalePicker.js b/src/components/LocalePicker.js index 5be074168250..4d434f12e3ec 100644 --- a/src/components/LocalePicker.js +++ b/src/components/LocalePicker.js @@ -10,6 +10,7 @@ import CONST from '../CONST'; import * as Localize from '../libs/Localize'; import Picker from './Picker'; import styles from '../styles/styles'; +import themeColors from '../styles/themes/default'; const propTypes = { /** Indicates which locale the user currently has selected */ @@ -51,6 +52,7 @@ const LocalePicker = props => ( size={props.size} value={props.preferredLocale} containerStyles={props.size === 'small' ? [styles.pickerContainerSmall] : []} + backgroundColor={themeColors.transparent} /> ); diff --git a/src/languages/en.js b/src/languages/en.js index c2edea86b01e..2a8891a3bdf5 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1182,4 +1182,33 @@ export default { report: { genericAddCommentFailureMessage: 'Unexpected error while posting the comment, please try again later', }, + footer: { + features: 'Features', + expenseManagement: 'Expense Management', + spendManagement: 'Spend Management', + expenseReports: 'Expense Reports', + companyCreditCard: 'Company Credit Card', + receiptScanningApp: 'Receipt Scanning App', + billPay: 'Bill Pay', + invoicing: 'Invoicing', + CPACard: 'CPA Card', + payroll: 'Payroll', + travel: 'Travel', + resources: 'Resources', + expensifyApproved: 'ExpensifyApproved!', + pressKit: 'Press Kit', + support: 'Support', + expensifyHelp: 'ExpensifyHelp', + community: 'Community', + privacy: 'Privacy', + learnMore: 'Learn More', + aboutExpensify: 'About Expensify', + blog: 'Blog', + jobs: 'Jobs', + expensifyOrg: 'Expensify.org', + investorRelations: 'Investor Relations', + getStarted: 'Get Started', + createAccount: 'Create a new account', + logIn: 'Log in', + }, }; diff --git a/src/languages/es.js b/src/languages/es.js index 8c82b5e70135..ca3148248bd6 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -1184,4 +1184,33 @@ export default { report: { genericAddCommentFailureMessage: 'Error inesperado al agregar el comentario, por favor inténtalo más tarde', }, + footer: { + features: 'Características', + expenseManagement: 'Gestión de Gastos', + spendManagement: 'Control de Gastos', + expenseReports: 'Informes de Gastos', + companyCreditCard: 'Tarjeta de Crédito de Empresa', + receiptScanningApp: 'Aplicación de Escaneado de Recibos', + billPay: 'Pago de Facturas', + invoicing: 'Facturación', + CPACard: 'Tarjeta Para Contables', + payroll: 'Nómina', + travel: 'Viajes', + resources: 'Recursos', + expensifyApproved: 'ExpensifyApproved!', + pressKit: 'Kit de Prensa', + support: 'Soporte', + expensifyHelp: '', + community: 'Comunidad', + privacy: 'Privacidad', + learnMore: 'Más Información', + aboutExpensify: 'Acerca de Expensify', + blog: 'Blog', + jobs: 'Empleo', + expensifyOrg: '', + investorRelations: 'Relaciones Con Los Inversores', + getStarted: 'Comenzar', + createAccount: 'Crear Una Cuenta Nueva', + logIn: 'Conectarse', + }, }; diff --git a/src/libs/Navigation/AppNavigator/defaultScreenOptions.js b/src/libs/Navigation/AppNavigator/defaultScreenOptions.js index f22e7d905768..3a0c0604d901 100644 --- a/src/libs/Navigation/AppNavigator/defaultScreenOptions.js +++ b/src/libs/Navigation/AppNavigator/defaultScreenOptions.js @@ -1,6 +1,7 @@ const defaultScreenOptions = { cardStyle: { overflow: 'visible', + flex: 1, }, headerShown: false, animationTypeForReplace: 'pop', diff --git a/src/pages/signin/Licenses.js b/src/pages/signin/Licenses.js new file mode 100644 index 000000000000..c860efa93451 --- /dev/null +++ b/src/pages/signin/Licenses.js @@ -0,0 +1,34 @@ +import React from 'react'; +import {View} from 'react-native'; +import styles from '../../styles/styles'; +import CONST from '../../CONST'; +import Text from '../../components/Text'; +import TextLink from '../../components/TextLink'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import LocalePicker from '../../components/LocalePicker'; + +const currentYear = new Date().getFullYear(); + +const Licenses = props => ( + <> + + {`© ${currentYear} Expensify`} + + + {props.translate('termsOfUse.phrase5')} + + {' '} + {props.translate('termsOfUse.phrase6')} + + . + + + + + +); + +Licenses.propTypes = {...withLocalizePropTypes}; +Licenses.displayName = 'Licenses'; + +export default withLocalize(Licenses); diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js index 07867403d050..97d3593eae34 100755 --- a/src/pages/signin/LoginForm.js +++ b/src/pages/signin/LoginForm.js @@ -17,7 +17,6 @@ import * as ValidationUtils from '../../libs/ValidationUtils'; import * as LoginUtils from '../../libs/LoginUtils'; import withToggleVisibilityView, {toggleVisibilityViewPropTypes} from '../../components/withToggleVisibilityView'; import FormAlertWithSubmitButton from '../../components/FormAlertWithSubmitButton'; -import OfflineIndicator from '../../components/OfflineIndicator'; import {withNetwork} from '../../components/OnyxProvider'; import networkPropTypes from '../../components/networkPropTypes'; import * as ErrorUtils from '../../libs/ErrorUtils'; @@ -211,7 +210,6 @@ class LoginForm extends React.Component { ) } - ); } diff --git a/src/pages/signin/PasswordForm.js b/src/pages/signin/PasswordForm.js index 7d8813313089..f2f3c88f0c8e 100755 --- a/src/pages/signin/PasswordForm.js +++ b/src/pages/signin/PasswordForm.js @@ -23,8 +23,8 @@ import canFocusInputOnScreenFocus from '../../libs/canFocusInputOnScreenFocus'; import * as ErrorUtils from '../../libs/ErrorUtils'; import {withNetwork} from '../../components/OnyxProvider'; import networkPropTypes from '../../components/networkPropTypes'; -import OfflineIndicator from '../../components/OfflineIndicator'; import FormHelpMessage from '../../components/FormHelpMessage'; +import Terms from './Terms'; const propTypes = { /* Onyx Props */ @@ -225,7 +225,9 @@ class PasswordForm extends React.Component { /> - + + + ); } diff --git a/src/pages/signin/ResendValidationForm.js b/src/pages/signin/ResendValidationForm.js index 7753faa65294..c6230e951be6 100755 --- a/src/pages/signin/ResendValidationForm.js +++ b/src/pages/signin/ResendValidationForm.js @@ -14,7 +14,6 @@ import compose from '../../libs/compose'; import redirectToSignIn from '../../libs/actions/SignInRedirect'; import Avatar from '../../components/Avatar'; import * as ReportUtils from '../../libs/ReportUtils'; -import OfflineIndicator from '../../components/OfflineIndicator'; import networkPropTypes from '../../components/networkPropTypes'; import {withNetwork} from '../../components/OnyxProvider'; import DotIndicatorMessage from '../../components/DotIndicatorMessage'; @@ -93,7 +92,6 @@ const ResendValidationForm = (props) => { isDisabled={props.network.isOffline} /> - ); }; diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index d74119c2907e..323c166b3ec4 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -1,10 +1,8 @@ import React, {Component} from 'react'; -import { - SafeAreaView, -} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import Str from 'expensify-common/lib/str'; +import {SafeAreaView} from 'react-native-safe-area-context'; import ONYXKEYS from '../../ONYXKEYS'; import styles from '../../styles/styles'; import compose from '../../libs/compose'; diff --git a/src/pages/signin/SignInPageLayout/Footer.js b/src/pages/signin/SignInPageLayout/Footer.js new file mode 100644 index 000000000000..c7970277276f --- /dev/null +++ b/src/pages/signin/SignInPageLayout/Footer.js @@ -0,0 +1,210 @@ +import {View} from 'react-native'; +import React from 'react'; +import _ from 'underscore'; +import Text from '../../../components/Text'; +import styles from '../../../styles/styles'; +import variables from '../../../styles/variables'; +import * as Expensicons from '../../../components/Icon/Expensicons'; +import TextLink from '../../../components/TextLink'; +import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; +import compose from '../../../libs/compose'; +import Licenses from '../Licenses'; +import Socials from '../Socials'; +import Hoverable from '../../../components/Hoverable'; +import CONST from '../../../CONST'; + +const propTypes = { + ...windowDimensionsPropTypes, + ...withLocalizePropTypes, +}; + +const columns = [ + { + translationPath: 'footer.features', + rows: [ + { + link: CONST.FOOTER.EXPENSE_MANAGEMENT_URL, + translationPath: 'footer.expenseManagement', + }, + { + link: CONST.FOOTER.SPEND_MANAGEMENT_URL, + translationPath: 'footer.spendManagement', + }, + { + link: CONST.FOOTER.EXPENSE_REPORTS_URL, + translationPath: 'footer.expenseReports', + }, + { + link: CONST.FOOTER.COMPANY_CARD_URL, + translationPath: 'footer.companyCreditCard', + }, + { + link: CONST.FOOTER.RECIEPT_SCANNING_URL, + translationPath: 'footer.receiptScanningApp', + }, + { + link: CONST.FOOTER.BILL_PAY_URL, + translationPath: 'footer.billPay', + }, + { + link: CONST.FOOTER.INVOICES_URL, + translationPath: 'footer.invoicing', + }, + { + link: CONST.FOOTER.CPA_CARD_URL, + translationPath: 'footer.CPACard', + }, + { + link: CONST.FOOTER.PAYROLL_URL, + translationPath: 'footer.payroll', + }, + { + link: CONST.FOOTER.TRAVEL_URL, + translationPath: 'footer.travel', + }, + ], + }, + { + translationPath: 'footer.resources', + rows: [ + { + link: CONST.FOOTER.EXPENSIFY_APPROVED_URL, + translationPath: 'footer.expensifyApproved', + }, + { + link: CONST.FOOTER.PRESS_KIT_URL, + translationPath: 'footer.pressKit', + }, + { + link: CONST.FOOTER.SUPPORT_URL, + translationPath: 'footer.support', + }, + { + link: CONST.FOOTER.HELP_URL, + translationPath: 'footer.expensifyHelp', + }, + { + link: CONST.FOOTER.COMMUNITY_URL, + translationPath: 'footer.community', + }, + { + link: CONST.FOOTER.PRIVACY_URL, + translationPath: 'footer.privacy', + }, + ], + }, + { + translationPath: 'footer.learnMore', + rows: [ + { + link: CONST.FOOTER.ABOUT_URL, + translationPath: 'footer.aboutExpensify', + }, + { + link: CONST.FOOTER.BLOG_URL, + translationPath: 'footer.blog', + }, + { + link: CONST.FOOTER.JOBS_URL, + translationPath: 'footer.jobs', + }, + { + link: CONST.FOOTER.ORG_URL, + translationPath: 'footer.expensifyOrg', + }, + { + link: CONST.FOOTER.INVESTOR_RELATIONS_URL, + translationPath: 'footer.investorRelations', + }, + ], + }, + { + translationPath: 'footer.getStarted', + rows: [ + { + link: CONST.NEW_EXPENSIFY_URL, + translationPath: 'footer.createAccount', + }, + { + link: CONST.NEW_EXPENSIFY_URL, + translationPath: 'footer.logIn', + }, + ], + }, +]; + +const Footer = (props) => { + const isVertical = props.isSmallScreenWidth; + const imageDirection = isVertical ? styles.flexRow : styles.flexColumn; + const imageStyle = isVertical ? styles.pr0 : styles.alignSelfCenter; + const columnDirection = isVertical ? styles.flexColumn : styles.flexRow; + const pageFooterWrapper = [styles.footerWrapper, imageDirection, imageStyle]; + const footerColumns = [styles.footerColumnsContainer, columnDirection]; + const footerColumn = isVertical ? [styles.p4] : [styles.p4, props.isMediumScreenWidth ? styles.w50 : styles.w25]; + + return ( + + + + + { /** Columns * */ } + {_.map(columns, (column, i) => ( + + + {props.translate(column.translationPath)} + + + { /** Rows * */ } + {_.map(column.rows, row => ( + + {hovered => ( + + {props.translate(row.translationPath)} + + )} + + ))} + {(i === 2) && ( + + + + )} + {(i === 3) && ( + + + + )} + + + ))} + + + {!isVertical + ? ( + + ) : ( + + )} + + + + + ); +}; + +Footer.propTypes = propTypes; +Footer.displayName = 'Footer'; + +export default compose( + withLocalize, + withWindowDimensions, +)(Footer); diff --git a/src/pages/signin/SignInPageLayout/SignInPageContent.js b/src/pages/signin/SignInPageLayout/SignInPageContent.js index 60d99b6ea2a2..76f03ec87715 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageContent.js +++ b/src/pages/signin/SignInPageLayout/SignInPageContent.js @@ -6,12 +6,12 @@ import styles from '../../../styles/styles'; import variables from '../../../styles/variables'; import ExpensifyCashLogo from '../../../components/ExpensifyCashLogo'; import Text from '../../../components/Text'; -import TermsAndLicenses from '../TermsAndLicenses'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import SignInPageForm from '../../../components/SignInPageForm'; import compose from '../../../libs/compose'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView'; +import OfflineIndicator from '../../../components/OfflineIndicator'; const propTypes = { /** The children to show inside the layout */ @@ -32,7 +32,7 @@ const SignInPageContent = props => ( ( {props.children} - - - + + + ); diff --git a/src/pages/signin/SignInPageLayout/SignInPageGraphics.js b/src/pages/signin/SignInPageLayout/SignInPageGraphics.js index c735bc9fd283..217a4713836c 100644 --- a/src/pages/signin/SignInPageLayout/SignInPageGraphics.js +++ b/src/pages/signin/SignInPageLayout/SignInPageGraphics.js @@ -1,17 +1,21 @@ import {Pressable} from 'react-native'; import React from 'react'; import _ from 'underscore'; -import styles from '../../../styles/styles'; import * as StyleUtils from '../../../styles/StyleUtils'; import * as Link from '../../../libs/actions/Link'; import SVGImage from '../../../components/SVGImage'; +import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; const backgroundStyle = StyleUtils.getLoginPagePromoStyle(); -const SignInPageGraphics = () => ( +const propTypes = { + ...windowDimensionsPropTypes, +}; + +const SignInPageGraphics = props => ( { @@ -29,5 +33,6 @@ const SignInPageGraphics = () => ( ); SignInPageGraphics.displayName = 'SignInPageGraphics'; +SignInPageGraphics.propTypes = propTypes; -export default SignInPageGraphics; +export default withWindowDimensions(SignInPageGraphics); diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index c165b336bb3d..bd0b4b52b0c5 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -1,10 +1,15 @@ import React from 'react'; -import {View} from 'react-native'; +import {View, ScrollView} from 'react-native'; +import {withSafeAreaInsets} from 'react-native-safe-area-context'; import PropTypes from 'prop-types'; +import compose from '../../../libs/compose'; import SignInPageContent from './SignInPageContent'; +import Footer from './Footer'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; import styles from '../../../styles/styles'; import SignInPageGraphics from './SignInPageGraphics'; +import * as StyleUtils from '../../../styles/StyleUtils'; +import scrollViewContentContainerStyles from './signInPageStyles'; const propTypes = { /** The children to show inside the layout */ @@ -24,24 +29,51 @@ const SignInPageLayout = (props) => { let containerStyles = [styles.flex1, styles.signInPageInner]; let contentContainerStyles = [styles.flex1, styles.flexRow]; + // To scroll on both mobile and web, we need to set the container height manually + const containerHeight = props.windowHeight - props.insets.top - props.insets.bottom; + if (props.isSmallScreenWidth) { containerStyles = [styles.flex1]; - contentContainerStyles = [styles.flex1]; + contentContainerStyles = [styles.flex1, styles.flexColumn]; } return ( - - - {props.children} - - {!props.isSmallScreenWidth && ( - + {!props.isSmallScreenWidth + ? ( + + + {props.children} + + + +