Skip to content

Commit

Permalink
fix(signup): redirect to login page
Browse files Browse the repository at this point in the history
- redirect to the login page after a user signsup successfully

[Delivers #161861613]
  • Loading branch information
MuhanguziDavid committed Nov 14, 2018
1 parent 1398ed8 commit cfab494
Show file tree
Hide file tree
Showing 16 changed files with 187 additions and 127 deletions.
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.6.0",
"history": "^4.7.2",
"jest-localstorage-mock": "^2.3.0",
"jwt-decode": "^2.2.0",
"node-sass": "^4.9.4",
"prop-types": "^15.6.2",
"react": "^16.6.0",
Expand Down Expand Up @@ -56,5 +58,11 @@
"jest": "^23.6.0",
"jest-cli": "^20.0.4",
"redux-mock-store": "^1.5.3"
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,mjs}",
"!src/setupTests.js"
]
}
}
16 changes: 16 additions & 0 deletions src/__mocks__/jwt-decode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const current_time = new Date().getTime() / 1000;

const jwt_decode = (token = '') => {
if (token !== '') {
return {
exp: current_time + 1000,
name: 'user1',
};
}
return {
exp: current_time - 1000,
name: 'user1',
};
};

export default jwt_decode;
4 changes: 1 addition & 3 deletions src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ export const LOGIN_USER_ERROR = 'LOGIN_USER_ERROR';
export const SOCIAL_LOGIN_INITIATED = 'SOCIAL_LOGIN_INITIATED';
export const SOCIAL_LOGIN_SUCCESS = 'SOCIAL_LOGIN_SUCCESS';
export const GET_ALL_ARTICLES_SUCCESS = 'GET_ALL_ARTICLES_SUCCESS';

// Profile action types
export const GET_PROFILE_PAYLOAD = 'GET_PROFILE_PAYLOAD';
export const GET_PROFILE_ERROR = 'GET_PROFILE_ERROR';
export const GET_PROFILE_INITIATED = 'GET_PROFILE_INITIATED';
export const LOGOUT_USER = 'LOGOUT_USER';
21 changes: 18 additions & 3 deletions src/actions/userActions.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import axios from 'axios';
import { toast } from 'react-toastify';
import jwt_decode from 'jwt-decode';
import {
REGISTER_USER_SUCCESS,
REGISTER_USER_ERROR,
LOGIN_USER_SUCCESS,
LOGIN_USER_ERROR,
GET_PROFILE_PAYLOAD,
GET_PROFILE_ERROR,
GET_PROFILE_INITIATED,
LOGOUT_USER,
} from './types';
import {
socialLoginInitiated,
Expand All @@ -24,7 +25,7 @@ export const fetchUsers = (postData) => dispatch => {
localStorage.setItem('auth_token', response.data.user.auth_token);
localStorage.setItem('username', response.data.user.username);
dispatch({ type: REGISTER_USER_SUCCESS, payload: true });
toast.success('Signup successful', { autoClose: 3500, hideProgressBar: true });
toast.success('Signup successful. Please proceed to login', { autoClose: 3500, hideProgressBar: true });
})
.catch((error) => {
let errorMessage = '';
Expand Down Expand Up @@ -100,6 +101,19 @@ export const facebookLoginUser = (serviceProvider, userData) => (dispatch) => {
});
});
};

export const updateLoginStatus = () => dispatch => {
const auth_token = localStorage.getItem('auth_token');
if (auth_token) {
const decoded_auth_token = jwt_decode(auth_token);
const current_time = new Date().getTime() / 1000;
if (current_time < decoded_auth_token.exp) {
return dispatch({ type: LOGIN_USER_SUCCESS, payload: true });
}
}
return dispatch({ type: LOGIN_USER_SUCCESS, payload: false });
};

