Created
May 15, 2015 04:50
-
-
Save wolfeidau/24e8f89a78920aa19c5d to your computer and use it in GitHub Desktop.
Simple auth JSX.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var React = require('react'); | |
var Router = require('react-router'); | |
var { DefaultRoute, Route, RouteHandler, Link } = Router; | |
require('purecss'); | |
require('./app.css'); | |
class App extends React.Component { | |
render () { | |
return ( | |
<div className="wrap"> | |
<Navigator/> | |
</div> | |
); | |
} | |
} | |
class Navigator extends React.Component { | |
constructor (props) { | |
super(props); | |
this.state = { | |
loggedIn: auth.loggedIn() | |
}; | |
} | |
setStateOnAuth (loggedIn) { | |
this.setState({ | |
loggedIn: loggedIn | |
}); | |
} | |
componentWillMount () { | |
auth.onChange = this.setStateOnAuth.bind(this); | |
auth.login(); | |
} | |
render () { | |
return ( | |
<div className="header"> | |
<div className="home-menu pure-menu pure-menu-horizontal pure-menu-fixed"> | |
<Link className="pure-menu-heading" to="/">Assembly</Link> | |
<ul className="pure-menu-list"> | |
<li className="pure-menu-item pure-menu-selected"><Link className="pure-menu-link" to="/">Home</Link></li> | |
<li className="pure-menu-item"><Link className="pure-menu-link" to="about">About</Link></li> | |
<li className="pure-menu-item"> | |
{this.state.loggedIn ? ( | |
<Link className="pure-menu-link" to="logout">Sign out</Link> | |
) : ( | |
<Link className="pure-menu-link" to="login">Sign in</Link> | |
)} | |
</li> | |
</ul> | |
<RouteHandler/> | |
</div> | |
</div> | |
); | |
} | |
} | |
var requireAuth = (Component) => { | |
return class Authenticated extends React.Component { | |
static willTransitionTo(transition) { | |
if (!auth.loggedIn()) { | |
transition.redirect('/login', {}, {'nextPath' : transition.path}); | |
} | |
} | |
render () { | |
return <Component {...this.props}/> | |
} | |
} | |
}; | |
var DashboardView = requireAuth(class extends React.Component { | |
render () { | |
var token = auth.getToken(); | |
return ( | |
<div> | |
<h1>Dashboard</h1> | |
<p>You made it!</p> | |
<p>{token}</p> | |
</div> | |
); | |
} | |
}); | |
class LoginView extends React.Component { | |
constructor (props) { | |
super(props); | |
this.handleSubmit = this.handleSubmit.bind(this); | |
this.state = { | |
error: false | |
}; | |
} | |
handleSubmit (event) { | |
event.preventDefault(); | |
var { router } = this.context; | |
var nextPath = router.getCurrentQuery().nextPath; | |
var email = this.refs.email.getDOMNode().value; | |
var pass = this.refs.pass.getDOMNode().value; | |
auth.login(email, pass, (loggedIn) => { | |
if (!loggedIn) | |
return this.setState({ error: true }); | |
if (nextPath) { | |
router.replaceWith(nextPath); | |
} else { | |
router.replaceWith('/about'); | |
} | |
}); | |
} | |
render () { | |
return ( | |
<form onSubmit={this.handleSubmit}> | |
<label><input ref="email" placeholder="email" defaultValue="joe@example.com"/></label> | |
<label><input ref="pass" placeholder="password"/></label> (hint: password1)<br/> | |
<button type="submit">login</button> | |
{this.state.error && ( | |
<p>Bad login information</p> | |
)} | |
</form> | |
); | |
} | |
} | |
LoginView.contextTypes = { | |
router: React.PropTypes.func | |
}; | |
class DefaultView extends React.Component { | |
render () { | |
return <h1>Home</h1>; | |
} | |
} | |
class AboutView extends React.Component { | |
render () { | |
return <h1>About</h1>; | |
} | |
} | |
class LogoutView extends React.Component { | |
componentDidMount () { | |
auth.logout(); | |
} | |
render () { | |
return <p>You are now logged out</p>; | |
} | |
} | |
// Fake authentication lib | |
var auth = { | |
login (email, pass, cb) { | |
cb = arguments[arguments.length - 1]; | |
if (localStorage.token) { | |
if (cb) cb(true); | |
this.onChange(true); | |
return; | |
} | |
pretendRequest(email, pass, (res) => { | |
if (res.authenticated) { | |
localStorage.token = res.token; | |
if (cb) cb(true); | |
this.onChange(true); | |
} else { | |
if (cb) cb(false); | |
this.onChange(false); | |
} | |
}); | |
}, | |
getToken: function () { | |
return localStorage.token; | |
}, | |
logout: function (cb) { | |
delete localStorage.token; | |
if (cb) cb(); | |
this.onChange(false); | |
}, | |
loggedIn: function () { | |
return !!localStorage.token; | |
}, | |
onChange: function () {} | |
}; | |
function pretendRequest(email, pass, cb) { | |
setTimeout(() => { | |
if (email === 'joe@example.com' && pass === 'password1') { | |
cb({ | |
authenticated: true, | |
token: Math.random().toString(36).substring(7) | |
}); | |
} else { | |
cb({authenticated: false}); | |
} | |
}, 0); | |
} | |
var routes = ( | |
<Route handler={App}> | |
<DefaultRoute handler={DefaultView}/> | |
<Route name="login" handler={LoginView}/> | |
<Route name="logout" handler={LogoutView}/> | |
<Route name="about" handler={AboutView}/> | |
<Route name="dashboard" handler={DashboardView}/> | |
</Route> | |
); | |
exports.LoginView = LoginView; | |
exports.AboutView = AboutView; | |
exports.DefaultView = DefaultView; | |
exports.LogoutView = LogoutView; | |
exports.App = App; | |
exports.routes = routes; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment