Skip to content

Commit

Permalink
User signs up
Browse files Browse the repository at this point in the history
  • Loading branch information
Remchi committed Sep 6, 2017
1 parent 9ef2076 commit baa1715
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@ 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";

const App = ({ location }) => (
<div className="ui container">
<Route location={location} path="/" exact component={HomePage} />
<GuestRoute location={location} path="/login" exact component={LoginPage} />
<GuestRoute
location={location}
path="/signup"
exact
component={SignupPage}
/>
<UserRoute
location={location}
path="/dashboard"
Expand Down
5 changes: 5 additions & 0 deletions src/actions/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import api from "../api";
import { userLoggedIn } from "./auth";

export const signup = data => dispatch =>
api.user.signup(data).then(user => dispatch(userLoggedIn(user)));
4 changes: 3 additions & 1 deletion src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
};
86 changes: 86 additions & 0 deletions src/components/forms/SignupForm.js
Original file line number Diff line number Diff line change
@@ -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 (
<Form onSubmit={this.onSubmit} loading={loading}>
<Form.Field error={!!errors.email}>
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
name="email"
placeholder="[email protected]"
value={data.email}
onChange={this.onChange}
/>
{errors.email && <InlineError text={errors.email} />}
</Form.Field>

<Form.Field error={!!errors.password}>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
name="password"
value={data.password}
onChange={this.onChange}
/>
{errors.password && <InlineError text={errors.password} />}
</Form.Field>

<Button primary>Sign Up</Button>
</Form>
);
}
}

SignupForm.propTypes = {
submit: PropTypes.func.isRequired
};

export default SignupForm;
4 changes: 3 additions & 1 deletion src/components/pages/HomePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ const HomePage = ({ isAuthenticated, logout }) => (
{isAuthenticated ? (
<button onClick={() => logout()}>Logout</button>
) : (
<Link to="/login">Login</Link>
<div>
<Link to="/login">Login</Link> or <Link to="/signup">Sign Up</Link>
</div>
)}
</div>
);
Expand Down
27 changes: 27 additions & 0 deletions src/components/pages/SignupPage.js
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<SignupForm submit={this.submit} />
</div>
);
}
}

SignupPage.propTypes = {
history: PropTypes.shape({
push: PropTypes.func.isRequired
}).isRequired,
signup: PropTypes.func.isRequired
};

export default connect(null, { signup })(SignupPage);

0 comments on commit baa1715

Please sign in to comment.