fix #180, relates to #185 in that the user is redirected to where they were post signup/login

This commit is contained in:
Cassie Tarakajian 2016-11-10 16:13:00 -05:00
parent c959aec6a9
commit 66b83df0f2
12 changed files with 72 additions and 31 deletions

View file

@ -104,3 +104,4 @@ export const RESET_JUST_OPENED_PROJECT = 'RESET_JUST_OPENED_PROJECT';
export const SET_PROJECT_SAVED_TIME = 'SET_PROJECT_SAVED_TIME';
export const RESET_PROJECT_SAVED_TIME = 'RESET_PROJECT_SAVED_TIME';
export const SET_PREVIOUS_PATH = 'SET_PREVIOUS_PATH';

View file

@ -220,3 +220,10 @@ export function resetProjectSavedTime() {
type: ActionTypes.RESET_PROJECT_SAVED_TIME,
};
}
export function setPreviousPath(path) {
return {
type: ActionTypes.SET_PREVIOUS_PATH,
path
};
}

View file

@ -1,5 +1,4 @@
import * as ActionTypes from '../../../constants';
import { browserHistory } from 'react-router';
import axios from 'axios';
const ROOT_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:8000/api' : '/api';
@ -26,10 +25,6 @@ export function getProjects(username) {
};
}
export function closeSketchList() {
browserHistory.goBack();
}
export function deleteProject(id) {
return (dispatch) => {
axios.delete(`${ROOT_URL}/projects/${id}`, { withCredentials: true })

View file

@ -1,15 +1,20 @@
import React from 'react';
import React, { PropTypes } from 'react';
import InlineSVG from 'react-inlinesvg';
const exitUrl = require('../../../images/exit.svg');
import { browserHistory } from 'react-router';
class About extends React.Component {
constructor(props) {
super(props);
this.closeAboutModal = this.closeAboutModal.bind(this);
}
componentDidMount() {
this.refs.about.focus();
}
closeAboutModal() {
browserHistory.goBack();
browserHistory.push(this.props.previousPath);
}
render() {
@ -42,4 +47,8 @@ class About extends React.Component {
}
}
About.propTypes = {
previousPath: PropTypes.string.isRequired
};
export default About;

View file

@ -3,7 +3,7 @@ import React, { PropTypes } from 'react';
function LoginForm(props) {
const { fields: { email, password }, handleSubmit, submitting, pristine } = props;
return (
<form className="login-form" onSubmit={handleSubmit(props.validateAndLoginUser.bind(this))}>
<form className="login-form" onSubmit={handleSubmit(props.validateAndLoginUser.bind(this, props.previousPath))}>
<p className="login-form__field">
<input
className="login-form__email-input"
@ -38,7 +38,8 @@ LoginForm.propTypes = {
validateAndLoginUser: PropTypes.func.isRequired,
submitting: PropTypes.bool,
invalid: PropTypes.bool,
pristine: PropTypes.bool
pristine: PropTypes.bool,
previousPath: PropTypes.string.isRequired
};
export default LoginForm;

View file

@ -32,9 +32,10 @@ class LoginView extends React.Component {
}
}
function mapStateToProps(state) {
function mapStateToProps(state, ownProps) {
return {
user: state.user
user: state.user,
previousPath: ownProps.previousPath
};
}

View file

@ -3,7 +3,7 @@ import React, { PropTypes } from 'react';
function SignupForm(props) {
const { fields: { username, email, password, confirmPassword }, handleSubmit, submitting, invalid, pristine } = props;
return (
<form className="signup-form" onSubmit={handleSubmit(props.signUpUser.bind(this))}>
<form className="signup-form" onSubmit={handleSubmit(props.signUpUser.bind(this, props.previousPath))}>
<p className="signup-form__field">
<input
className="signup-form__username-input"
@ -60,7 +60,8 @@ SignupForm.propTypes = {
signUpUser: PropTypes.func.isRequired,
submitting: PropTypes.bool,
invalid: PropTypes.bool,
pristine: PropTypes.bool
pristine: PropTypes.bool,
previousPath: PropTypes.string.isRequired
};
export default SignupForm;

View file

@ -26,9 +26,10 @@ class SignupView extends React.Component {
}
}
function mapStateToProps(state) {
function mapStateToProps(state, ownProps) {
return {
user: state.user
user: state.user,
previousPath: ownProps.previousPath
};
}

View file

@ -2,7 +2,7 @@ import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import moment from 'moment';
import { Link } from 'react-router';
import { Link, browserHistory } from 'react-router';
import * as SketchActions from '../actions/projects';
import * as ProjectActions from '../actions/project';
import InlineSVG from 'react-inlinesvg';
@ -10,17 +10,26 @@ const exitUrl = require('../../../images/exit.svg');
const trashCan = require('../../../images/trash-can.svg');
class SketchList extends React.Component {
constructor(props) {
super(props);
this.closeSketchList = this.closeSketchList.bind(this);
}
componentDidMount() {
this.props.getProjects(this.props.username);
document.getElementById('sketchlist').focus();
}
closeSketchList() {
browserHistory.push(this.props.previousPath);
}
render() {
return (
<section className="sketch-list" aria-label="project list" tabIndex="0" role="main" id="sketchlist">
<header className="sketch-list__header">
<h2>Sketches</h2>
<button className="sketch-list__exit-button" onClick={this.props.closeSketchList}>
<button className="sketch-list__exit-button" onClick={this.closeSketchList}>
<InlineSVG src={exitUrl} alt="Close Sketch List Overlay" />
</button>
</header>
@ -72,9 +81,9 @@ SketchList.propTypes = {
user: PropTypes.object.isRequired,
getProjects: PropTypes.func.isRequired,
sketches: PropTypes.array.isRequired,
closeSketchList: PropTypes.func.isRequired,
username: PropTypes.string,
deleteProject: PropTypes.func.isRequired
deleteProject: PropTypes.func.isRequired,
previousPath: PropTypes.string.isRequired
};
function mapStateToProps(state) {

View file

@ -69,6 +69,12 @@ class IDEView extends React.Component {
document.body.className = this.props.preferences.theme;
}
componentWillReceiveProps(nextProps) {
if (nextProps.location !== this.props.location) {
this.props.setPreviousPath(this.props.location.pathname);
}
}
componentWillUpdate(nextProps) {
if (this.props.ide.consoleIsExpanded !== nextProps.ide.consoleIsExpanded) {
this.consoleSize = nextProps.ide.consoleIsExpanded ? 180 : 29;
@ -366,7 +372,10 @@ class IDEView extends React.Component {
if (this.props.location.pathname.match(/sketches$/)) {
return (
<Overlay>
<SketchList username={this.props.params.username} />
<SketchList
username={this.props.params.username}
previousPath={this.props.ide.previousPath}
/>
</Overlay>
);
}
@ -375,7 +384,7 @@ class IDEView extends React.Component {
if (this.props.location.pathname === '/about') {
return (
<Overlay>
<About />
<About previousPath={this.props.ide.previousPath} />
</Overlay>
);
}
@ -407,7 +416,7 @@ class IDEView extends React.Component {
if (this.props.location.pathname === '/login') {
return (
<Overlay>
<LoginView />
<LoginView previousPath={this.props.ide.previousPath} />
</Overlay>
);
}
@ -416,7 +425,7 @@ class IDEView extends React.Component {
if (this.props.location.pathname === '/signup') {
return (
<Overlay>
<SignupView />
<SignupView previousPath={this.props.ide.previousPath} />
</Overlay>
);
}
@ -434,7 +443,9 @@ class IDEView extends React.Component {
if (this.props.location.pathname.match(/\/reset-password\/[a-fA-F0-9]+/)) {
return (
<Overlay>
<NewPasswordView token={this.props.params.reset_password_token} />
<NewPasswordView
token={this.props.params.reset_password_token}
/>
</Overlay>
);
}
@ -479,7 +490,8 @@ IDEView.propTypes = {
infiniteLoop: PropTypes.bool.isRequired,
previewIsRefreshing: PropTypes.bool.isRequired,
infiniteLoopMessage: PropTypes.string.isRequired,
projectSavedTime: PropTypes.string.isRequired
projectSavedTime: PropTypes.string.isRequired,
previousPath: PropTypes.string.isRequired
}).isRequired,
startSketch: PropTypes.func.isRequired,
stopSketch: PropTypes.func.isRequired,
@ -578,7 +590,8 @@ IDEView.propTypes = {
startSketchAndRefresh: PropTypes.func.isRequired,
endSketchRefresh: PropTypes.func.isRequired,
startRefreshSketch: PropTypes.func.isRequired,
setBlobUrl: PropTypes.func.isRequired
setBlobUrl: PropTypes.func.isRequired,
setPreviousPath: PropTypes.func.isRequired
};
function mapStateToProps(state) {

View file

@ -18,7 +18,8 @@ const initialState = {
previewIsRefreshing: false,
infiniteLoopMessage: '',
projectJustOpened: false,
projectSavedTime: ''
projectSavedTime: '',
previousPath: '/'
};
const ide = (state = initialState, action) => {
@ -89,6 +90,8 @@ const ide = (state = initialState, action) => {
return Object.assign({}, state, { projectSavedTime: action.value });
case ActionTypes.RESET_PROJECT_SAVED_TIME:
return Object.assign({}, state, { projectSavedTime: '' });
case ActionTypes.SET_PREVIOUS_PATH:
return Object.assign({}, state, { previousPath: action.path });
default:
return state;
}

View file

@ -12,14 +12,14 @@ export function authError(error) {
};
}
export function signUpUser(formValues) {
export function signUpUser(previousPath, formValues) {
return (dispatch) => {
axios.post(`${ROOT_URL}/signup`, formValues, { withCredentials: true })
.then(response => {
dispatch({ type: ActionTypes.AUTH_USER,
user: response.data
});
browserHistory.push('/');
browserHistory.push(previousPath);
})
.catch(response => dispatch(authError(response.data.error)));
};
@ -43,7 +43,7 @@ export function loginUserFailure(error) {
};
}
export function validateAndLoginUser(formProps, dispatch) {
export function validateAndLoginUser(previousPath, formProps, dispatch) {
return new Promise((resolve, reject) => {
loginUser(formProps)
.then(response => {
@ -54,7 +54,7 @@ export function validateAndLoginUser(formProps, dispatch) {
type: ActionTypes.SET_PREFERENCES,
preferences: response.data.preferences
});
browserHistory.push('/');
browserHistory.push(previousPath);
resolve();
})
.catch(response => {