From 42db215414545c62793b653e9ace40e02813c769 Mon Sep 17 00:00:00 2001 From: "Andrew Revinsky (DART)" Date: Mon, 15 Feb 2016 21:58:46 +0300 Subject: [PATCH] Fully functional Sign Up & Sign Incontrols. --- js-frontend/package.json | 2 + js-frontend/src/App.js | 37 ++-- .../src/controls/bootstrap/ButtonLoader.js | 78 +++++++ .../src/controls/bootstrap/EmailSignInForm.js | 94 +++++++++ .../src/controls/bootstrap/EmailSignUpForm.js | 195 ++++++++++++++++++ js-frontend/src/controls/bootstrap/Input.js | 64 ++++++ js-frontend/src/views/SignIn.js | 23 ++- js-frontend/src/views/SignUp.js | 12 +- js-frontend/webpack.config.js | 1 + 9 files changed, 479 insertions(+), 27 deletions(-) create mode 100644 js-frontend/src/controls/bootstrap/ButtonLoader.js create mode 100644 js-frontend/src/controls/bootstrap/EmailSignInForm.js create mode 100644 js-frontend/src/controls/bootstrap/EmailSignUpForm.js create mode 100644 js-frontend/src/controls/bootstrap/Input.js diff --git a/js-frontend/package.json b/js-frontend/package.json index 7c14a47..41ec88d 100644 --- a/js-frontend/package.json +++ b/js-frontend/package.json @@ -48,11 +48,13 @@ "babel-polyfill": "6.1.4", "babel-runtime": "6.0.14", "history": "1.17.0", + "immutable": "^3.7.6", "invariant": "^2.1.1", "object-pick": "^0.1.1", "react": "^0.14.7", "react-bootstrap": "^0.28.3", "react-dom": "^0.14.0", + "react-loader": "^2.0.0", "react-pacomo": "^0.5.1", "react-redux": "^4.4.0", "react-router": "^1.0.3", diff --git a/js-frontend/src/App.js b/js-frontend/src/App.js index 835855f..6817ad3 100644 --- a/js-frontend/src/App.js +++ b/js-frontend/src/App.js @@ -182,25 +182,26 @@ export function initialize({cookies, isServer, currentLocation, userAgent} = {}) //apiUrl: __API_URL__ apiUrl: '/api' } - }, { - evilUser: { - //apiUrl: __API_URL__, - apiUrl: '/api', - signOutPath: "/mangs/sign_out", - emailSignInPath: "/mangs/sign_in", - emailRegistrationPath: "/mangs", - accountUpdatePath: "/mangs", - accountDeletePath: "/mangs", - passwordResetPath: "/mangs/password", - passwordUpdatePath: "/mangs/password", - tokenValidationPath: "/mangs/validate_token", - authProviderPaths: { - github: "/mangs/github", - facebook: "/mangs/facebook", - google: "/mangs/google_oauth2" - } - } } + //, { + // evilUser: { + // //apiUrl: __API_URL__, + // apiUrl: '/api', + // signOutPath: "/mangs/sign_out", + // emailSignInPath: "/mangs/sign_in", + // emailRegistrationPath: "/mangs", + // accountUpdatePath: "/mangs", + // accountDeletePath: "/mangs", + // passwordResetPath: "/mangs/password", + // passwordUpdatePath: "/mangs/password", + // tokenValidationPath: "/mangs/validate_token", + // authProviderPaths: { + // github: "/mangs/github", + // facebook: "/mangs/facebook", + // google: "/mangs/google_oauth2" + // } + // } + //} ], { cookies, isServer, diff --git a/js-frontend/src/controls/bootstrap/ButtonLoader.js b/js-frontend/src/controls/bootstrap/ButtonLoader.js new file mode 100644 index 0000000..a808d67 --- /dev/null +++ b/js-frontend/src/controls/bootstrap/ButtonLoader.js @@ -0,0 +1,78 @@ +/** + * Created by andrew on 15/02/16. + */ +import React, { PropTypes } from "react"; +import { Button, Glyphicon } from "react-bootstrap"; +import Spinner from "react-loader"; + +class ButtonLoader extends React.Component { + static propTypes = { + icon: PropTypes.node, + loading: PropTypes.bool, + spinConfig: PropTypes.object, + spinColorDark: PropTypes.string, + spinColorLight: PropTypes.string, + children: PropTypes.node, + onClick: PropTypes.func.isRequired, + style: PropTypes.object + }; + + static defaultProps = { + icon: , + loading: false, + spinConfig: { + lines: 10, + length: 4, + width: 2, + radius: 3 + }, + spinColorDark: "#444", + spinColorLight: "#fff", + children: Submit, + style: {} + }; + + renderIcon () { + let icon; + + if (this.props.loading) { + let spinColor = (!this.props.bsStyle || this.props.bsStyle === "default") + ? this.props.spinColorDark + : this.props.spinColorLight; + + icon = ; + } else { + icon = this.props.icon; + } + + return ( +
+ {icon} +
+ ); + } + + render () { + return ( + + ); + } +} + +export default ButtonLoader; diff --git a/js-frontend/src/controls/bootstrap/EmailSignInForm.js b/js-frontend/src/controls/bootstrap/EmailSignInForm.js new file mode 100644 index 0000000..ce189f4 --- /dev/null +++ b/js-frontend/src/controls/bootstrap/EmailSignInForm.js @@ -0,0 +1,94 @@ +/** + * Created by andrew on 15/02/16. + */ +import React, {PropTypes} from "react"; +import auth from "redux-auth"; +import Input from "./Input"; +import ButtonLoader from "./ButtonLoader"; +import { emailSignInFormUpdate, emailSignIn } from "redux-auth"; +import { Glyphicon } from "react-bootstrap"; +import { connect } from "react-redux"; + +/* + + */ + +class EmailSignInForm extends React.Component { + static propTypes = { + endpoint: PropTypes.string, + inputProps: PropTypes.shape({ + email: PropTypes.object, + password: PropTypes.object, + submit: PropTypes.object + }) + }; + + static defaultProps = { + inputProps: { + email: {}, + password: {}, + submit: {} + } + }; + + getEndpoint () { + return ( + this.props.endpoint || + this.props.auth.getIn(["configure", "currentEndpointKey"]) || + this.props.auth.getIn(["configure", "defaultEndpointKey"]) + ); + } + + handleInput (key, val) { + this.props.dispatch(emailSignInFormUpdate(this.getEndpoint(), key, val)); + } + + handleSubmit (event) { + event.preventDefault(); + let formData = this.props.auth.getIn(["emailSignIn", this.getEndpoint(), "form"]).toJS(); + debugger; + this.props.dispatch(emailSignIn(formData, this.getEndpoint())); + } + + render () { + let disabled = ( + this.props.auth.getIn(["user", "isSignedIn"]) || + this.props.auth.getIn(["emailSignIn", this.getEndpoint(), "loading"]) + ); + + return ( +
+ + + } + className='email-sign-in-submit pull-right' + disabled={disabled} + onClick={this.handleSubmit.bind(this)} + {...this.props.inputProps.submit}> + Sign In + +
+ ); + } +} + +export default connect(({auth}) => ({auth}))(EmailSignInForm); \ No newline at end of file diff --git a/js-frontend/src/controls/bootstrap/EmailSignUpForm.js b/js-frontend/src/controls/bootstrap/EmailSignUpForm.js new file mode 100644 index 0000000..1f1af6b --- /dev/null +++ b/js-frontend/src/controls/bootstrap/EmailSignUpForm.js @@ -0,0 +1,195 @@ +/** + * Created by andrew on 15/02/16. + */ +import React, {PropTypes} from "react"; +import auth from "redux-auth"; +import Input from "./Input"; +import ButtonLoader from "./ButtonLoader"; +import { emailSignUpFormUpdate, emailSignUp } from "redux-auth"; +import { Glyphicon } from "react-bootstrap"; +import { connect } from "react-redux"; + +class EmailSignUpForm extends React.Component { + static propTypes = { + endpoint: PropTypes.string, + inputProps: PropTypes.shape({ + email: PropTypes.object, + password: PropTypes.object, + passwordConfirmation: PropTypes.object, + submit: PropTypes.object + }) + }; + + static defaultProps = { + inputProps: { + email: {}, + password: {}, + submit: {} + } + }; + + getEndpoint () { + return ( + this.props.endpoint || + this.props.auth.getIn(["configure", "currentEndpointKey"]) || + this.props.auth.getIn(["configure", "defaultEndpointKey"]) + ); + } + + handleInput (key, val) { + this.props.dispatch(emailSignUpFormUpdate(this.getEndpoint(), key, val)); + } + + handleSubmit (event) { + event.preventDefault(); + let formData = this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form"]).toJS(); + this.props.dispatch(emailSignUp(formData, this.getEndpoint())); + } + + render () { + let disabled = ( + this.props.auth.getIn(["user", "isSignedIn"]) || + this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "loading"]) + ); + + /* + * + + + */ + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + } + disabled={disabled} + onClick={this.handleSubmit.bind(this)} + {...this.props.inputProps.submit}> + Sign Up + +
+ ); + } +} + +export default connect(({auth}) => ({auth}))(EmailSignUpForm); \ No newline at end of file diff --git a/js-frontend/src/controls/bootstrap/Input.js b/js-frontend/src/controls/bootstrap/Input.js new file mode 100644 index 0000000..bda633c --- /dev/null +++ b/js-frontend/src/controls/bootstrap/Input.js @@ -0,0 +1,64 @@ +/** + * Created by andrew on 15/02/16. + */ +import React, { PropTypes } from "react"; +import { Input, Glyphicon } from "react-bootstrap"; +import Immutable from "immutable"; + +class AuthInput extends React.Component { + static propTypes = { + label: PropTypes.string, + value: PropTypes.string, + errors: PropTypes.object + }; + + static defaultProps = { + label: "", + value: null, + errors: Immutable.fromJS([]) + }; + + handleInput (ev) { + this.props.onChange(ev.target.value); + } + + renderErrorList () { + if (this.props.errors.size) { + return ( +
+ {this.props.errors.map((err, i) => { + return ( +

+ + {this.props.label} {err} +

+ ); + })} +
+ ); + } else { + return ; + } + } + + render () { + return ( +
+ + {this.renderErrorList()} +
+ ); + } +} + +export default AuthInput; diff --git a/js-frontend/src/views/SignIn.js b/js-frontend/src/views/SignIn.js index 01e93ab..96a42ac 100644 --- a/js-frontend/src/views/SignIn.js +++ b/js-frontend/src/views/SignIn.js @@ -5,11 +5,32 @@ import React from "react"; import { PageHeader } from "react-bootstrap"; import { connect } from "react-redux"; +//import ButtonLoader from "./ButtonLoader"; +import { Input } from "react-bootstrap"; +import ButtonLoader from "../controls/bootstrap/ButtonLoader"; + +//export {bootstrap, materialUi} from "./views"; + + // bootstrap theme -import { EmailSignInForm } from "redux-auth/bootstrap-theme"; +//import { EmailSignInForm } from "redux-auth/bootstrap-theme"; +import EmailSignInForm from "../controls/bootstrap/EmailSignInForm"; + export class SignIn extends React.Component { + render () { + const signInProps = { + inputProps: { + password: { + className: 'hide hidden', + style: { display: 'none' }, + value: null, + disabled: true + } + } + }; + return ; //return ( //
diff --git a/js-frontend/src/views/SignUp.js b/js-frontend/src/views/SignUp.js index 931ff8a..9972cfe 100644 --- a/js-frontend/src/views/SignUp.js +++ b/js-frontend/src/views/SignUp.js @@ -5,18 +5,14 @@ import React from "react"; import { PageHeader } from "react-bootstrap"; import { connect } from "react-redux"; -import { EmailSignUpForm } from "redux-auth/bootstrap-theme" +//import { EmailSignUpForm } from "redux-auth/bootstrap-theme" +import EmailSignUpForm from "../controls/bootstrap/EmailSignUpForm"; export class SignUp extends React.Component { render () { - return ; - //return ( - //
- // Sign Up Page - //

Here you can register.

- //
- //); + return ; + } } export default connect(({routes}) => ({routes}))(SignUp); \ No newline at end of file diff --git a/js-frontend/webpack.config.js b/js-frontend/webpack.config.js index d5471fb..c7c612a 100644 --- a/js-frontend/webpack.config.js +++ b/js-frontend/webpack.config.js @@ -30,6 +30,7 @@ export default (DEBUG, PATH, PORT=3000) => ({ { test: /\.jsx?$/, include: [ path.resolve(__dirname, "src"), + path.resolve(__dirname, "node_modules/redux-auth/src/views/bootstrap") ], loader: "babel-loader", query: {