export const getProfile = () => dispatch => {
dispatch({ type: GET_PROFILE_INITIATED, payload: true });
const auth_token = localStorage.getItem('auth_token');
Expand All @@ -112,6 +126,7 @@ export const getProfile = () => dispatch => {
dispatch({ type: GET_PROFILE_PAYLOAD, payload: response.data.profile });
})
.catch(() => {
dispatch({ type: GET_PROFILE_ERROR, payload: 'This profile does not exist' });
localStorage.removeItem('auth_token');
dispatch({ type: LOGOUT_USER, payload: false });
});
};
26 changes: 19 additions & 7 deletions src/components/landingPage/Navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { NavLink } from 'react-router-dom';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import img from '../../assets/images/logo.png';
import { updateLoginStatus } from '../../actions/userActions';

export class Navbar extends Component {
constructor(props) {
Expand All @@ -12,15 +14,20 @@ export class Navbar extends Component {
};
}

componentDidMount() {
const { updateLoginStatus } = this.props;
updateLoginStatus();
}

componentWillReceiveProps(nextProps) {
if (nextProps.isLoginSuccess === true) {
if (nextProps.isLoggedIn === true) {
this.state.isLoggedIn = true;
}
}

render() {
const username = localStorage.getItem('username');
const { isLoggedIn } = this.state;
const { isLoggedIn } = this.props;
return (
<nav className="navbar fixed-top navbar-expand-lg nav-bg">
<div className="container">
Expand Down Expand Up @@ -50,7 +57,7 @@ export class Navbar extends Component {
<div className="dropdown-menu" aria-labelledby="navbarDropdown">
<NavLink className="dropdown-item" to={`/profiles/${username}`}>Profile</NavLink>
<div className="dropdown-divider" />
<a className="dropdown-item" href="#">Logout</a>
<NavLink className="dropdown-item" to="#">Logout</NavLink>
</div>
</div>
</li>
Expand Down Expand Up @@ -78,15 +85,20 @@ export class Navbar extends Component {
}

const mapStateToProps = state => ({
isLoginSuccess: state.user.isLoginSuccess,
isLoggedIn: state.user.isLoggedIn,
});

const matchDispatchToProps = (dispatch) => bindActionCreators({
updateLoginStatus,
}, dispatch);

Navbar.propTypes = {
isLoginSuccess: PropTypes.bool,
isLoggedIn: PropTypes.bool,
updateLoginStatus: PropTypes.func.isRequired,
};

Navbar.defaultProps = {
isLoginSuccess: false,
isLoggedIn: false,
};

export default connect(mapStateToProps, {})(Navbar);
export default connect(mapStateToProps, matchDispatchToProps)(Navbar);
8 changes: 4 additions & 4 deletions src/components/login/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class Login extends Component {
}

componentWillReceiveProps(nextProps) {
if (nextProps.isLoginSuccess === true) {
if (nextProps.isLoggedIn === true) {
const { history } = this.props;
history.push('/dashboard');
}
Expand Down Expand Up @@ -115,17 +115,17 @@ export class Login extends Component {

Login.propTypes = {
signIn: PropTypes.func.isRequired,
isLoginSuccess: PropTypes.bool,
isLoggedIn: PropTypes.bool,
history: PropTypes.object.isRequired,
};

Login.defaultProps = {
isLoginSuccess: false,
isLoggedIn: false,
};

const mapStateToProps = state => ({
isLoginPending: state.user.isLoginPending,
isLoginSuccess: state.user.isLoginSuccess,
isLoggedIn: state.user.isLoggedIn,
loginError: state.user.loginError,
});

Expand Down
48 changes: 23 additions & 25 deletions src/components/profiles/Profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,33 @@ import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Loader from 'react-loader';
import PropTypes from 'prop-types';
import 'react-toastify/dist/ReactToastify.css';
import profileImage from '../../assets/images/profileImage.png';
import { getProfile } from '../../actions/userActions';

export class Profile extends Component {
constructor(props) {
super(props);
this.state = {
loaded: false,
};
}

componentDidMount() {
const { getProfile } = this.props;
getProfile();
}

componentWillReceiveProps(nextProps) {
if (nextProps.getProfileInitiated === true) {
this.setState({ loaded: true });
if (nextProps.isLoggedIn === false) {
const { history } = this.props;
history.push('/login');
}
}

render() {
const { loaded } = this.state;
const { getProfilePayload } = this.props;
const profileData = getProfilePayload;
const {
loading, profilePayload: {
followers, following, username, bio,
},
} = this.props;
let followersNumber;
let followingNumber;
if (profileData.followers) {
followersNumber = profileData.followers.length;
followingNumber = profileData.following.length;
if (followers) {
followersNumber = followers.length;
followingNumber = following.length;
} else {
followersNumber = 'loading';
followingNumber = 'loading';
Expand All @@ -45,15 +40,15 @@ export class Profile extends Component {
<div className="container-fluid ah-container">
<div>
<div className="col-9 mx-auto lp-intro">
<Loader loaded={loaded}>
<Loader loaded={!loading}>
<div className="row profile-header ah-container">
<div className="col-4">
<img className="img-thumbnail profile-image" src={profileImage} alt="avatar" />
</div>
<div className="col-6 top-buffer">
<div className="row">
<div className="col-12">
<h3 className="profile-username">{ profileData.username }</h3>
<h3 className="profile-username">{ username }</h3>
</div>
</div>
<div className="row followers-following">
Expand Down Expand Up @@ -83,7 +78,7 @@ export class Profile extends Component {
</div>
<div className="row bottom-filler bio-body">
<p align="justify">
{ profileData.bio }
{ bio }
</p>
</div>
</Loader>
Expand All @@ -96,23 +91,26 @@ export class Profile extends Component {
}

const mapStateToProps = state => ({
getProfilePayload: state.user.getProfilePayload,
getProfileInitiated: state.user.getProfileInitiated,
profilePayload: state.user.profilePayload,
isLoggedIn: state.user.isLoggedIn,
loading: state.user.loading,
});

const matchDispatchToProps = (dispatch) => bindActionCreators({
getProfile,
}, dispatch);

Profile.propTypes = {
getProfilePayload: PropTypes.object,
profilePayload: PropTypes.object,
getProfile: PropTypes.func.isRequired,
getProfileInitiated: PropTypes.bool,
isLoggedIn: PropTypes.bool,
history: PropTypes.object.isRequired,
loading: PropTypes.bool.isRequired,
};

Profile.defaultProps = {
getProfilePayload: false,
getProfileInitiated: false,
profilePayload: {},
isLoggedIn: true,
};

export default connect(mapStateToProps, matchDispatchToProps)(Profile);
2 changes: 1 addition & 1 deletion src/components/register/RegisterUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class RegisterUser extends Component {
componentWillReceiveProps(nextProps) {
if (nextProps.registerUserSuccess === true) {
const { history } = this.props;
history.push('/');
history.push('/login');
}
}

Expand Down
23 changes: 11 additions & 12 deletions src/reducers/userReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,18 @@ import {
SOCIAL_LOGIN_INITIATED,
SOCIAL_LOGIN_SUCCESS,
GET_PROFILE_PAYLOAD,
GET_PROFILE_ERROR,
GET_PROFILE_INITIATED,
LOGOUT_USER,
} from '../actions/types';


const initialState = {
registerUserSuccess: false,
isLoginSuccess: false,
isLoggedIn: false,
registerUserError: {},
loginError: {},
isLoggedIn: false,
loading: false,
getProfilePayload: {},
getProfileError: '',
getProfileInitiated: false,
profilePayload: {},
};


Expand All @@ -39,7 +36,7 @@ const userReducer = (state = initialState, action) => {
case LOGIN_USER_SUCCESS:
return {
...state,
isLoginSuccess: action.payload,
isLoggedIn: action.payload,
};

case LOGIN_USER_ERROR:
Expand All @@ -62,17 +59,19 @@ const userReducer = (state = initialState, action) => {
case GET_PROFILE_PAYLOAD:
return {
...state,
getProfilePayload: action.payload,
profilePayload: action.payload,
loading: false,
};
case GET_PROFILE_ERROR:
case GET_PROFILE_INITIATED:
return {
...state,
getProfileError: action.payload,
loading: action.payload,
};
case GET_PROFILE_INITIATED:
case LOGOUT_USER:
return {
...state,
getProfileInitiated: action.payload,
isLoggedIn: action.payload,
loading: false,
};
default:
return state;
Expand Down
Loading

0 comments on commit cfab494

Please sign in to comment.