diff --git a/web/splash/splash.css b/web/splash/splash.css --- a/web/splash/splash.css +++ b/web/splash/splash.css @@ -36,7 +36,7 @@ color: white; font-size: 38px; } -header.header span.requestAccess { +header.header { padding: 10px 20px; border-radius: 20px; border: 1px solid white; @@ -101,111 +101,3 @@ padding-top: 9px; text-align: center; } -div.requestAccessContainer { - margin: 25px; - display: flex; - flex-direction: column; - align-items: center; -} -form.requestAccessForm { - display: flex; - align-items: center; -} -input.requestAccessEmail { - width: 300px; - border: 0; - padding: 10px 10px 8px 10px; - font-size: 18px; - border-radius: 5px; - background-color: rgba(119, 119, 119, 0.13); - color: black; -} -input.requestAccessEmail::placeholder, -input.requestAccessEmail::-ms-input-placeholder { - color: #777777; -} -button.requestAccessSubmit { - border: 0px; - padding: 10px 10px 8px 10px; - font-size: 18px; - border-radius: 5px; - background-color: rgba(0, 170, 0, 0.53); - color: white; - margin-left: 15px; - cursor: pointer; - width: 78px; - height: 39px; -} -p.androidWarning { - font-size: 14px; - padding: 5px; -} -p.requestAccessError { - font-size: 14px; - padding: 10px; - text-align: center; - color: red; -} -p.requestAccessSuccess { - font-size: 18px; - padding: 20px; - text-align: center; -} - -div.customSelect { - position: relative; - display: block; - border: 1px solid #bbb; - border-radius: 0.3em; - background-color: #f5f5f5; - margin-left: 15px; -} -div.customSelect::after { - content: ' '; - position: absolute; - top: 50%; - right: 1em; - z-index: 2; - pointer-events: none; - display: none; - width: 0; - height: 0; - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-top: 7px solid #666; - margin-top: -3px; -} -div.customSelect select { - width: 100%; - margin: 0; - outline: none; - padding: 0.6em 0.8em 0.5em 0.8em; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - font-size: 16px; - font-family: sans-serif; - color: #444; - border-radius: 0.2em; -} -div.customSelect select:focus { - color: #222; - outline: none; -} -@supports (-webkit-appearance: none) or (appearance: none) or - ((-moz-appearance: none) and (mask-type: alpha)) { - div.customSelect::after { - display: block; - } - div.customSelect select { - padding-right: 2em; - background: none; - border: 1px solid transparent; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - } - div.customSelect select:focus { - border-color: #aaa; - } -} diff --git a/web/splash/splash.react.js b/web/splash/splash.react.js --- a/web/splash/splash.react.js +++ b/web/splash/splash.react.js @@ -1,87 +1,17 @@ // @flow -import invariant from 'invariant'; import * as React from 'react'; -import { - requestAccessActionTypes, - requestAccess, -} from 'lib/actions/user-actions'; -import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; -import { validEmailRegex } from 'lib/shared/account-utils'; -import type { AccessRequest } from 'lib/types/account-types'; -import { type DeviceType, assertDeviceType } from 'lib/types/device-types'; -import { type LoadingStatus } from 'lib/types/loading-types'; -import { - type DispatchActionPromise, - useDispatchActionPromise, - useServerCall, -} from 'lib/utils/action-utils'; - -import Button from '../components/button.react'; -import LoadingIndicator from '../loading-indicator.react'; import LogInModal from '../modals/account/log-in-modal.react'; import { useModalContext } from '../modals/modal-provider.react'; -import { useSelector } from '../redux/redux-utils'; import css from './splash.css'; -const defaultRequestAccessScrollHeight = 390; - type Props = { - +loadingStatus: LoadingStatus, - +dispatchActionPromise: DispatchActionPromise, - +requestAccess: (accessRequest: AccessRequest) => Promise<void>, +setModal: (modal: React.Node) => void, +modal: ?React.Node, }; -type State = { - +platform: DeviceType, - +email: string, - +error: ?string, - +success: ?string, -}; -class Splash extends React.PureComponent<Props, State> { - emailInput: ?HTMLInputElement; - bottomContainer: ?HTMLDivElement; - state: State = { - platform: 'ios', - email: '', - error: null, - success: null, - }; - - componentDidMount() { - if ('scrollRestoration' in history) { - history.scrollRestoration = 'manual'; - } - } - +class Splash extends React.PureComponent<Props> { render() { - let androidWarning = null; - if (this.state.platform === 'android') { - androidWarning = ( - <p className={css.androidWarning}> - Make sure this is the email you use to log in to the Google Play - Store! - </p> - ); - } - let error = null; - if (this.state.error) { - error = <p className={css.requestAccessError}>{this.state.error}</p>; - } - let success = null; - if (this.state.success) { - success = ( - <p className={css.requestAccessSuccess}>{this.state.success}</p> - ); - } - let submitButtonContent = 'Submit'; - if (this.props.loadingStatus === 'loading') { - submitButtonContent = ( - <LoadingIndicator status={this.props.loadingStatus} /> - ); - } return ( <React.Fragment> <div className={css.headerContainer}> @@ -90,9 +20,6 @@ <div className={css.headerContents}> <h1>Comm</h1> <div className={css.actionLinks}> - <a href="#" onClick={this.onClickRequestAccess}> - <span className={css.requestAccess}>Request access</span> - </a> <a href="#" onClick={this.onClickLogIn}> <span>Log in</span> </a> @@ -116,7 +43,7 @@ </div> </div> </div> - <div className={css.bottomContainer} ref={this.bottomContainerRef}> + <div className={css.bottomContainer}> <div className={css.bottom}> <div className={css.headerRest}> <div className={css.prompt}> @@ -127,36 +54,6 @@ <p className={css.promptDescription}> If you'd like to try it out, please let us know! </p> - <div className={css.requestAccessContainer}> - <div> - <form className={css.requestAccessForm}> - <input - type="text" - value={this.state.email} - onChange={this.onChangeEmail} - placeholder="Email address" - className={css.requestAccessEmail} - ref={this.emailInputRef} - /> - <div className={css.customSelect}> - <select onChange={this.onChangePlatform}> - <option value="ios">iOS</option> - <option value="android">Android</option> - </select> - </div> - <Button - type="submit" - className={css.requestAccessSubmit} - onClick={this.onSubmitRequestAccess} - > - {submitButtonContent} - </Button> - </form> - {androidWarning} - </div> - {error} - {success} - </div> </div> </div> <div className={css.headerOverscroll} /> @@ -168,100 +65,18 @@ ); } - bottomContainerRef = (bottomContainer: ?HTMLDivElement) => { - this.bottomContainer = bottomContainer; - }; - - emailInputRef = (emailInput: ?HTMLInputElement) => { - this.emailInput = emailInput; - }; - - onChangeEmail = (event: SyntheticEvent<HTMLInputElement>) => { - this.setState({ email: event.currentTarget.value }); - }; - - onChangePlatform = (event: SyntheticEvent<HTMLSelectElement>) => { - this.setState({ platform: assertDeviceType(event.currentTarget.value) }); - }; - onClickLogIn = (event: SyntheticEvent<HTMLAnchorElement>) => { event.preventDefault(); this.props.setModal(<LogInModal />); }; - - onClickRequestAccess = (event: SyntheticEvent<HTMLAnchorElement>) => { - event.preventDefault(); - const { bottomContainer } = this; - invariant(bottomContainer, 'bottomContainer should exist'); - const formHeight = 180; - const contentHeight = 790; - const guaranteesSpace = contentHeight - window.innerHeight + formHeight; - if (bottomContainer.scrollTop < guaranteesSpace) { - bottomContainer.scrollTop = Math.max( - defaultRequestAccessScrollHeight, - guaranteesSpace, - ); - } - if (this.emailInput) { - this.emailInput.focus(); - } - }; - - onSubmitRequestAccess = (event: SyntheticEvent<HTMLElement>) => { - event.preventDefault(); - - if (this.state.email.search(validEmailRegex) === -1) { - this.setState({ success: null, error: 'Please enter a valid email!' }); - invariant(this.emailInput, 'should be set'); - this.emailInput.focus(); - return; - } - - this.props.dispatchActionPromise( - requestAccessActionTypes, - this.requestAccessAction(), - ); - }; - - async requestAccessAction() { - try { - await this.props.requestAccess({ - email: this.state.email, - platform: this.state.platform, - }); - this.setState({ - success: - "Thanks for your interest! We'll let you know as soon as " + - "we're able to extend an invite.", - error: null, - }); - } catch (e) { - this.setState({ success: null, error: 'Unknown error...' }); - throw e; - } - } } -const loadingStatusSelector = createLoadingStatusSelector( - requestAccessActionTypes, -); - const ConnectedSplash: React.ComponentType<{}> = React.memo<{}>( function ConnectedSplash(): React.Node { - const loadingStatus = useSelector(loadingStatusSelector); - const callRequestAccess = useServerCall(requestAccess); - const dispatchActionPromise = useDispatchActionPromise(); - const modalContext = useModalContext(); return ( - <Splash - loadingStatus={loadingStatus} - requestAccess={callRequestAccess} - dispatchActionPromise={dispatchActionPromise} - setModal={modalContext.setModal} - modal={modalContext.modal} - /> + <Splash setModal={modalContext.setModal} modal={modalContext.modal} /> ); }, );