diff options
| author | Jules Laplace <jules@okfoc.us> | 2017-03-18 21:42:30 +0100 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2017-03-18 21:42:30 +0100 |
| commit | c548b3bd3f0de1a1a74606d60ef9fdd323792918 (patch) | |
| tree | 453c4d1d44d97536a519e66ce17eb488ad098ec2 /client/components | |
| parent | 09ffebf333adfe45967b44eb8f6237a65a876e25 (diff) | |
user authentication in browser
Diffstat (limited to 'client/components')
| -rw-r--r-- | client/components/App.jsx | 56 | ||||
| -rw-r--r-- | client/components/CalorieView.jsx | 56 | ||||
| -rw-r--r-- | client/components/LoggedOutView.jsx | 192 | ||||
| -rw-r--r-- | client/components/ModalDialog.jsx | 16 |
4 files changed, 315 insertions, 5 deletions
diff --git a/client/components/App.jsx b/client/components/App.jsx index f7cfa97..5a026b4 100644 --- a/client/components/App.jsx +++ b/client/components/App.jsx @@ -1,10 +1,56 @@ -import React from 'react'; +import React from 'react' +import LoggedOutView from './LoggedOutView.jsx' +import CalorieView from './CalorieView.jsx' + +import feathers from 'feathers/client' +import feathersHooks from 'feathers-hooks' +import feathersRest from 'feathers-rest/client' +import feathersAuthentication from 'feathers-authentication/client' +import superagent from 'superagent' + +const rest = feathersRest(window.location.origin) + +const client = feathers() + .configure(feathersHooks()) + .configure(feathersAuthentication({ storage: localStorage })) + .configure(rest.superagent(superagent)) export default class App extends React.Component { + constructor() { + super() + this.state = { + ready: true, + loggedIn: false, + user: {}, + } + client.authenticate() + .then(user => { + console.log(user) + this.setState({ ready: true, loggedIn: true, user: user }) + }) + .catch(error => { + this.setState({ ready: true }) + console.error(error) + }) + } render() { - return ( - <div style={{textAlign: 'center'}}> - <h1>Hello World</h1> - </div>); + if (this.state.ready) { + if (this.state.loggedIn) { + return ( + <CalorieView client={client} /> + ) + } + else { + return ( + <LoggedOutView client={client} /> + ) + } + } + else { + return ( + <div>LOADING...</div> + ) + } } } + diff --git a/client/components/CalorieView.jsx b/client/components/CalorieView.jsx new file mode 100644 index 0000000..3c5fe2d --- /dev/null +++ b/client/components/CalorieView.jsx @@ -0,0 +1,56 @@ +import React from 'react' +import ModalDialog from './ModalDialog.jsx' + +export default class LoggedOutView extends React.Component { + constructor() { + super() + this.state = { modal: null } +// this.showLogin = this.showLogin.bind(this) +// this.showSignup = this.showSignup.bind(this) +// this.closeModal = this.closeModal.bind(this) + } +// showLogin() { +// this.setState({ modal: 'login' }) +// } +// showSignup() { +// this.setState({ modal: 'signup' }) +// } +// closeModal() { +// this.setState({ modal: '' }) +// } + render() { +// const loginVisible = this.state.modal == 'login' +// const signupVisible = this.state.modal == 'signup' + return ( + <div> + LOGGED IN + </div> +// <Welcome +// onLoginClick={this.showLogin} +// onSignupClick={this.showSignup} /> +// <LoginForm +// client={this.props.client} +// visible={loginVisible} +// onClose={this.closeModal} /> +// <SignupForm +// client={this.props.client} +// visible={signupVisible} +// onClose={this.closeModal} /> + ) + } +} + + +// export default class UserForm extends React.Component { +// render() { +// return ( +// ) +// } +// } +// +// export default class MealForm extends React.Component { +// render() { +// return ( +// ) +// } +// } diff --git a/client/components/LoggedOutView.jsx b/client/components/LoggedOutView.jsx new file mode 100644 index 0000000..e058455 --- /dev/null +++ b/client/components/LoggedOutView.jsx @@ -0,0 +1,192 @@ +import React from 'react' +import ModalDialog from './ModalDialog.jsx' + +export default class LoggedOutView extends React.Component { + constructor() { + super() + this.state = { modal: null } + this.showLogin = this.showLogin.bind(this) + this.showSignup = this.showSignup.bind(this) + this.closeModal = this.closeModal.bind(this) + } + showLogin() { + this.setState({ modal: 'login' }) + } + showSignup() { + this.setState({ modal: 'signup' }) + } + closeModal() { + this.setState({ modal: '' }) + } + render() { + const loginVisible = this.state.modal == 'login' + const signupVisible = this.state.modal == 'signup' + return ( + <div> + <Welcome + onLoginClick={this.showLogin} + onSignupClick={this.showSignup} /> + <LoginForm + client={this.props.client} + visible={loginVisible} + onClose={this.closeModal} /> + <SignupForm + client={this.props.client} + visible={signupVisible} + onClose={this.closeModal} /> + </div> + ) + } +} + +class Welcome extends React.Component { + render() { + return ( + <div className='welcome inner'> + <h1>Calorie Counter</h1> + <button onClick={this.props.onLoginClick}> + Log In + </button> + <button onClick={this.props.onSignupClick}> + Sign Up + </button> + </div> + ) + } +} + +class LoginForm extends React.Component { + constructor() { + super() + this.state = { + email: '', + password: '', + error: null, + } + this.updateState = this.updateState.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) + } + updateState(event){ + const name = event.target.name + const value = event.target.value + this.setState({ + [name]: value, + error: null, + }) + } + handleSubmit(event) { + event.preventDefault() + this.props.client.authenticate({ + type: 'local', + email: this.state.email, + password: this.state.password, + }).then(res => { + console.log('Authenticated!', res); + // this.props.client.set('user', res.data) + // something in this library is hardcoded accessToken + // return this.props.client.passport.setJWT(res.token) + }).catch(error => { + console.error('Error authenticating!', error); + this.setState({ + error: error.toString() + }) + }) + } + render() { + return ( + <ModalDialog visible={this.props.visible} onClose={this.props.onClose}> + <form onSubmit={this.handleSubmit}> + <input type='email' + name='email' + placeholder='Email address' + onChange={this.updateState} + /><br/> + <input type='password' + name='password' + placeholder='Password' + onChange={this.updateState} + /><br/> + <input type='submit' + value='Log In' + /> + <div className='error'>{this.state.error}</div> + </form> + </ModalDialog> + ) + } +} + +class SignupForm extends React.Component { + constructor() { + super() + this.state = { + email: '', + password: '', + goal: 0, + error: null, + } + this.updateState = this.updateState.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) + } + updateState(event){ + const name = event.target.name + const value = event.target.value + this.setState({ + [name]: value, + error: null, + }) + } + handleSubmit(event) { + event.preventDefault() + const usersService = this.props.client.service('users') + usersService.create(this.state).then(result => { + return this.props.client.authenticate({ + strategy: 'local', + email: this.state.email, + password: this.state.password, + }) + }) + .then(res => { + this.props.client.set('user', res.data) + this.props.client.set('token', res.accessToken) + return client.passport.verifyJWT(res.accessToken) + }) + .then(payload => { + console.log(payload) + }).catch(error => { + console.error(error) + this.setState({ + error: error.toString() + }) + }) + } + render() { + return ( + <ModalDialog visible={this.props.visible} onClose={this.props.onClose}> + <form onSubmit={this.handleSubmit}> + <input type='email' + name='email' + placeholder='Email address' + onChange={this.updateState} + /><br/> + <input type='password' + name='password' + placeholder='Password' + onChange={this.updateState} + /><br/> + <input type='number' + name='goal' + min='0' + max='100000' + placeholder='Calorie Goal' + onChange={this.updateState} + /><br/> + <input type='submit' + value='Sign Up' + /> + <div className='error'>{this.state.error}</div> + </form> + </ModalDialog> + ) + } +} diff --git a/client/components/ModalDialog.jsx b/client/components/ModalDialog.jsx new file mode 100644 index 0000000..0b6aae1 --- /dev/null +++ b/client/components/ModalDialog.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +export default function ModalDialog (props) { + const visible = props.visible ? 'visible' : '' + function cancel (e) { + e.stopPropagation() + } + return ( + <div className={'modal ' + visible} onClick={props.onClose}> + <div className='inner' onClick={cancel}> + {props.children} + <div className='close' onClick={props.onClose}>x</div> + </div> + </div> + ) +} |
