Skip to content

Commit

Permalink
Merge d217a26 into b641b75
Browse files Browse the repository at this point in the history
  • Loading branch information
segunolalive committed Oct 19, 2017
2 parents b641b75 + d217a26 commit 7c60813
Show file tree
Hide file tree
Showing 8 changed files with 306 additions and 19 deletions.
2 changes: 1 addition & 1 deletion client/actions/api.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
let api = '/api/v1';

if (process.env.NODE_ENV === 'development') {
api = 'http://localhost:5000/api/v1';
api = 'http://localhost:4000/api/v1';
}

/**
Expand Down
9 changes: 4 additions & 5 deletions client/components/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import BookDetail from './library/BookDetail';
import Dashboard from './dashboard/Dashboard';
import Logout from './auth/Logout';
// import ForgotPassword from './forgotPassword';
//
// import UpdateProfile from './dashboard/UpdateProfile';
import UpdateProfile from './dashboard/UpdateProfile';

import mock from './mock';

Expand All @@ -28,7 +27,7 @@ import mock from './mock';
class App extends Component {
/**
* Creates an instance of App.
* @param {Object} props
* @param {Object} props
* @memberof App
*/
constructor(props) {
Expand All @@ -38,7 +37,7 @@ class App extends Component {
}
/**
* renders app to DOM
*
*
* @returns {JSX} JSX representation of component
* @memberof App
*/
Expand All @@ -49,7 +48,7 @@ class App extends Component {
<Switch>
<Route path='/' exact component={Home} />
<Route path='/dashboard' component={Dashboard} />
{/* <Route path='/update-profile'component={UpdateProfile} /> */}
<Route path='/update-profile'component={UpdateProfile} />
<Route path='/login' component={Login} />
<Route path='/logout' component={Logout} />
<Route path='/signup' component={SignUp} />
Expand Down
179 changes: 179 additions & 0 deletions client/components/auth/Login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { Row } from 'react-materialize';
import GoogleLogin from 'react-google-login';
import FaGoogle from 'react-icons/lib/fa/google';

import Header from '../header/Header';
import { login } from '../../actions/login';
import Loading from '../Loading';


const Materialize = window.Materialize;

/*
eslint-disable
*/
class Login extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
};
this.handleLogin = this.handleLogin.bind(this);
this.handleChange = this.handleChange.bind(this);
this.responseGoogle = this.responseGoogle.bind(this);
}

responseGoogle(response) {
// const loginProfile = response.getBasicProfile();
console.log(response);
}

handleLogin(event) {
event.preventDefault();
this.setState({ isLoading: true });
this.props.login(this.state)
.then(
(data) => {
Materialize.toast(
`Welcome Back, ${data.firstName || 'Reader'}`,
2500,
'teal darken-4'
);
},
(error) => {
Materialize.toast(error.response.data.message, 2500, 'red darken-4');
this.setState({ isLoading: false });
}
)
.catch((err) => {
Materialize.toast(
`Ouch! Something went awry. It's probably our fault`,
2500,
'red darken-4'
);
this.setState({ isLoading: false });
});
}

handleChange(event) {
event.preventDefault();
const formField = event.target.name;
const user = Object.assign({}, this.state);
if (!!event.target.value.trim()) {
user[formField] = event.target.value.trim();
}
this.setState(() => user);
}

render() {
const loadingState = this.state.isLoading ?
<Loading text='logging in' /> : null
return (
this.props.isLoggedIn === true ?
<Redirect to='/dashboard'/> :
<div>
<Header
navLinks={['login', 'sign up', 'library']}
/>
<main>
<section className="account">
<Row>
<div className="container">
<div className="center">
<div className="col m6 s12 welcome">
<h2>Hello Reader</h2>
<h6>Welcome home avid reader</h6>
</div>
<div className="col m6 s12">
<form onSubmit={this.handleLogin}>
<div className="col s12">
<h5>Login</h5>
</div>
<div className="col s12">
<div className="container">
<div className="input-field">
<input type="text"
name="username"
placeholder="Username"
className="validate"
required
title="username is required for login"
onChange={this.handleChange}
/>
</div>
<div className="input-field">
<input type="password"
name="password"
placeholder="password"
className="validate"
required
title="password is required for login"
onChange={this.handleChange}
/>
</div>
{loadingState}
<div className="input-field">
<input
type="submit"
name="submit"
value="LOGIN"
className="btn waves-effect waves-light"
style={{ width: '100%' }}
/>
</div>
<div className="input-field">
{/* <GoogleLogin
clientId={GOOGLE_CLIENT_ID}
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
className="btn red darken-4"
style={{ width: '100%' }}
>
<FaGoogle
style={{
color: '#032442',
fontSize: '2rem',
}}
/>
<span> Login with Google</span>
</GoogleLogin> */}
</div>
<div>
<p className="center">Don&apos;t have an account?
<Link to="/signup"> Sign up</Link>
</p>
</div>
<div>
<p className="center">Forgot password? &nbsp; &nbsp;
<Link to="/forgot-password"> Click here</Link>
</p>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</Row>
</section>
</main>
</div>
);
}
}

Login.propTypes = {
login: PropTypes.func.isRequired,
};

const mapStateToProps = ({ authReducer }) => (
{ isLoggedIn: authReducer.isLoggedIn }
);


export default connect(mapStateToProps, { login })(Login);
8 changes: 4 additions & 4 deletions client/components/dashboard/ProfileInfo.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { Col, Icon } from 'react-materialize';
import imageFallback from '../../static/profile_image.png';

Expand All @@ -20,13 +21,12 @@ const ProfileInfo = props => (
</div>
</Col>
<Col s={12} className="profile-info">
<a className="btn waves-effect"
href="#"
onClick={props.onClick}
<Link className="btn waves-effect"
to="/update-profile"
>
<Icon>edit</Icon>
Edit Profile
</a>
</Link>
</Col>
</Col>
);
Expand Down
109 changes: 109 additions & 0 deletions client/components/dashboard/UpdateProfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Col, Row } from 'react-materialize';

import Header from '../header/Header';

/**
* Component to update user profile
* @type {Object}
*/
class UpdateProfile extends Component {
/**
* constructs instance of Component
* @return {Object} JSX component
*/
constructor() {
super();
this.handleSubmit = this.handleSubmit.bind(this);
}
/**
* handles form submission
* @param {Object} event DOM onSubmit event
* @return {mixed} sends a network request
*/
handleSubmit(event) {
event.preventDefault();
}

/**
* class method that renders a component to the DOM
* @return {Object} JSX element
*/
render() {
return (
<div>
<Header
activeLink='dashboard'
/>
<main>
<Row>
<Col s={12} m={6} className="offset-m3">
<form onSubmit={this.handleSubmit}>
<div style={{ marginBottom: '50px' }}>
<h5 className="center" >
Update your profile information
</h5>
</div>

<div className="input-field">
<h6>First Name:</h6>
<input
id="firstName"
defaultValue={this.props.user.firstName || ''}
/>
</div>
<div className="input-field">
<h6>Last Name:</h6>
<input
id="lastName"
defaultValue={this.props.user.lastName || ''}
/>
</div>
<h6 className="red-text darken-4" >
Leave the password fields empty unless you actually want
to change your password
</h6>
<div className="input-field">
<h6>Current Password:</h6>
<input
id=""
type="password"
defaultValue=""
/>
</div>
<div className="input-field">
<h6>New Password:</h6>
<input
type="password"
id="newPassword"
defaultValue=""
/>
</div>
<div className="input-field">
<input
className="btn teal darken-4 waves-effect waves-light"
style={{ width: '100%' }}
type="submit"
value="Submit"
/>
</div>
</form>
</Col>
</Row>
</main>
</div>
);
}
}

UpdateProfile.propTypes = {
user: PropTypes.object.isRequired,
};

const mapStateToProps = ({ authReducer }) => ({
user: authReducer.user,
});

export default connect(mapStateToProps)(UpdateProfile);
2 changes: 1 addition & 1 deletion server/bin/www.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import http from 'http';

import app from '../app';

const port = parseInt(process.env.PORT, 10) || 5000;
const port = parseInt(process.env.PORT, 10) || 4000;

const server = http.createServer(app);

Expand Down
2 changes: 1 addition & 1 deletion server/middleware/authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dotenv.config();
*/
const getToken = (req) => {
const token = req.body.token || req.headers['x-access-token'] ||
req.headers.Authorization.slice(7);
(req.headers.Authorization && req.headers.Authorization.slice(7));
return token;
};

Expand Down
14 changes: 7 additions & 7 deletions webpack.prod.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ module.exports = {
warnings: false
}
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
},
GOOGLE_CLIENT_SECRET: JSON.stringify('VenazYqo1V-41a8pAocf7a9H'),
GOOGLE_CLIENT_ID: JSON.stringify('701806023399-vgqondt26qh10vcuei77r7nsbcd8oa8k.apps.googleusercontent.com')
})
// new webpack.DefinePlugin({
// 'process.env': {
// NODE_ENV: JSON.stringify('production')
// },
// GOOGLE_CLIENT_SECRET: JSON.stringify('VenazYqo1V-41a8pAocf7a9H'),
// GOOGLE_CLIENT_ID: JSON.stringify('701806023399-vgqondt26qh10vcuei77r7nsbcd8oa8k.apps.googleusercontent.com')
// })
],
};

0 comments on commit 7c60813

Please sign in to comment.