diff --git a/src/components/PageLayout/PageLayout.js b/src/components/PageLayout/PageLayout.js
index b7adc73d..feb13a11 100644
--- a/src/components/PageLayout/PageLayout.js
+++ b/src/components/PageLayout/PageLayout.js
@@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import Helmet from 'react-helmet';
import { withRouter } from 'react-router-dom';
+import { FormattedMessage } from 'react-intl';
import { Topbar } from '../../containers';
const scrollToTop = () => {
@@ -21,12 +22,32 @@ class PageLayout extends Component {
}
render() {
- const { className, title, children, authError } = this.props;
- // TODO: use FlashMessages for authError
+ const { className, title, children, authInfoError, logoutError } = this.props;
+
+ // TODO: use FlashMessages for auth errors
+
+ /* eslint-disable no-console */
+ if (authInfoError && console && console.error) {
+ console.error(authInfoError);
+ }
+ if (logoutError && console && console.error) {
+ console.error(logoutError);
+ }
+ /* eslint-enable no-console */
+
return (
- {authError ?
Error in auth: {authError.message}
: null}
+ {authInfoError
+ ?
+
+
+ : null}
+ {logoutError
+ ?
+
+
+ : null}
{title}
{children}
@@ -37,17 +58,21 @@ class PageLayout extends Component {
const { any, string, instanceOf, func } = PropTypes;
-PageLayout.defaultProps = { className: '', children: null, authError: null };
+PageLayout.defaultProps = { className: '', children: null, authInfoError: null, logoutError: null };
PageLayout.propTypes = {
className: string,
title: string.isRequired,
children: any,
- authError: instanceOf(Error),
+ authInfoError: instanceOf(Error),
+ logoutError: instanceOf(Error),
// history.listen function from withRouter
listen: func.isRequired,
};
-const mapStateToProps = state => ({ authError: state.Auth.error });
+const mapStateToProps = state => ({
+ authInfoError: state.Auth.authInfoError,
+ logoutError: state.Auth.logoutError,
+});
export default connect(mapStateToProps)(withRouter(PageLayout));
diff --git a/src/containers/AuthenticationPage/AuthenticationPage.js b/src/containers/AuthenticationPage/AuthenticationPage.js
index 356d7f35..8c836f8f 100644
--- a/src/containers/AuthenticationPage/AuthenticationPage.js
+++ b/src/containers/AuthenticationPage/AuthenticationPage.js
@@ -1,23 +1,44 @@
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
+import { FormattedMessage } from 'react-intl';
import { PageLayout, NamedLink, NamedRedirect } from '../../components';
import { LoginForm, SignUpForm } from '../../containers';
import { login } from '../../ducks/Auth.duck';
export const AuthenticationPageComponent = props => {
- const { location, tab, isAuthenticated, onLoginSubmit, onSignUpSubmit } = props;
+ const {
+ location,
+ tab,
+ isAuthenticated,
+ loginError,
+ onLoginSubmit,
+ onSignUpSubmit,
+ } = props;
const isLogin = tab === 'login';
const from = location.state && location.state.from ? location.state.from : null;
const authRedirect = from ?
:
;
+ // TODO: use FlashMessages for auth errors
+
+ /* eslint-disable no-console */
+ if (loginError && console && console.error) {
+ console.error(loginError);
+ }
+ /* eslint-enable no-console */
+
return (
{isAuthenticated ? authRedirect : null}
+ {loginError
+ ?
+
+
+ : null}
{from
?
- You must log in to view the page at
+
{from}
: null}
@@ -29,19 +50,28 @@ export const AuthenticationPageComponent = props => {
);
};
-AuthenticationPageComponent.defaultProps = { tab: 'signup' };
+AuthenticationPageComponent.defaultProps = {
+ tab: 'signup',
+ authInfoError: null,
+ loginError: null,
+ logoutError: null,
+};
-const { object, oneOf, shape, bool, func } = PropTypes;
+const { object, oneOf, shape, bool, func, instanceOf } = PropTypes;
AuthenticationPageComponent.propTypes = {
location: shape({ state: object }).isRequired,
tab: oneOf(['login', 'signup']),
isAuthenticated: bool.isRequired,
+ loginError: instanceOf(Error),
onLoginSubmit: func.isRequired,
onSignUpSubmit: func.isRequired,
};
-const mapStateToProps = state => ({ isAuthenticated: state.Auth.isAuthenticated });
+const mapStateToProps = state => ({
+ isAuthenticated: state.Auth.isAuthenticated,
+ loginError: state.Auth.loginError,
+});
const mapDispatchToProps = dispatch => ({
onLoginSubmit: ({ email, password }) => dispatch(login(email, password)),
diff --git a/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap b/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap
index 1b2ad3b3..4b349936 100644
--- a/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap
+++ b/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap
@@ -2,7 +2,9 @@ exports[`AuthenticationPageComponent matches snapshot 1`] = `
- You must log in to view the page at
+
/protected
diff --git a/src/translations/en.json b/src/translations/en.json
index 858a8517..c055e900 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -1,8 +1,11 @@
{
- "landingpage.examplelink": "Show nice studios! (from json)",
+ "AuthenticationPage.loginFailed": "The email and password you entered did not match our records. Please double-check and try again.",
+ "AuthenticationPage.loginRequiredFor": "You must log in to view the page at",
"HeroSearchForm.placeholder": "Location search (soon)",
"HeroSearchForm.search": "Search",
- "HeroSection.title": "Book Studiotime anywhere",
"HeroSection.subTitle": "The largest online community to rent music studios",
- "ListingPage.loadingListingData": "Loading listing data"
+ "HeroSection.title": "Book Studiotime anywhere",
+ "ListingPage.loadingListingData": "Loading listing data",
+ "PageLayout.authInfoFailed": "Could not get authentication information.",
+ "PageLayout.logoutFailed": "Logout failed. Please try again."
}