Skip to content
This repository has been archived by the owner on Aug 28, 2020. It is now read-only.

Commit

Permalink
Consolidate authentication form, move to redux-form
Browse files Browse the repository at this point in the history
There is no createAccount action on the server, so that'll be the next
step
  • Loading branch information
pletcher committed Aug 18, 2017
1 parent 409b997 commit 5d19e95
Show file tree
Hide file tree
Showing 15 changed files with 221 additions and 354 deletions.
5 changes: 5 additions & 0 deletions imports/reducers/index.js
@@ -0,0 +1,5 @@
import { reducer as form } from 'redux-form'

export default {
form,
}
31 changes: 22 additions & 9 deletions imports/startup/client/App.jsx
@@ -1,7 +1,13 @@
import React from 'react';
import { ApolloProvider } from 'react-apollo';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import {
applyMiddleware,
combineReducers,
compose,
createStore,
} from 'redux'
import { mount } from 'react-mounter';
import { ApolloProvider } from 'react-apollo';

import AboutPage from '/imports/ui/components/pages/AboutPage';
import BrowsePage from '/imports/ui/components/browse/BrowsePage';
Expand All @@ -15,18 +21,25 @@ import UserLayout from '/imports/ui/layouts/UserLayout';

import Utils from '/imports/lib/utils';
import client from './apolloClient';
import reducers from '/imports/reducers'

/*
import configureStore from './store/configureStore';
import registerServiceWorker from './registerServiceWorker';
// initialState is a placeholder for now, but it could eventually
// be hydrated on application start
const initialState = {}

const store = configureStore();
const history = syncHistoryWithStore(browserHistory, store);
*/
const store = createStore(
combineReducers({
...reducers,
apollo: client.reducer()
}),
initialState,
compose(
applyMiddleware(client.middleware())
)
)

