Debugging finished
This commit is contained in:
Generated
+29
-11
@@ -3857,9 +3857,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint": {
|
"eslint": {
|
||||||
"version": "5.1.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.3.0.tgz",
|
||||||
"integrity": "sha512-DyH6JsoA1KzA5+OSWFjg56DFJT+sDLO0yokaPZ9qY0UEmYrPA1gEX/G1MnVkmRDsksG4H1foIVz2ZXXM3hHYvw==",
|
"integrity": "sha512-N/tCqlMKkyNvAvLu+zI9AqDasnSLt00K+Hu8kdsERliC9jYEc8ck12XtjvOXrBKu8fK6RrBcN9bat6Xk++9jAg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ajv": "^6.5.0",
|
"ajv": "^6.5.0",
|
||||||
@@ -3878,7 +3878,7 @@
|
|||||||
"functional-red-black-tree": "^1.0.1",
|
"functional-red-black-tree": "^1.0.1",
|
||||||
"glob": "^7.1.2",
|
"glob": "^7.1.2",
|
||||||
"globals": "^11.7.0",
|
"globals": "^11.7.0",
|
||||||
"ignore": "^3.3.3",
|
"ignore": "^4.0.2",
|
||||||
"imurmurhash": "^0.1.4",
|
"imurmurhash": "^0.1.4",
|
||||||
"inquirer": "^5.2.0",
|
"inquirer": "^5.2.0",
|
||||||
"is-resolvable": "^1.1.0",
|
"is-resolvable": "^1.1.0",
|
||||||
@@ -3893,7 +3893,7 @@
|
|||||||
"path-is-inside": "^1.0.2",
|
"path-is-inside": "^1.0.2",
|
||||||
"pluralize": "^7.0.0",
|
"pluralize": "^7.0.0",
|
||||||
"progress": "^2.0.0",
|
"progress": "^2.0.0",
|
||||||
"regexpp": "^1.1.0",
|
"regexpp": "^2.0.0",
|
||||||
"require-uncached": "^1.0.3",
|
"require-uncached": "^1.0.3",
|
||||||
"semver": "^5.5.0",
|
"semver": "^5.5.0",
|
||||||
"string.prototype.matchall": "^2.0.0",
|
"string.prototype.matchall": "^2.0.0",
|
||||||
@@ -3982,6 +3982,12 @@
|
|||||||
"integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==",
|
"integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ignore": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-Z/vAH2GGIEATQnBVXMclE2IGV6i0GyVngKThcGZ5kHgHMxLo9Ow2+XHRq1aEKEej5vOF1TPJNbvX6J/anT0M7A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"inquirer": {
|
"inquirer": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz",
|
||||||
@@ -4019,6 +4025,12 @@
|
|||||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"regexpp": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||||
@@ -11661,9 +11673,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react": {
|
"react": {
|
||||||
"version": "16.4.1",
|
"version": "16.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-16.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-16.4.2.tgz",
|
||||||
"integrity": "sha512-3GEs0giKp6E0Oh/Y9ZC60CmYgUPnp7voH9fbjWsvXtYFb4EWtgQub0ADSq0sJR0BbHc4FThLLtzlcFaFXIorwg==",
|
"integrity": "sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"fbjs": "^0.8.16",
|
"fbjs": "^0.8.16",
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
@@ -11746,9 +11758,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-dom": {
|
"react-dom": {
|
||||||
"version": "16.4.1",
|
"version": "16.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.4.2.tgz",
|
||||||
"integrity": "sha512-1Gin+wghF/7gl4Cqcvr1DxFX2Osz7ugxSwl6gBqCMpdrxHjIFUS7GYxrFftZ9Ln44FHw0JxCFD9YtZsrbR5/4A==",
|
"integrity": "sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"fbjs": "^0.8.16",
|
"fbjs": "^0.8.16",
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
@@ -12252,6 +12264,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"redux-devtools-extension": {
|
||||||
|
"version": "2.13.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.5.tgz",
|
||||||
|
"integrity": "sha512-QQ9BRy77oURHMdGys9rfQcCQDzXZ1T4oW+eUyE5Cg7DNVau69HJzc4YNDMOmpi0Dzpi1zOQgQ2rUpgJta4Lfqg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"redux-logger": {
|
"redux-logger": {
|
||||||
"version": "3.0.6",
|
"version": "3.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"babel-core": "^6.26.3",
|
"babel-core": "^6.26.3",
|
||||||
"babel-eslint": "^8.2.5",
|
"babel-eslint": "^8.2.5",
|
||||||
"babel-runtime": "^6.26.0",
|
"babel-runtime": "^6.26.0",
|
||||||
"eslint": "^5.0.1",
|
"eslint": "^5.3.0",
|
||||||
"eslint-config-recommended": "^3.0.0",
|
"eslint-config-recommended": "^3.0.0",
|
||||||
"eslint-plugin-babel": "^5.1.0",
|
"eslint-plugin-babel": "^5.1.0",
|
||||||
"eslint-plugin-flowtype": "^2.49.3",
|
"eslint-plugin-flowtype": "^2.49.3",
|
||||||
@@ -18,13 +18,14 @@
|
|||||||
"react-app-rewire-eslint": "^0.2.3",
|
"react-app-rewire-eslint": "^0.2.3",
|
||||||
"react-app-rewired": "^1.5.2",
|
"react-app-rewired": "^1.5.2",
|
||||||
"react-devtools": "^3.2.3",
|
"react-devtools": "^3.2.3",
|
||||||
"react-scripts": "1.1.4"
|
"react-scripts": "1.1.4",
|
||||||
|
"redux-devtools-extension": "^2.13.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"connected-react-router": "^4.3.0",
|
"connected-react-router": "^4.3.0",
|
||||||
"react": "^16.4.1",
|
"react": "^16.4.2",
|
||||||
"react-dom": "^16.4.1",
|
"react-dom": "^16.4.2",
|
||||||
"react-loadable": "^5.4.0",
|
"react-loadable": "^5.4.0",
|
||||||
"react-redux": "^5.0.7",
|
"react-redux": "^5.0.7",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^4.3.1",
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/* noflow */
|
||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import { BrowserRouter, Switch, Route, Link } from "react-router-dom";
|
||||||
|
import { ConnectedRouter } from "connected-react-router";
|
||||||
|
|
||||||
|
import {
|
||||||
|
ConnectedLogin,
|
||||||
|
ConnectedProtectedRoutes,
|
||||||
|
AuthRoute
|
||||||
|
} from "./routingApp";
|
||||||
|
import { history, store } from "./routingApp/store";
|
||||||
|
|
||||||
|
const Home = () => <h1>Home Sweet Home</h1>;
|
||||||
|
const Help = () => <h1>Help! SOS!</h1>;
|
||||||
|
const Alpha = () => <h1>Alpha</h1>;
|
||||||
|
const Bravo = () => <h1>Bravo</h1>;
|
||||||
|
const Charlie = () => <h1>Charlie</h1>;
|
||||||
|
const Zulu = () => <h1>Zulu</h1>;
|
||||||
|
const Error404 = () => <h1>404 Error!</h1>;
|
||||||
|
|
||||||
|
class App extends Component<{}> {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Provider store={store}>
|
||||||
|
<BrowserRouter>
|
||||||
|
<ConnectedRouter history={history}>
|
||||||
|
<div>
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<Link to="/">Home</Link>
|
||||||
|
<Link to="/login">Log in</Link>
|
||||||
|
<Link to="/about/routing">
|
||||||
|
About Routing
|
||||||
|
</Link>
|
||||||
|
<Link to="/alpha">Alpha...</Link>
|
||||||
|
<Link to="/bravo">Bravo...</Link>
|
||||||
|
<Link to="/charlie">
|
||||||
|
Charlie...
|
||||||
|
</Link>
|
||||||
|
<Link to="/wrong">
|
||||||
|
...Wrong...
|
||||||
|
</Link>
|
||||||
|
<Link to="/zulu">Zulu</Link>
|
||||||
|
<Link to="/help">Help</Link>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<Switch>
|
||||||
|
<Route exact path="/" component={Home} />
|
||||||
|
<Route path="/help" component={Help} />
|
||||||
|
<Route
|
||||||
|
path="/about/:something"
|
||||||
|
render={props => (
|
||||||
|
<div>
|
||||||
|
<h1>About...</h1>
|
||||||
|
{props.match.params.something}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/login"
|
||||||
|
component={ConnectedLogin}
|
||||||
|
/>
|
||||||
|
<AuthRoute
|
||||||
|
path="/alpha"
|
||||||
|
component={Alpha}
|
||||||
|
/>
|
||||||
|
<AuthRoute
|
||||||
|
path="/bravo"
|
||||||
|
component={Bravo}
|
||||||
|
/>
|
||||||
|
<AuthRoute
|
||||||
|
path="/charlie"
|
||||||
|
component={Charlie}
|
||||||
|
/>
|
||||||
|
<AuthRoute path="/zulu" component={Zulu} />
|
||||||
|
<AuthRoute component={Error404} />
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
</ConnectedRouter>
|
||||||
|
</BrowserRouter>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
@@ -2,9 +2,26 @@
|
|||||||
|
|
||||||
import { createStore, applyMiddleware } from "redux";
|
import { createStore, applyMiddleware } from "redux";
|
||||||
import { createLogger } from "redux-logger";
|
import { createLogger } from "redux-logger";
|
||||||
|
import { composeWithDevTools } from "redux-devtools-extension";
|
||||||
|
|
||||||
import { reducer } from "./counter.reducer.js";
|
import { reducer } from "./counter.reducer.js";
|
||||||
|
|
||||||
const logger = createLogger({ diff: true, duration: true });
|
const logger = createLogger({
|
||||||
|
diff: true,
|
||||||
|
duration: true
|
||||||
|
});
|
||||||
|
|
||||||
export const store = createStore(reducer, applyMiddleware(logger));
|
// The following uses only redux-logger
|
||||||
|
/*
|
||||||
|
export const store =
|
||||||
|
process.env.NODE_ENV === "development"
|
||||||
|
? createStore(reducer, applyMiddleware(logger))
|
||||||
|
: createStore(reducer);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// The following uses redux-devtools-extension in addition to redux-logger
|
||||||
|
|
||||||
|
export const store = createStore(
|
||||||
|
reducer,
|
||||||
|
composeWithDevTools(applyMiddleware(logger))
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
|
|
||||||
import App from "./App.regions";
|
import App from "./App.routing.auth";
|
||||||
import registerServiceWorker from "./registerServiceWorker";
|
import registerServiceWorker from "./registerServiceWorker";
|
||||||
|
|
||||||
ReactDOM.render(<App />, document.getElementById("root"));
|
ReactDOM.render(<App />, document.getElementById("root"));
|
||||||
|
|||||||
@@ -3,9 +3,20 @@
|
|||||||
import { createStore, applyMiddleware } from "redux";
|
import { createStore, applyMiddleware } from "redux";
|
||||||
import thunk from "redux-thunk";
|
import thunk from "redux-thunk";
|
||||||
import { createLogger } from "redux-logger";
|
import { createLogger } from "redux-logger";
|
||||||
|
import { composeWithDevTools } from "redux-devtools-extension";
|
||||||
|
|
||||||
import { reducer } from "./worlds.reducer.js";
|
import { reducer } from "./worlds.reducer.js";
|
||||||
|
|
||||||
const logger = createLogger({ duration: true });
|
const logger = createLogger({ duration: true });
|
||||||
|
|
||||||
|
// The following uses redux-logger, only.
|
||||||
|
/*
|
||||||
export const store = createStore(reducer, applyMiddleware(thunk, logger));
|
export const store = createStore(reducer, applyMiddleware(thunk, logger));
|
||||||
|
*/
|
||||||
|
|
||||||
|
// The following uses redux-devtools-extension in addition to redux-logger
|
||||||
|
|
||||||
|
export const store = createStore(
|
||||||
|
reducer,
|
||||||
|
composeWithDevTools(applyMiddleware(thunk, logger))
|
||||||
|
);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { Route, Redirect } from "react-router-dom";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
export class Auth extends React.Component<{
|
||||||
|
loginRoute: string,
|
||||||
|
token: string,
|
||||||
|
location: object
|
||||||
|
}> {
|
||||||
|
static propTypes = {
|
||||||
|
loginRoute: PropTypes.string.isRequired,
|
||||||
|
token: PropTypes.string.isRequired,
|
||||||
|
location: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const myProps = { ...this.props };
|
||||||
|
if (!myProps.token) {
|
||||||
|
delete myProps.component;
|
||||||
|
myProps.render = () => (
|
||||||
|
<Redirect
|
||||||
|
to={{
|
||||||
|
pathname: this.props.loginRoute,
|
||||||
|
state: { from: this.props.location }
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <Route {...myProps} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
|
import { Auth } from "./authRoute.component";
|
||||||
|
export const AuthRoute = connect(state => ({
|
||||||
|
token: state.token,
|
||||||
|
loginRoute: "/login"
|
||||||
|
}))(Auth);
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import { ConnectedLogin } from "./login.connected.js";
|
||||||
|
import { ConnectedProtectedRoutes } from "./protectedRoutes.connected.js";
|
||||||
|
import { AuthRoute } from "./authRoute.connected.js";
|
||||||
|
|
||||||
|
export { ConnectedLogin, ConnectedProtectedRoutes, AuthRoute };
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import { loginService } from "./serviceApi";
|
||||||
|
|
||||||
|
export const LOGIN_REQUEST = "login:request";
|
||||||
|
export const LOGIN_SUCCESS = "login:success";
|
||||||
|
export const LOGIN_FAILURE = "login:failure";
|
||||||
|
|
||||||
|
export const loginRequest = () => ({
|
||||||
|
type: LOGIN_REQUEST
|
||||||
|
});
|
||||||
|
|
||||||
|
export const loginSuccess = (token: string) => ({
|
||||||
|
type: LOGIN_SUCCESS,
|
||||||
|
token
|
||||||
|
});
|
||||||
|
|
||||||
|
export const loginFailure = () => ({
|
||||||
|
type: LOGIN_FAILURE
|
||||||
|
});
|
||||||
|
|
||||||
|
// Complex actions:
|
||||||
|
|
||||||
|
export const attemptLogin = (
|
||||||
|
user: string,
|
||||||
|
password: string
|
||||||
|
) => async dispatch => {
|
||||||
|
try {
|
||||||
|
dispatch(loginRequest());
|
||||||
|
// the next line delays execution for 5 seconds:
|
||||||
|
// await new Promise(resolve => setTimeout(resolve, 5000));
|
||||||
|
const result = await loginService(user, password);
|
||||||
|
dispatch(loginSuccess(result.data));
|
||||||
|
} catch (e) {
|
||||||
|
dispatch(loginFailure());
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import { Redirect } from "react-router-dom";
|
||||||
|
|
||||||
|
export class Login extends React.PureComponent<{
|
||||||
|
onLogin: func,
|
||||||
|
logging: boolean,
|
||||||
|
token: string,
|
||||||
|
location: object
|
||||||
|
}> {
|
||||||
|
static propTypes = {
|
||||||
|
onLogin: PropTypes.func.isRequired,
|
||||||
|
logging: PropTypes.bool.isRequired,
|
||||||
|
token: PropTypes.string.isRequired,
|
||||||
|
location: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
state = {
|
||||||
|
userName: "",
|
||||||
|
password: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
onUserNameBlur = e => this.setState({ userName: e.target.value });
|
||||||
|
|
||||||
|
onPasswordBlur = e => this.setState({ password: e.target.value });
|
||||||
|
|
||||||
|
onLoginClick = () =>
|
||||||
|
this.props.onLogin(this.state.userName, this.state.password);
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (
|
||||||
|
this.state.userName &&
|
||||||
|
this.state.password &&
|
||||||
|
this.props.token
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<Redirect to={this.props.location.state.from.pathname} />
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Login Form</h1>
|
||||||
|
<div>
|
||||||
|
User:<input
|
||||||
|
type="text"
|
||||||
|
onBlur={this.onUserNameBlur}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Password:
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
onBlur={this.onPasswordBlur}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={this.onLoginClick}
|
||||||
|
disabled={this.props.logging}
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
|
import { Login } from "./login.component";
|
||||||
|
import { attemptLogin } from "./login.actions";
|
||||||
|
|
||||||
|
export const ConnectedLogin = connect(
|
||||||
|
state => ({
|
||||||
|
logging: state.logging,
|
||||||
|
token: state.token
|
||||||
|
}),
|
||||||
|
dispatch => ({
|
||||||
|
onLogin: (user: string, password: string) =>
|
||||||
|
dispatch(attemptLogin(user, password))
|
||||||
|
})
|
||||||
|
)(Login);
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import {
|
||||||
|
LOGIN_REQUEST,
|
||||||
|
LOGIN_SUCCESS,
|
||||||
|
LOGIN_FAILURE
|
||||||
|
} from "./login.actions";
|
||||||
|
|
||||||
|
export const reducer = (
|
||||||
|
state: object = {
|
||||||
|
// initial state
|
||||||
|
logging: false,
|
||||||
|
token: ""
|
||||||
|
},
|
||||||
|
action
|
||||||
|
) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case LOGIN_REQUEST:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
logging: true,
|
||||||
|
token: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
case LOGIN_SUCCESS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
logging: false,
|
||||||
|
token: action.token
|
||||||
|
};
|
||||||
|
|
||||||
|
case LOGIN_FAILURE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
logging: false
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { Redirect, Switch } from "react-router-dom";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
export class ProtectedRoutes extends React.Component<{
|
||||||
|
token: string,
|
||||||
|
children: any,
|
||||||
|
location: object
|
||||||
|
}> {
|
||||||
|
static propTypes = {
|
||||||
|
token: PropTypes.string.isRequired,
|
||||||
|
children: PropTypes.any,
|
||||||
|
location: PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return this.props.token ? (
|
||||||
|
<Switch>{this.props.children}</Switch>
|
||||||
|
) : (
|
||||||
|
<Redirect
|
||||||
|
to={{
|
||||||
|
pathname: "/login",
|
||||||
|
state: { from: this.props.location }
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
|
import { ProtectedRoutes } from "./protectedRoutes.component";
|
||||||
|
|
||||||
|
export const ConnectedProtectedRoutes = connect(state => ({
|
||||||
|
token: state.token
|
||||||
|
}))(ProtectedRoutes);
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export const loginService = (user, password) =>
|
||||||
|
axios.post(
|
||||||
|
`http://localhost:8443/gettoken`,
|
||||||
|
`user=${user}&password=${password}`
|
||||||
|
);
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import { createStore, applyMiddleware } from "redux";
|
||||||
|
import thunk from "redux-thunk";
|
||||||
|
import { createLogger } from "redux-logger";
|
||||||
|
import { composeWithDevTools } from "redux-devtools-extension";
|
||||||
|
import { connectRouter, routerMiddleware } from "connected-react-router";
|
||||||
|
import { createBrowserHistory } from "history";
|
||||||
|
|
||||||
|
import { reducer } from "./login.reducer";
|
||||||
|
|
||||||
|
const logger = createLogger({ duration: true });
|
||||||
|
|
||||||
|
export const history = createBrowserHistory();
|
||||||
|
|
||||||
|
export const store = createStore(
|
||||||
|
connectRouter(history)(reducer),
|
||||||
|
composeWithDevTools(
|
||||||
|
applyMiddleware(routerMiddleware(history), thunk, logger)
|
||||||
|
)
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user