@datawheel/canon-core
Version:
Reusable React environment and components for creating visualization engines.
142 lines (121 loc) • 5.07 kB
JSX
import React, {Component} from "react";
import PropTypes from "prop-types";
import {connect} from "react-redux";
import {withNamespaces} from "react-i18next";
import {signup} from "../actions/auth";
import {Intent} from "@blueprintjs/core";
import {SocialButtons} from "./SocialButtons";
import {SIGNUP_EXISTS} from "../consts";
import "./Forms.css";
class SignUp extends Component {
constructor(props) {
super(props);
this.state = {
agreedToTerms: false,
error: null,
password: "",
passwordAgain: "",
email: null,
submitted: false
};
this.onChange = this.onChange.bind(this);
}
onChange(e) {
const val = e.target.name === "agreedToTerms" ? e.target.checked : e.target.value;
this.setState({[e.target.name]: val});
}
onSubmit(e) {
e.preventDefault();
const {legal, redirect, t} = this.props;
const {agreedToTerms, email, password, passwordAgain, username} = this.state;
if (password !== passwordAgain) {
this.setState({error: {icon: "lock", message: t("SignUp.error.PasswordMatch")}});
}
else if (!username || !email || !password) {
this.setState({error: {icon: "id-number", message: t("SignUp.error.IncompleteFields")}});
}
else if ((legal.privacy || legal.terms) && !agreedToTerms) {
this.setState({error: {icon: "saved", message: t("SignUp.error.TermsAgree")}});
}
else {
this.props.signup({username, email, password, redirect});
this.setState({submitted: true});
}
}
componentDidUpdate() {
const {auth, t} = this.props;
const {error, submitted} = this.state;
if (submitted && !auth.loading) {
if (auth.error === SIGNUP_EXISTS) {
this.showToast(t("SignUp.error.Exists"), "blocked-person", Intent.WARNING);
}
else if (!auth.error) {
this.showToast(t("SignUp.success"), "endorsed", Intent.SUCCESS);
}
this.setState({submitted: false});
}
else if (error) {
this.showToast(error.message, error.icon, error.intent);
this.setState({error: false});
}
}
showToast(message, icon = "lock", intent = Intent.DANGER) {
const Toast = this.context.toast.current;
Toast.show({icon, intent, message});
}
render() {
const {auth, legal, social, t} = this.props;
const {agreedToTerms} = this.state;
const email = this.state.email === null ? auth.error && auth.error.email ? auth.error.email : "" : this.state.email;
return (
<div>
<form id="signup" onSubmit={this.onSubmit.bind(this)} className="login-container">
<div className="bp3-input-group">
<span className="bp3-icon bp3-icon-envelope"></span>
<input className="bp3-input" placeholder={ t("SignUp.E-mail") } value={email} type="email" name="email" onChange={this.onChange} tabIndex="1" />
</div>
<div className="bp3-input-group">
<span className="bp3-icon bp3-icon-user"></span>
<input className="bp3-input" placeholder={ t("SignUp.Username") } value={this.state.username} type="text" name="username" onFocus={this.onChange} onChange={this.onChange} tabIndex="2" />
</div>
<div className="bp3-input-group">
<span className="bp3-icon bp3-icon-lock"></span>
<input className="bp3-input" placeholder={ t("SignUp.Password") } value={this.state.password} type="password" name="password" onFocus={this.onChange} onChange={this.onChange} autoComplete="Off" tabIndex="3" />
</div>
<div className="bp3-input-group">
<span className="bp3-icon bp3-icon-lock"></span>
<input className="bp3-input" placeholder={ t("SignUp.Confirm Password") } value={this.state.passwordAgain} type="password" name="passwordAgain" onFocus={this.onChange} onChange={this.onChange} autoComplete="Off" tabIndex="4" />
</div>
{ legal.privacy || legal.terms
? <label className="bp3-control bp3-checkbox" htmlFor="ppcbox">
<input type="checkbox" id="ppcbox" name="agreedToTerms" checked={agreedToTerms} onChange={this.onChange} />
<span className="bp3-control-indicator"></span>
<span dangerouslySetInnerHTML={{__html: legal.privacy && legal.terms ? t("SignUp.PrivacyTermsText", legal) : legal.privacy ? t("SignUp.PrivacyText", legal) : t("SignUp.TermsText", legal)}}></span>
</label>
: null }
<button type="submit" className="bp3-button bp3-fill" tabIndex="5">{ t("SignUp.Sign Up") }</button>
</form>
<SocialButtons social={social} />
</div>
);
}
}
SignUp.defaultProps = {
redirect: "/"
};
SignUp.contextTypes = {
toast: PropTypes.object
};
const mapStateToProps = state => ({
auth: state.auth,
legal: state.legal,
social: state.social
});
const mapDispatchToProps = dispatch => ({
signup: userData => {
dispatch(signup(userData));
}
});
SignUp = withNamespaces()(SignUp);
SignUp = connect(mapStateToProps, mapDispatchToProps)(SignUp);
export {SignUp};