From 12896bd23eeba79884245c1c29fdc568cf21a7fa Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 14 Mar 2016 08:50:46 -0400 Subject: Converting to Webpack. Stage 1. --- .../components/signup_team_complete.jsx | 81 +++++++ .../components/team_signup_display_name_page.jsx | 141 ++++++++++++ .../components/team_signup_email_item.jsx | 89 ++++++++ .../components/team_signup_finished.jsx | 17 ++ .../components/team_signup_password_page.jsx | 221 +++++++++++++++++++ .../components/team_signup_send_invites_page.jsx | 215 ++++++++++++++++++ .../components/team_signup_url_page.jsx | 211 ++++++++++++++++++ .../components/team_signup_username_page.jsx | 169 +++++++++++++++ .../components/team_signup_welcome_page.jsx | 239 +++++++++++++++++++++ 9 files changed, 1383 insertions(+) create mode 100644 webapp/components/signup_team_complete/components/signup_team_complete.jsx create mode 100644 webapp/components/signup_team_complete/components/team_signup_display_name_page.jsx create mode 100644 webapp/components/signup_team_complete/components/team_signup_email_item.jsx create mode 100644 webapp/components/signup_team_complete/components/team_signup_finished.jsx create mode 100644 webapp/components/signup_team_complete/components/team_signup_password_page.jsx create mode 100644 webapp/components/signup_team_complete/components/team_signup_send_invites_page.jsx create mode 100644 webapp/components/signup_team_complete/components/team_signup_url_page.jsx create mode 100644 webapp/components/signup_team_complete/components/team_signup_username_page.jsx create mode 100644 webapp/components/signup_team_complete/components/team_signup_welcome_page.jsx (limited to 'webapp/components/signup_team_complete') diff --git a/webapp/components/signup_team_complete/components/signup_team_complete.jsx b/webapp/components/signup_team_complete/components/signup_team_complete.jsx new file mode 100644 index 000000000..02040c734 --- /dev/null +++ b/webapp/components/signup_team_complete/components/signup_team_complete.jsx @@ -0,0 +1,81 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import BrowserStore from 'stores/browser_store.jsx'; + +import {FormattedMessage} from 'react-intl'; + +import {browserHistory} from 'react-router'; + +import React from 'react'; + +export default class SignupTeamComplete extends React.Component { + constructor(props) { + super(props); + + this.updateParent = this.updateParent.bind(this); + } + componentWillMount() { + const data = JSON.parse(this.props.location.query.d); + this.hash = this.props.location.query.h; + + var initialState = BrowserStore.getGlobalItem(this.hash); + + if (!initialState) { + initialState = {}; + initialState.wizard = 'welcome'; + initialState.team = {}; + initialState.team.email = data.email; + initialState.team.allowed_domains = ''; + initialState.invites = []; + initialState.invites.push(''); + initialState.invites.push(''); + initialState.invites.push(''); + initialState.user = {}; + initialState.hash = this.hash; + initialState.data = this.props.location.query.d; + } + + this.setState(initialState); + } + componentDidMount() { + browserHistory.push('/signup_team_complete/welcome'); + } + updateParent(state, skipSet) { + BrowserStore.setGlobalItem(this.hash, state); + + if (!skipSet) { + this.setState(state); + browserHistory.push('/signup_team_complete/' + state.wizard); + } + } + render() { + return ( +
+
+ + + + +
+
+
+
+ {React.cloneElement(this.props.children, { + state: this.state, + updateParent: this.updateParent + })} +
+
+
+
+ ); + } +} + +SignupTeamComplete.defaultProps = { +}; +SignupTeamComplete.propTypes = { + location: React.PropTypes.object, + children: React.PropTypes.node +}; diff --git a/webapp/components/signup_team_complete/components/team_signup_display_name_page.jsx b/webapp/components/signup_team_complete/components/team_signup_display_name_page.jsx new file mode 100644 index 000000000..111fc6835 --- /dev/null +++ b/webapp/components/signup_team_complete/components/team_signup_display_name_page.jsx @@ -0,0 +1,141 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import ReactDOM from 'react-dom'; +import * as utils from 'utils/utils.jsx'; +import * as client from 'utils/client.jsx'; + +import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'react-intl'; + +import logoImage from 'images/logo.png'; + +const holders = defineMessages({ + required: { + id: 'team_signup_display_name.required', + defaultMessage: 'This field is required' + }, + charLength: { + id: 'team_signup_display_name.charLength', + defaultMessage: 'Name must be 4 or more characters up to a maximum of 15' + } +}); + +import React from 'react'; + +class TeamSignupDisplayNamePage extends React.Component { + constructor(props) { + super(props); + + this.submitBack = this.submitBack.bind(this); + this.submitNext = this.submitNext.bind(this); + + this.state = {}; + } + submitBack(e) { + e.preventDefault(); + this.props.state.wizard = 'welcome'; + this.props.updateParent(this.props.state); + } + submitNext(e) { + e.preventDefault(); + + const {formatMessage} = this.props.intl; + var displayName = ReactDOM.findDOMNode(this.refs.name).value.trim(); + if (!displayName) { + this.setState({nameError: formatMessage(holders.required)}); + return; + } else if (displayName.length < 4 || displayName.length > 15) { + this.setState({nameError: formatMessage(holders.charLength)}); + return; + } + + this.props.state.wizard = 'team_url'; + this.props.state.team.display_name = displayName; + this.props.state.team.name = utils.cleanUpUrlable(displayName); + this.props.updateParent(this.props.state); + } + handleFocus(e) { + e.preventDefault(); + e.currentTarget.select(); + } + render() { + client.track('signup', 'signup_team_02_name'); + + var nameError = null; + var nameDivClass = 'form-group'; + if (this.state.nameError) { + nameError = ; + nameDivClass += ' has-error'; + } + + return ( +
+
+ +

+ +

+
+
+
+ +
+
+ {nameError} +
+
+ +
+ +
+ + + +
+
+
+ ); + } +} + +TeamSignupDisplayNamePage.propTypes = { + intl: intlShape.isRequired, + state: React.PropTypes.object, + updateParent: React.PropTypes.func +}; + +export default injectIntl(TeamSignupDisplayNamePage); diff --git a/webapp/components/signup_team_complete/components/team_signup_email_item.jsx b/webapp/components/signup_team_complete/components/team_signup_email_item.jsx new file mode 100644 index 000000000..c3903ca85 --- /dev/null +++ b/webapp/components/signup_team_complete/components/team_signup_email_item.jsx @@ -0,0 +1,89 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import ReactDOM from 'react-dom'; +import * as Utils from 'utils/utils.jsx'; + +import {intlShape, injectIntl, defineMessages} from 'react-intl'; + +const holders = defineMessages({ + validEmail: { + id: 'team_signup_email.validEmail', + defaultMessage: 'Please enter a valid email address' + }, + different: { + id: 'team_signup_email.different', + defaultMessage: 'Please use a different email than the one used at signup' + }, + address: { + id: 'team_signup_email.address', + defaultMessage: 'Email Address' + } +}); + +import React from 'react'; + +class TeamSignupEmailItem extends React.Component { + constructor(props) { + super(props); + + this.getValue = this.getValue.bind(this); + this.validate = this.validate.bind(this); + + this.state = {}; + } + getValue() { + return ReactDOM.findDOMNode(this.refs.email).value.trim(); + } + validate(teamEmail) { + const {formatMessage} = this.props.intl; + const email = ReactDOM.findDOMNode(this.refs.email).value.trim().toLowerCase(); + + if (!email) { + return true; + } + + if (!Utils.isEmail(email)) { + this.setState({emailError: formatMessage(holders.validEmail)}); + return false; + } else if (email === teamEmail) { + this.setState({emailError: formatMessage(holders.different)}); + return false; + } + + this.setState({emailError: ''}); + return true; + } + render() { + let emailError = null; + let emailDivClass = 'form-group'; + if (this.state.emailError) { + emailError = ; + emailDivClass += ' has-error'; + } + + return ( +
+ + {emailError} +
+ ); + } +} + +TeamSignupEmailItem.propTypes = { + intl: intlShape.isRequired, + focus: React.PropTypes.bool, + email: React.PropTypes.string +}; + +export default injectIntl(TeamSignupEmailItem, {withRef: true}); diff --git a/webapp/components/signup_team_complete/components/team_signup_finished.jsx b/webapp/components/signup_team_complete/components/team_signup_finished.jsx new file mode 100644 index 000000000..9fbb8473a --- /dev/null +++ b/webapp/components/signup_team_complete/components/team_signup_finished.jsx @@ -0,0 +1,17 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import {FormattedMessage} from 'react-intl'; + +import React from 'react'; + +export default class FinishedPage extends React.Component { + render() { + return ( + + ); + } +} diff --git a/webapp/components/signup_team_complete/components/team_signup_password_page.jsx b/webapp/components/signup_team_complete/components/team_signup_password_page.jsx new file mode 100644 index 000000000..110690da1 --- /dev/null +++ b/webapp/components/signup_team_complete/components/team_signup_password_page.jsx @@ -0,0 +1,221 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import $ from 'jquery'; +import ReactDOM from 'react-dom'; +import * as Client from 'utils/client.jsx'; +import BrowserStore from 'stores/browser_store.jsx'; +import UserStore from 'stores/user_store.jsx'; +import Constants from 'utils/constants.jsx'; + +import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl'; +import {browserHistory} from 'react-router'; + +import logoImage from 'images/logo.png'; + +const holders = defineMessages({ + passwordError: { + id: 'team_signup_password.passwordError', + defaultMessage: 'Please enter at least {chars} characters' + }, + creating: { + id: 'team_signup_password.creating', + defaultMessage: 'Creating team...' + } +}); + +import React from 'react'; + +class TeamSignupPasswordPage extends React.Component { + constructor(props) { + super(props); + + this.submitBack = this.submitBack.bind(this); + this.submitNext = this.submitNext.bind(this); + + this.state = {}; + } + submitBack(e) { + e.preventDefault(); + this.props.state.wizard = 'username'; + this.props.updateParent(this.props.state); + } + submitNext(e) { + e.preventDefault(); + + var password = ReactDOM.findDOMNode(this.refs.password).value.trim(); + if (!password || password.length < Constants.MIN_PASSWORD_LENGTH) { + this.setState({passwordError: this.props.intl.formatMessage(holders.passwordError, {chars: Constants.MIN_PASSWORD_LENGTH})}); + return; + } + + this.setState({passwordError: null, serverError: null}); + $('#finish-button').button('loading'); + var teamSignup = JSON.parse(JSON.stringify(this.props.state)); + teamSignup.user.password = password; + teamSignup.user.allow_marketing = true; + delete teamSignup.wizard; + + Client.createTeamFromSignup(teamSignup, + () => { + Client.track('signup', 'signup_team_08_complete'); + + var props = this.props; + + Client.loginByEmail(teamSignup.team.name, teamSignup.team.email, teamSignup.user.password, + () => { + UserStore.setLastEmail(teamSignup.team.email); + if (this.props.hash > 0) { + BrowserStore.setGlobalItem(this.props.hash, JSON.stringify({wizard: 'finished'})); + } + + $('#sign-up-button').button('reset'); + props.state.wizard = 'finished'; + props.updateParent(props.state, true); + + browserHistory.push('/' + teamSignup.team.name + '/channels/town-square'); + }, + (err) => { + if (err.id === 'api.user.login.not_verified.app_error') { + browserHistory.push('/verify_email?email=' + encodeURIComponent(teamSignup.team.email) + '&teamname=' + encodeURIComponent(teamSignup.team.name)); + } else { + this.setState({serverError: err.message}); + $('#finish-button').button('reset'); + } + } + ); + }, + (err) => { + this.setState({serverError: err.message}); + $('#finish-button').button('reset'); + } + ); + } + render() { + Client.track('signup', 'signup_team_07_password'); + + var passwordError = null; + var passwordDivStyle = 'form-group'; + if (this.state.passwordError) { + passwordError =
; + passwordDivStyle = ' has-error'; + } + + var serverError = null; + if (this.state.serverError) { + serverError =
; + } + + return ( +
+
+ +

+ +

+
+ +
+
+
+ +
+
{this.props.state.team.email}
+
+
+
+
+ +
+ + + + +
+
+ {passwordError} + {serverError} +
+
+
+ +
+

+ +

+
+ + + +
+
+
+ ); + } +} + +TeamSignupPasswordPage.defaultProps = { + state: {}, + hash: '' +}; +TeamSignupPasswordPage.propTypes = { + intl: intlShape.isRequired, + state: React.PropTypes.object, + hash: React.PropTypes.string, + updateParent: React.PropTypes.func +}; + +export default injectIntl(TeamSignupPasswordPage); diff --git a/webapp/components/signup_team_complete/components/team_signup_send_invites_page.jsx b/webapp/components/signup_team_complete/components/team_signup_send_invites_page.jsx new file mode 100644 index 000000000..db060b6b9 --- /dev/null +++ b/webapp/components/signup_team_complete/components/team_signup_send_invites_page.jsx @@ -0,0 +1,215 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import $ from 'jquery'; +import EmailItem from './team_signup_email_item.jsx'; +import * as Client from 'utils/client.jsx'; + +import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; + +import logoImage from 'images/logo.png'; + +import React from 'react'; + +export default class TeamSignupSendInvitesPage extends React.Component { + constructor(props) { + super(props); + this.submitBack = this.submitBack.bind(this); + this.submitNext = this.submitNext.bind(this); + this.submitAddInvite = this.submitAddInvite.bind(this); + this.submitSkip = this.submitSkip.bind(this); + this.keySubmit = this.keySubmit.bind(this); + this.state = { + emailEnabled: global.window.mm_config.SendEmailNotifications === 'true' + }; + } + submitBack(e) { + e.preventDefault(); + this.props.state.wizard = 'team_url'; + + this.props.updateParent(this.props.state); + } + submitNext(e) { + e.preventDefault(); + + var valid = true; + + if (this.state.emailEnabled) { + var emails = []; + + for (var i = 0; i < this.props.state.invites.length; i++) { + if (this.refs['email_' + i].getWrappedInstance().validate(this.props.state.team.email)) { + emails.push(this.refs['email_' + i].getWrappedInstance().getValue()); + } else { + valid = false; + } + } + + if (valid) { + this.props.state.invites = emails; + } + } + + if (valid) { + this.props.state.wizard = 'username'; + this.props.updateParent(this.props.state); + } + } + submitAddInvite(e) { + e.preventDefault(); + this.props.state.wizard = 'send_invites'; + if (!this.props.state.invites) { + this.props.state.invites = []; + } + this.props.state.invites.push(''); + this.props.updateParent(this.props.state); + } + submitSkip(e) { + e.preventDefault(); + this.props.state.wizard = 'username'; + this.props.updateParent(this.props.state); + } + keySubmit(e) { + if (e && e.keyCode === 13) { + this.submitNext(e); + } + } + componentDidMount() { + if (!this.state.emailEnabled) { + // Must use keypress not keyup due to event chain of pressing enter + $('body').keypress(this.keySubmit); + } + } + componentWillUnmount() { + if (!this.state.emailEnabled) { + $('body').off('keypress', this.keySubmit); + } + } + render() { + Client.track('signup', 'signup_team_05_send_invites'); + + var content = null; + var bottomContent = null; + + if (this.state.emailEnabled) { + var emails = []; + + for (var i = 0; i < this.props.state.invites.length; i++) { + if (i === 0) { + emails.push( + + ); + } else { + emails.push( + + ); + } + } + + content = ( +
+ {emails} +
+ + + +
+
+ ); + + bottomContent = ( +

+ + + + + +

+ ); + } else { + content = ( +
+ +
+ ); + } + + return ( +
+
+ +

+ +

+ {content} +
+ +
+ + {bottomContent} +
+ + + +
+
+ ); + } +} + +TeamSignupSendInvitesPage.propTypes = { + state: React.PropTypes.object.isRequired, + updateParent: React.PropTypes.func.isRequired +}; diff --git a/webapp/components/signup_team_complete/components/team_signup_url_page.jsx b/webapp/components/signup_team_complete/components/team_signup_url_page.jsx new file mode 100644 index 000000000..b2ab57285 --- /dev/null +++ b/webapp/components/signup_team_complete/components/team_signup_url_page.jsx @@ -0,0 +1,211 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import $ from 'jquery'; +import ReactDOM from 'react-dom'; +import * as Utils from 'utils/utils.jsx'; +import * as Client from 'utils/client.jsx'; +import Constants from 'utils/constants.jsx'; + +import {injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl'; + +import logoImage from 'images/logo.png'; + +const holders = defineMessages({ + required: { + id: 'team_signup_url.required', + defaultMessage: 'This field is required' + }, + regex: { + id: 'team_signup_url.regex', + defaultMessage: "Use only lower case letters, numbers and dashes. Must start with a letter and can't end in a dash." + }, + charLength: { + id: 'team_signup_url.charLength', + defaultMessage: 'Name must be 4 or more characters up to a maximum of 15' + }, + taken: { + id: 'team_signup_url.taken', + defaultMessage: 'URL is taken or contains a reserved word' + }, + unavailable: { + id: 'team_signup_url.unavailable', + defaultMessage: 'This URL is unavailable. Please try another.' + } +}); + +import React from 'react'; + +class TeamSignupUrlPage extends React.Component { + constructor(props) { + super(props); + + this.submitBack = this.submitBack.bind(this); + this.submitNext = this.submitNext.bind(this); + this.handleFocus = this.handleFocus.bind(this); + + this.state = {nameError: ''}; + } + submitBack(e) { + e.preventDefault(); + this.props.state.wizard = 'team_display_name'; + this.props.updateParent(this.props.state); + } + submitNext(e) { + e.preventDefault(); + + const {formatMessage} = this.props.intl; + const name = ReactDOM.findDOMNode(this.refs.name).value.trim(); + if (!name) { + this.setState({nameError: formatMessage(holders.required)}); + return; + } + + const cleanedName = Utils.cleanUpUrlable(name); + + const urlRegex = /^[a-z]+([a-z\-0-9]+|(__)?)[a-z0-9]+$/g; + if (cleanedName !== name || !urlRegex.test(name)) { + this.setState({nameError: formatMessage(holders.regex)}); + return; + } else if (cleanedName.length < 4 || cleanedName.length > 15) { + this.setState({nameError: formatMessage(holders.charLength)}); + return; + } + + if (global.window.mm_config.RestrictTeamNames === 'true') { + for (let index = 0; index < Constants.RESERVED_TEAM_NAMES.length; index++) { + if (cleanedName.indexOf(Constants.RESERVED_TEAM_NAMES[index]) === 0) { + this.setState({nameError: formatMessage(holders.taken)}); + return; + } + } + } + + Client.findTeamByName(name, + (data) => { + if (data) { + this.setState({nameError: formatMessage(holders.unavailable)}); + } else { + if (global.window.mm_config.SendEmailNotifications === 'true') { + this.props.state.wizard = 'send_invites'; + } else { + this.props.state.wizard = 'username'; + } + this.props.state.team.type = 'O'; + + this.props.state.team.name = name; + this.props.updateParent(this.props.state); + } + }, + (err) => { + this.setState({nameError: err.message}); + } + ); + } + handleFocus(e) { + e.preventDefault(); + + e.currentTarget.select(); + } + render() { + $('body').tooltip({selector: '[data-toggle=tooltip]', trigger: 'hover click'}); + + Client.track('signup', 'signup_team_03_url'); + + let nameError = null; + let nameDivClass = 'form-group'; + if (this.state.nameError) { + nameError = ; + nameDivClass += ' has-error'; + } + + const title = `${Utils.getWindowLocationOrigin()}/`; + + return ( +
+
+ +

+ +

+
+
+
+
+ + {title} + + +
+
+
+ {nameError} +
+

+ +

+
    + +
+ +
+ + + +
+
+
+ ); + } +} + +TeamSignupUrlPage.propTypes = { + intl: intlShape.isRequired, + state: React.PropTypes.object, + updateParent: React.PropTypes.func +}; + +export default injectIntl(TeamSignupUrlPage); diff --git a/webapp/components/signup_team_complete/components/team_signup_username_page.jsx b/webapp/components/signup_team_complete/components/team_signup_username_page.jsx new file mode 100644 index 000000000..b79c1179f --- /dev/null +++ b/webapp/components/signup_team_complete/components/team_signup_username_page.jsx @@ -0,0 +1,169 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import ReactDOM from 'react-dom'; +import * as Utils from 'utils/utils.jsx'; +import * as Client from 'utils/client.jsx'; +import Constants from 'utils/constants.jsx'; + +import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl'; + +import logoImage from 'images/logo.png'; + +const holders = defineMessages({ + reserved: { + id: 'team_signup_username.reserved', + defaultMessage: 'This username is reserved, please choose a new one.' + }, + invalid: { + id: 'team_signup_username.invalid', + defaultMessage: 'Username must begin with a letter, and contain between {min} to {max} characters in total, which may be numbers, lowercase letters, or any of the symbols \'.\', \'-\', or \'_\'' + } +}); + +import React from 'react'; + +class TeamSignupUsernamePage extends React.Component { + constructor(props) { + super(props); + + this.submitBack = this.submitBack.bind(this); + this.submitNext = this.submitNext.bind(this); + + this.state = {}; + } + submitBack(e) { + e.preventDefault(); + if (global.window.mm_config.SendEmailNotifications === 'true') { + this.props.state.wizard = 'send_invites'; + } else { + this.props.state.wizard = 'team_url'; + } + + this.props.updateParent(this.props.state); + } + submitNext(e) { + e.preventDefault(); + + const {formatMessage} = this.props.intl; + var name = ReactDOM.findDOMNode(this.refs.name).value.trim().toLowerCase(); + + var usernameError = Utils.isValidUsername(name); + if (usernameError === 'Cannot use a reserved word as a username.') { //this should be change to some kind of ID + this.setState({nameError: formatMessage(holders.reserved)}); + return; + } else if (usernameError) { + this.setState({nameError: formatMessage(holders.invalid, {min: Constants.MIN_USERNAME_LENGTH, max: Constants.MAX_USERNAME_LENGTH})}); + return; + } + + this.props.state.wizard = 'password'; + this.props.state.user.username = name; + this.props.updateParent(this.props.state); + } + render() { + Client.track('signup', 'signup_team_06_username'); + + var nameError = null; + var nameHelpText = ( + + + + ); + var nameDivClass = 'form-group'; + if (this.state.nameError) { + nameError = ; + nameHelpText = ''; + nameDivClass += ' has-error'; + } + + return ( +
+
+ +

+ +

+
+ +
+
+
+
+
+
+ +
+ + {nameHelpText} +
+
+ {nameError} +
+
+ +
+ + + +
+
+
+ ); + } +} + +TeamSignupUsernamePage.defaultProps = { + state: null +}; +TeamSignupUsernamePage.propTypes = { + intl: intlShape.isRequired, + state: React.PropTypes.object, + updateParent: React.PropTypes.func +}; + +export default injectIntl(TeamSignupUsernamePage); diff --git a/webapp/components/signup_team_complete/components/team_signup_welcome_page.jsx b/webapp/components/signup_team_complete/components/team_signup_welcome_page.jsx new file mode 100644 index 000000000..99e633659 --- /dev/null +++ b/webapp/components/signup_team_complete/components/team_signup_welcome_page.jsx @@ -0,0 +1,239 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import ReactDOM from 'react-dom'; +import * as Utils from 'utils/utils.jsx'; +import * as Client from 'utils/client.jsx'; +import BrowserStore from 'stores/browser_store.jsx'; + +import {injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl'; + +import {browserHistory} from 'react-router'; + +import logoImage from 'images/logo.png'; + +const holders = defineMessages({ + storageError: { + id: 'team_signup_welcome.storageError', + defaultMessage: 'This service requires local storage to be enabled. Please enable it or exit private browsing.' + }, + validEmailError: { + id: 'team_signup_welcome.validEmailError', + defaultMessage: 'Please enter a valid email address' + }, + address: { + id: 'team_signup_welcome.address', + defaultMessage: 'Email Address' + } +}); + +import React from 'react'; + +class TeamSignupWelcomePage extends React.Component { + constructor(props) { + super(props); + + this.submitNext = this.submitNext.bind(this); + this.handleDiffEmail = this.handleDiffEmail.bind(this); + this.handleDiffSubmit = this.handleDiffSubmit.bind(this); + this.handleKeyPress = this.handleKeyPress.bind(this); + + this.state = {useDiff: false}; + + document.addEventListener('keyup', this.handleKeyPress, false); + } + submitNext(e) { + if (!BrowserStore.isLocalStorageSupported()) { + this.setState({storageError: this.props.intl.formatMessage(holders.storageError)}); + return; + } + e.preventDefault(); + this.props.state.wizard = 'team_display_name'; + this.props.updateParent(this.props.state); + } + handleDiffEmail(e) { + e.preventDefault(); + this.setState({useDiff: true}); + } + handleDiffSubmit(e) { + e.preventDefault(); + + const {formatMessage} = this.props.intl; + var state = {useDiff: true, serverError: ''}; + + var email = ReactDOM.findDOMNode(this.refs.email).value.trim().toLowerCase(); + if (!email || !Utils.isEmail(email)) { + state.emailError = formatMessage(holders.validEmailError); + this.setState(state); + return; + } else if (!BrowserStore.isLocalStorageSupported()) { + state.emailError = formatMessage(holders.storageError); + this.setState(state); + return; + } + state.emailError = ''; + + Client.signupTeam(email, + function success(data) { + if (data.follow_link) { + window.location.href = data.follow_link; + } else { + this.props.state.wizard = 'finished'; + this.props.updateParent(this.props.state); + browserHistory.push('/signup_team_confirm/?email=' + encodeURIComponent(email)); + } + }.bind(this), + function error(err) { + let errorMsg = err.message; + + if (err.detailed_error.indexOf('Invalid RCPT TO address provided') >= 0) { + errorMsg = formatMessage(holders.validEmailError); + } + + this.setState({emailError: '', serverError: errorMsg}); + }.bind(this) + ); + } + handleKeyPress(event) { + if (event.keyCode === 13) { + this.submitNext(event); + } + } + componentWillUnmount() { + document.removeEventListener('keyup', this.handleKeyPress, false); + } + render() { + Client.track('signup', 'signup_team_01_welcome'); + + var storageError = null; + if (this.state.storageError) { + storageError = ; + } + + var emailError = null; + var emailDivClass = 'form-group'; + if (this.state.emailError) { + emailError = ; + emailDivClass += ' has-error'; + } + + var serverError = null; + if (this.state.serverError) { + serverError = ( +
+ +
+ ); + } + + var differentEmailLinkClass = ''; + var emailDivContainerClass = 'hidden'; + if (this.state.useDiff) { + differentEmailLinkClass = 'hidden'; + emailDivContainerClass = ''; + } + + return ( +
+ +

+ +

+

{global.window.mm_config.SiteName}

+

+ +

+
+ +
+
+
{this.props.state.team.email}
+
+
+

+ +

+
+ + {storageError} +
+
+
+
+
+
+ +
+
+ {emailError} +
+ {serverError} + +
+ + + +
+ ); + } +} + +TeamSignupWelcomePage.defaultProps = { + state: {} +}; +TeamSignupWelcomePage.propTypes = { + intl: intlShape.isRequired, + updateParent: React.PropTypes.func.isRequired, + state: React.PropTypes.object +}; + +export default injectIntl(TeamSignupWelcomePage); -- cgit v1.2.3-1-g7c22