From baa171539eb78a1bec98995d8df0cad61f42f7cf Mon Sep 17 00:00:00 2001 From: Rem Zolotykh Date: Wed, 6 Sep 2017 22:02:21 +0300 Subject: [PATCH] User signs up --- src/App.js | 7 +++ src/actions/users.js | 5 ++ src/api.js | 4 +- src/components/forms/SignupForm.js | 86 ++++++++++++++++++++++++++++++ src/components/pages/HomePage.js | 4 +- src/components/pages/SignupPage.js | 27 ++++++++++ 6 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 src/actions/users.js create mode 100644 src/components/forms/SignupForm.js create mode 100644 src/components/pages/SignupPage.js diff --git a/src/App.js b/src/App.js index e9cbc0b..607efc7 100644 --- a/src/App.js +++ b/src/App.js @@ -4,6 +4,7 @@ import { Route } from "react-router-dom"; import HomePage from "./components/pages/HomePage"; import LoginPage from "./components/pages/LoginPage"; import DashboardPage from "./components/pages/DashboardPage"; +import SignupPage from "./components/pages/SignupPage"; import UserRoute from "./components/routes/UserRoute"; import GuestRoute from "./components/routes/GuestRoute"; @@ -11,6 +12,12 @@ const App = ({ location }) => (
+ dispatch => + api.user.signup(data).then(user => dispatch(userLoggedIn(user))); diff --git a/src/api.js b/src/api.js index 40eb6fa..1a37adf 100644 --- a/src/api.js +++ b/src/api.js @@ -3,6 +3,8 @@ import axios from "axios"; export default { user: { login: credentials => - axios.post("/api/auth", { credentials }).then(res => res.data.user) + axios.post("/api/auth", { credentials }).then(res => res.data.user), + signup: user => + axios.post("/api/users", { user }).then(res => res.data.user) } }; diff --git a/src/components/forms/SignupForm.js b/src/components/forms/SignupForm.js new file mode 100644 index 0000000..d7bcd99 --- /dev/null +++ b/src/components/forms/SignupForm.js @@ -0,0 +1,86 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Form, Button } from "semantic-ui-react"; +import isEmail from "validator/lib/isEmail"; +import InlineError from "../messages/InlineError"; + +class SignupForm extends React.Component { + state = { + data: { + email: "", + password: "" + }, + loading: false, + errors: {} + }; + + onChange = e => + this.setState({ + ...this.state, + data: { ...this.state.data, [e.target.name]: e.target.value } + }); + + onSubmit = e => { + e.preventDefault(); + const errors = this.validate(this.state.data); + this.setState({ errors }); + if (Object.keys(errors).length === 0) { + this.setState({ loading: true }); + this.props + .submit(this.state.data) + .catch(err => + this.setState({ errors: err.response.data.errors, loading: false }) + ); + } + }; + + validate = data => { + const errors = {}; + + if (!isEmail(data.email)) errors.email = "Invalid email"; + if (!data.password) errors.password = "Can't be blank"; + + return errors; + }; + + render() { + const { data, errors, loading } = this.state; + + return ( +
+ + + + {errors.email && } + + + + + + {errors.password && } + + + +
+ ); + } +} + +SignupForm.propTypes = { + submit: PropTypes.func.isRequired +}; + +export default SignupForm; diff --git a/src/components/pages/HomePage.js b/src/components/pages/HomePage.js index 6c588ab..3472d10 100644 --- a/src/components/pages/HomePage.js +++ b/src/components/pages/HomePage.js @@ -10,7 +10,9 @@ const HomePage = ({ isAuthenticated, logout }) => ( {isAuthenticated ? ( ) : ( - Login +
+ Login or Sign Up +
)}
); diff --git a/src/components/pages/SignupPage.js b/src/components/pages/SignupPage.js new file mode 100644 index 0000000..afc835f --- /dev/null +++ b/src/components/pages/SignupPage.js @@ -0,0 +1,27 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; +import SignupForm from "../forms/SignupForm"; +import { signup } from "../../actions/users"; + +class SignupPage extends React.Component { + submit = data => + this.props.signup(data).then(() => this.props.history.push("/dashboard")); + + render() { + return ( +
+ +
+ ); + } +} + +SignupPage.propTypes = { + history: PropTypes.shape({ + push: PropTypes.func.isRequired + }).isRequired, + signup: PropTypes.func.isRequired +}; + +export default connect(null, { signup })(SignupPage);