AuthenticationPage and fake authentication setup

This commit is contained in:
Vesa Luusua 2017-01-12 18:56:01 +02:00
parent 66b1887c82
commit a8ad16f089
4 changed files with 137 additions and 20 deletions

View file

@ -1,6 +1,7 @@
import React from 'react';
import { Match, Miss, Redirect } from 'react-router';
import {
AuthenticationPage,
CheckoutPage,
LandingPage,
ListingPage,
@ -13,25 +14,84 @@ import {
// client and when rendering in the server.
const RedirectLandingPage = () => <Redirect to="/" />;
const Routes = () => (
<div>
<Match exactly pattern="/" component={ LandingPage } />
// Fake authentication module
// An example from react-router v4 repository
export const fakeAuth = {
isAuthenticated: false,
authenticate(cb) {
this.isAuthenticated = true;
setTimeout(cb, 100); // fake async
},
signout(cb) {
this.isAuthenticated = false;
cb();
setTimeout(cb, 100); // weird bug if async?
}
};
{/* Search view */}
<Match exactly pattern="/s" component={ SearchPage } />
{/* Listing view */}
<Match exactly pattern="/l/:slug" component={ ListingPage } />
<Match exactly pattern="/l" component={ RedirectLandingPage } />
{/* profile / storefront view */}
<Match exactly pattern="/u/:displayName" component={ ProfilePage } />
<Match exactly pattern="/u" component={ RedirectLandingPage } />
{/* checkout */}
<Match exactly pattern="/checkout/:listingId" component={ CheckoutPage } />
<Miss component={ NotFoundPage } />
</div>
// User must be authenticated before he can see certain pages
export const MatchWhenAuthorized = ({ component: Component, ...rest }) => (
<Match {...rest} render={
(props) => (
fakeAuth.isAuthenticated ?
( <Component { ...props } /> ) :
( <Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)
}/>
);
class Routes extends React.Component {
getChildContext() {
return { router: this.props.router };
}
render() {
return (
<div>
<Match exactly pattern="/" component={ LandingPage } />
{/* Search view */}
<Match exactly pattern="/s" component={ SearchPage } />
{/* Listing view */}
<Match exactly pattern="/l/:slug" component={ ListingPage } />
<Match exactly pattern="/l" component={ RedirectLandingPage } />
{/* profile / storefront view */}
<Match exactly pattern="/u/:displayName" component={ ProfilePage } />
<Match exactly pattern="/u" component={ RedirectLandingPage } />
{/* checkout */}
<Match exactly pattern="/checkout/:listingId" component={ CheckoutPage } />
{/* Login and signup */}
<Match
exactly
pattern="/login"
component={
(props) => <AuthenticationPage { ...props } tab='login' />
} />
<Match
exactly
pattern="/signup"
component={
(props) => <AuthenticationPage { ...props } tab='signup' />
} />
<Miss component={ NotFoundPage } />
</div>
);
}
}
Routes.childContextTypes = {
router: React.PropTypes.object
};
export default Routes;

View file

@ -4,9 +4,11 @@ import Helmet from 'react-helmet';
import { BrowserRouter, ServerRouter } from 'react-router';
import Routes from './Routes';
const RoutesWithRouterProp = ({ router }) => <Routes router={router} />
export const ClientApp = () => (
<BrowserRouter>
<Routes />
{ RoutesWithRouterProp }
</BrowserRouter>
);
@ -14,7 +16,7 @@ export const ServerApp = (props) => {
const { url, context } = props;
return (
<ServerRouter location={ url } context={ context } >
<Routes />
{ RoutesWithRouterProp }
</ServerRouter>
);
};

View file

@ -0,0 +1,53 @@
import React, { Component } from 'react';
import { Link, Redirect } from 'react-router';
import { Page } from '../../components';
import { fakeAuth } from '../../Routes';
class AuthenticationPage extends Component {
constructor(props) {
super(props);
this.state = {
redirectToReferrer: false,
};
this.login = this.login.bind(this);
}
login() {
fakeAuth.authenticate(() => {
this.setState({ redirectToReferrer: true });
})
}
render() {
const { from } = this.props.location.state || '/';
const { redirectToReferrer } = this.state;
const toLogin = <Link to={{ pathname: '/login', state: { from: from || '/' }}}>Log in</Link>;
const toSignup = <Link to={{ pathname: '/signup', state: { from: from || '/' }}}>Sign up</Link>;
const alternativeMethod = this.props.tab === 'login' ? toSignup : toLogin;
const currentMethod = this.props.tab === 'login' ? 'Log in' : 'Sign up';
const fromLoginMsg = from ?
( <p>
You must log in to view the page at
<code>{from.pathname}</code>
</p> ) :
null
return (
<Page title={ `Authentication page: ${this.props.tab} tab` }>
{ redirectToReferrer ?
( <Redirect to={from || '/'}/> ):
null
}
{ fromLoginMsg }
<button onClick={this.login}>{ currentMethod }</button>
<p>or { alternativeMethod }</p>
</Page>
)
}
}
export default AuthenticationPage;

View file

@ -1,3 +1,4 @@
import AuthenticationPage from './AuthenticationPage/AuthenticationPage';
import CheckoutPage from './CheckoutPage/CheckoutPage';
import LandingPage from './LandingPage/LandingPage';
import ListingPage from './ListingPage/ListingPage';
@ -6,6 +7,7 @@ import SearchPage from './SearchPage/SearchPage';
import NotFoundPage from './NotFoundPage/NotFoundPage';
export {
AuthenticationPage,
CheckoutPage,
LandingPage,
ListingPage,