const App = () => (
<ApolloProvider client={client}>
<ApolloProvider store={store} client={client}>
<Router>
<Switch>
<Route exact path="/" component={HomeLayout} />
Expand Down
114 changes: 114 additions & 0 deletions imports/ui/components/auth/AuthForm/AuthForm.js
@@ -0,0 +1,114 @@
import React from 'react';
import PropTypes from 'prop-types'
import { Field, reduxForm } from 'redux-form'

const renderPasswordRepeat = props => {
if (props.authAction === 'signup') {
return (
<div className="at-input form-group has-feedback">
<label className="control-label" htmlFor="at-field-password">
Password (Again)
</label>
<Field
component="input"
name="passwordRepeat"
type="password"
className="form-control sign-in-input--password sign-in-input--password-repeat"
id="at-field-password-repeat"
placeholder="Password (again)"
autoCapitalize="none"
autoCorrect="off"
autoComplete="off"
style={{
backgroundImage: 'url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAkCAYAAADo6zjiAAAAAXNSR0IArs4c6QAAAvhJREFUWAndWDtrIlEUPo4SUVDUhbjrWqkgiYGNnWBhEPMPoizb+g8sUgk2Vlv6Hxa2lnSC5GFArLTQViWs0SImYKFgjHvOrHN3Xo6OOxLYC5N73ue75965c4wJcBSLxc+vr6/fkTxbLpc+khk1TCbTAGNdWyyWy3w+/0se17RK3sLEH+RKI3kE8oQgvshBcLTyfSenhVCOVZUl6+KQO5NI9ssocnFG77kWfrVcVIF3Hf83gKOjI8jlckDzurHXCkQiEXA6nUDzurFXAPju83mFWQ3EXgGoJZTLJACsVisEg0Fwu91yO9hVpwgkE1gE3uVyQTabBYfDAW9vb1Aul6HZbPLqXXVCbK2ZVSAWi/HJyZjjOEgmk8xvVx0LoEEwABo2e1UxAPV6HSaTCZ+MtqBarbLEu+pYAA3CVCgUloKeDprf74fxeAzPz8+CmJ+1dBLDDQy+ko9ocrPqDx4kADb4GqpGIGMEccq2wNDoWwTDL6OH+oN3A7DCmGD3wBagNU2Oj48hk8mstcHWD3DFEj1W4ZNhFbDZbJLg2zKGVUAMYD6fw3Q6lWDA1Up4gTEMgN1uF2JCq9WCq6srxmsRFnwdBmq9mpaTmk5cAY/HA+fn5/ye93o96Ha7ai68jCpwjc83nvuHP2IAgUAA6KGRSCTg/v4eKpWKanSObiSswpOqVofQbDavtY7H4xCNRlX1ZrzzJ6lU6gduw0cEQr+OHKqWG4SdTgdGoxE0Gg24u7uDwWAAoVAIBGBUIeHzLg71p2cSSzbQ4m/HBlNIp9OsH6TvS6lUUrgYdg+cnJzAwcEBS0C01+tl/MvLC6PFhGGv4cXFBX/qaaWz2Qx8Ph/g+WK5+v0+o8XEXwuxdEeaEh4eHiq8h8Mh1Go1hZwEugHgQX2kO1wejRqYcDjMN7R04OgmpJ6i3W7zB3OxWMhdgGLpBoBRbvD5Ko92e3sL9OgcN7oP4ereGOtMpDDH1VNDcqkbAP6H4wEdTzHATyqhIvIGAfmQL8WgWL8B6msZ8cYhQlQAAAAASUVORK5CYII=&quot;)',
backgroundRepeat: 'no-repeat',
backgroundAttachment: 'scroll',
backgroundSize: '16px 18px',
backgroundPosition: '98% 50%',
}}
/>
<span className="help-block hide" />
</div>
)
}

return null
}

export const AuthForm = props => {
return (
<div className="at-pwd-form">
<form role="form" id="at-pwd-form" noValidate="" onSubmit={props.handleSubmit}>
<fieldset>
<div className="at-input form-group has-feedback">
<label className="control-label" htmlFor="at-field-email">
Email
</label>
<Field
component="input"
name="email"
type="email"
className="form-control sign-in-input--email"
id="at-field-email"
placeholder="Email"
autoCapitalize="none"
autoCorrect="off"
autoComplete="off"
style={{
backgroundImage: 'url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAkCAYAAADo6zjiAAAAAXNSR0IArs4c6QAAAvhJREFUWAndWDtrIlEUPo4SUVDUhbjrWqkgiYGNnWBhEPMPoizb+g8sUgk2Vlv6Hxa2lnSC5GFArLTQViWs0SImYKFgjHvOrHN3Xo6OOxLYC5N73ue75965c4wJcBSLxc+vr6/fkTxbLpc+khk1TCbTAGNdWyyWy3w+/0se17RK3sLEH+RKI3kE8oQgvshBcLTyfSenhVCOVZUl6+KQO5NI9ssocnFG77kWfrVcVIF3Hf83gKOjI8jlckDzurHXCkQiEXA6nUDzurFXAPju83mFWQ3EXgGoJZTLJACsVisEg0Fwu91yO9hVpwgkE1gE3uVyQTabBYfDAW9vb1Aul6HZbPLqXXVCbK2ZVSAWi/HJyZjjOEgmk8xvVx0LoEEwABo2e1UxAPV6HSaTCZ+MtqBarbLEu+pYAA3CVCgUloKeDprf74fxeAzPz8+CmJ+1dBLDDQy+ko9ocrPqDx4kADb4GqpGIGMEccq2wNDoWwTDL6OH+oN3A7DCmGD3wBagNU2Oj48hk8mstcHWD3DFEj1W4ZNhFbDZbJLg2zKGVUAMYD6fw3Q6lWDA1Up4gTEMgN1uF2JCq9WCq6srxmsRFnwdBmq9mpaTmk5cAY/HA+fn5/ye93o96Ha7ai68jCpwjc83nvuHP2IAgUAA6KGRSCTg/v4eKpWKanSObiSswpOqVofQbDavtY7H4xCNRlX1ZrzzJ6lU6gduw0cEQr+OHKqWG4SdTgdGoxE0Gg24u7uDwWAAoVAIBGBUIeHzLg71p2cSSzbQ4m/HBlNIp9OsH6TvS6lUUrgYdg+cnJzAwcEBS0C01+tl/MvLC6PFhGGv4cXFBX/qaaWz2Qx8Ph/g+WK5+v0+o8XEXwuxdEeaEh4eHiq8h8Mh1Go1hZwEugHgQX2kO1wejRqYcDjMN7R04OgmpJ6i3W7zB3OxWMhdgGLpBoBRbvD5Ko92e3sL9OgcN7oP4ereGOtMpDDH1VNDcqkbAP6H4wEdTzHATyqhIvIGAfmQL8WgWL8B6msZ8cYhQlQAAAAASUVORK5CYII=&quot;)',
backgroundRepeat: 'no-repeat',
backgroundAttachment: 'scroll',
backgroundSize: '16px 18px',
backgroundPosition: '98% 50%',
}}
/>
<span className="help-block hide" />
</div>
<div className="at-input form-group has-feedback">
<label className="control-label" htmlFor="at-field-password">
Password
</label>
<Field
component="input"
name="password"
type="password"
className="form-control sign-in-input--password"
id="at-field-password"
placeholder="Password"
autoCapitalize="none"
autoCorrect="off"
autoComplete="off"
style={{
backgroundImage: 'url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAkCAYAAADo6zjiAAAAAXNSR0IArs4c6QAAAvhJREFUWAndWDtrIlEUPo4SUVDUhbjrWqkgiYGNnWBhEPMPoizb+g8sUgk2Vlv6Hxa2lnSC5GFArLTQViWs0SImYKFgjHvOrHN3Xo6OOxLYC5N73ue75965c4wJcBSLxc+vr6/fkTxbLpc+khk1TCbTAGNdWyyWy3w+/0se17RK3sLEH+RKI3kE8oQgvshBcLTyfSenhVCOVZUl6+KQO5NI9ssocnFG77kWfrVcVIF3Hf83gKOjI8jlckDzurHXCkQiEXA6nUDzurFXAPju83mFWQ3EXgGoJZTLJACsVisEg0Fwu91yO9hVpwgkE1gE3uVyQTabBYfDAW9vb1Aul6HZbPLqXXVCbK2ZVSAWi/HJyZjjOEgmk8xvVx0LoEEwABo2e1UxAPV6HSaTCZ+MtqBarbLEu+pYAA3CVCgUloKeDprf74fxeAzPz8+CmJ+1dBLDDQy+ko9ocrPqDx4kADb4GqpGIGMEccq2wNDoWwTDL6OH+oN3A7DCmGD3wBagNU2Oj48hk8mstcHWD3DFEj1W4ZNhFbDZbJLg2zKGVUAMYD6fw3Q6lWDA1Up4gTEMgN1uF2JCq9WCq6srxmsRFnwdBmq9mpaTmk5cAY/HA+fn5/ye93o96Ha7ai68jCpwjc83nvuHP2IAgUAA6KGRSCTg/v4eKpWKanSObiSswpOqVofQbDavtY7H4xCNRlX1ZrzzJ6lU6gduw0cEQr+OHKqWG4SdTgdGoxE0Gg24u7uDwWAAoVAIBGBUIeHzLg71p2cSSzbQ4m/HBlNIp9OsH6TvS6lUUrgYdg+cnJzAwcEBS0C01+tl/MvLC6PFhGGv4cXFBX/qaaWz2Qx8Ph/g+WK5+v0+o8XEXwuxdEeaEh4eHiq8h8Mh1Go1hZwEugHgQX2kO1wejRqYcDjMN7R04OgmpJ6i3W7zB3OxWMhdgGLpBoBRbvD5Ko92e3sL9OgcN7oP4ereGOtMpDDH1VNDcqkbAP6H4wEdTzHATyqhIvIGAfmQL8WgWL8B6msZ8cYhQlQAAAAASUVORK5CYII=&quot;)',
backgroundRepeat: 'no-repeat',
backgroundAttachment: 'scroll',
backgroundSize: '16px 18px',
backgroundPosition: '98% 50%',
}}
/>
<span className="help-block hide" />
</div>
{renderPasswordRepeat(props)}
<span className="error-text">
{props.errorMessage}
</span>
<button type="submit" className="at-btn submit btn btn-lg btn-block btn-default" id="at-btn">
{props.authAction === 'login' ? 'Sign in' : 'Register'}
</button>
</fieldset>
</form>
</div>
)
}

AuthForm.propTypes = {
authAction: PropTypes.oneOf(['login', 'signup']).isRequired,
errorMessage: PropTypes.string,
handleSubmit: PropTypes.func.isRequired,
}

AuthForm.defaultProps = {
errorMessage: '',
}

export default reduxForm({ form: 'authentication' })(AuthForm);
Expand Up @@ -2,13 +2,13 @@ import React from 'react';
import renderer from 'react-test-renderer';

// component:
import PWDLoginForm from './PWDLoginForm';
import AuthForm from './AuthForm';

describe('PWDLoginForm', () => {
describe('AuthForm', () => {
it('renders correctly', () => {

const tree = renderer
.create(<PWDLoginForm />)
.create(<AuthForm />)
.toJSON();
expect(tree).toMatchSnapshot();
});
Expand Down
6 changes: 6 additions & 0 deletions imports/ui/components/auth/AuthForm/package.json
@@ -0,0 +1,6 @@
{
"name": "AuthForm",
"version": "0.0.2",
"private": true,
"main": "./AuthForm.js"
}
35 changes: 22 additions & 13 deletions imports/ui/components/auth/AuthModal/AuthModal.js
Expand Up @@ -8,9 +8,8 @@ import { Accounts } from 'meteor/accounts-base';
import { Link } from 'react-router-dom';
import { Meteor } from 'meteor/meteor';

import AuthForm from '/imports/ui/components/auth/AuthForm';
import OAuthButtons from '/imports/ui/components/auth/OAuthButtons';
import PWDLoginForm from '/imports/ui/components/auth/PWDLoginForm';
import PWDSignupForm from '/imports/ui/components/auth/PWDSignupForm';

const ESCAPE_KEY = 27;

Expand Down Expand Up @@ -47,6 +46,7 @@ export default class AuthModal extends React.Component {
this.handleLoginFacebook = this.handleLoginFacebook.bind(this)
this.handleLoginGoogle = this.handleLoginGoogle.bind(this)
this.handleLoginTwitter = this.handleLoginTwitter.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}

getChildContext() {
Expand Down Expand Up @@ -77,6 +77,15 @@ export default class AuthModal extends React.Component {
event.keyCode === ESCAPE_KEY && this.props.closeModal()
}

handleSubmit(values) {
console.log(values)
if (this.props.authAction === 'login') {
return this.handleLogin(values.email, values.password)
}

this.handleSignup(values.email, values.password, values.passwordRepeat)
}

handleLogin(email, password) {
Meteor.loginWithPassword(email, password, err => {
if (err) {
Expand Down Expand Up @@ -125,7 +134,7 @@ export default class AuthModal extends React.Component {
})
}

handleSignUp(email, password, passwordRepeat) {
handleSignup(email, password, passwordRepeat) {
if (password !== passwordRepeat) {
// QUESTION: Why was this check throwing a Meteor.Error previously?
return this.setState({
Expand All @@ -136,6 +145,7 @@ export default class AuthModal extends React.Component {
const checkPassword = Accounts._hashPassword(password)

Meteor.call('createAccount', { email, checkPassword }, (err, result) => {
console.log(err, result)
if (err) {
return this.setState({
errorMessage: err.message,
Expand Down Expand Up @@ -177,12 +187,6 @@ export default class AuthModal extends React.Component {

if (authAction === 'login') {
title = 'Sign in'
pwdForm = (
<PWDLoginForm
login={this.handleLogin}
errorMsg={this.state.errorMessage}
/>
)
alternateAction = (
<p>
Don't have an account? <Link to="sign-up" id="at-signUp" className="at-link at-signup">Register</Link>.
Expand All @@ -191,9 +195,10 @@ export default class AuthModal extends React.Component {
} else if (authAction === 'signup') {
title = 'Create an account'
pwdForm = (
<PWDSignupForm
handleSignup={this.handleSignup}
errorMsg={this.state.errorMessage}
<AuthForm
authAction={authAction}
onSubmit={this.handleSignup}
errorMessage={this.state.errorMessage}
/>
)
termsNotice = (
Expand Down Expand Up @@ -237,7 +242,11 @@ export default class AuthModal extends React.Component {
<strong>OR</strong>
</div>

{pwdForm}
<AuthForm
authAction={authAction}
onSubmit={this.handleSubmit}
errorMsg={this.state.errorMessage}
/>

<div className="at-signup-link">

Expand Down
87 changes: 0 additions & 87 deletions imports/ui/components/auth/PWDLoginForm/PWDLoginForm.js

This file was deleted.

0 comments on commit 5d19e95

Please sign in to comment.