diff --git a/web/splash/splash.css b/web/splash/splash.css index ef3ac43ae..2676bacaf 100644 --- a/web/splash/splash.css +++ b/web/splash/splash.css @@ -1,211 +1,103 @@ div.headerContainer { flex: 1 1 auto; padding: 0 10px; } div.topContainer { position: absolute; top: 0; left: 0; right: 0; } div.content { flex: 1 0 0; position: relative; min-height: 100%; } div.top { max-width: 1024px; margin: 0 auto; } div.headerContents { display: flex; justify-content: space-between; align-items: center; padding-top: 5px; padding-bottom: 7px; } div.actionLinks > * { padding-right: 15px; color: white; font-weight: 300; } div.actionLinks > *:last-child { padding-right: 0; } header.header h1 { color: white; font-size: 38px; } -header.header span.requestAccess { +header.header { padding: 10px 20px; border-radius: 20px; border: 1px solid white; } div.body { padding: 30px 0 20px 0; } div.intro { text-align: center; margin-bottom: 50px; } p.introHeader { color: white; font-size: 28px; font-weight: 300; } p.introDescription { color: white; font-size: 21px; font-weight: 300; padding-top: 5px; } div.bottomContainer { z-index: 2; position: relative; overflow: auto; height: 100%; } div.bottom { margin-top: 728px; min-height: 100%; display: flex; flex-direction: column; } div.headerRest { background-color: rgba(255, 255, 255, 0.84); flex-grow: 1; } div.headerOverscroll { position: fixed; top: 100%; left: 0; right: 0; height: 1000px; background-color: white; } div.prompt { margin: 0 auto; display: flex; flex-direction: column; align-items: center; } p.promptHeader { color: #282828; font-size: 21px; padding-top: 25px; text-align: center; } p.promptDescription { color: #282828; font-size: 18px; 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 index 350a57fbc..42def68dc 100644 --- a/web/splash/splash.react.js +++ b/web/splash/splash.react.js @@ -1,269 +1,84 @@ // @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, +setModal: (modal: React.Node) => void, +modal: ?React.Node, }; -type State = { - +platform: DeviceType, - +email: string, - +error: ?string, - +success: ?string, -}; -class Splash extends React.PureComponent { - 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 { render() { - let androidWarning = null; - if (this.state.platform === 'android') { - androidWarning = ( -

- Make sure this is the email you use to log in to the Google Play - Store! -

- ); - } - let error = null; - if (this.state.error) { - error =

{this.state.error}

; - } - let success = null; - if (this.state.success) { - success = ( -

{this.state.success}

- ); - } - let submitButtonContent = 'Submit'; - if (this.props.loadingStatus === 'loading') { - submitButtonContent = ( - - ); - } return (

Comm is a chat app with an integrated calendar.

We make it incredibly easy to plan events with your friends.

-
+

We're currently alpha testing the first version of our app.

If you'd like to try it out, please let us know!

-
-
-
- -
- -
- -
- {androidWarning} -
- {error} - {success} -
{this.props.modal} ); } - bottomContainerRef = (bottomContainer: ?HTMLDivElement) => { - this.bottomContainer = bottomContainer; - }; - - emailInputRef = (emailInput: ?HTMLInputElement) => { - this.emailInput = emailInput; - }; - - onChangeEmail = (event: SyntheticEvent) => { - this.setState({ email: event.currentTarget.value }); - }; - - onChangePlatform = (event: SyntheticEvent) => { - this.setState({ platform: assertDeviceType(event.currentTarget.value) }); - }; - onClickLogIn = (event: SyntheticEvent) => { event.preventDefault(); this.props.setModal(); }; - - onClickRequestAccess = (event: SyntheticEvent) => { - 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) => { - 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 ( - + ); }, ); export default ConnectedSplash;