Fully functional Sign Up & Sign Incontrols.

This commit is contained in:
Andrew Revinsky (DART)
2016-02-15 21:58:46 +03:00
parent 822c0efb6d
commit 42db215414
9 changed files with 479 additions and 27 deletions

View File

@@ -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",

View File

@@ -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,

View File

@@ -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: <Glyphicon glyph="heart" />,
loading: false,
spinConfig: {
lines: 10,
length: 4,
width: 2,
radius: 3
},
spinColorDark: "#444",
spinColorLight: "#fff",
children: <span>Submit</span>,
style: {}
};
renderIcon () {
let icon;
if (this.props.loading) {
let spinColor = (!this.props.bsStyle || this.props.bsStyle === "default")
? this.props.spinColorDark
: this.props.spinColorLight;
icon = <Spinner ref="spinner" {...this.props.spinConfig} color={spinColor} loaded={false} />;
} else {
icon = this.props.icon;
}
return (
<div style={{
position: "relative",
display: "inline-block",
marginRight: "6px",
width: "10px",
height: "10px",
top: "1px"
}}>
{icon}
</div>
);
}
render () {
return (
<Button
onClick={this.props.onClick}
disabled={this.props.disabled || this.props.loading}
bsStyle={this.props.bsStyle}
className={this.props.className}
type={this.props.type}
style={this.props.style}
bsSize={this.props.bsSize}>
{this.renderIcon()} {this.props.children}
</Button>
);
}
}
export default ButtonLoader;

View File

@@ -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";
/*
<Input type="password"
label="Password"
className="email-sign-in-password"
placeholder="Password"
disabled={disabled}
value={this.props.auth.getIn(["emailSignIn", this.getEndpoint(), "form", "password"])}
errors={this.props.auth.getIn(["emailSignIn", this.getEndpoint(), "errors", "password"])}
onChange={this.handleInput.bind(this, "password")}
{...this.props.inputProps.password} />
*/
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 (
<form className='redux-auth email-sign-in-form clearfix'
onSubmit={this.handleSubmit.bind(this)}>
<Input type="text"
className="email-sign-in-email"
label="Email"
placeholder="Email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignIn", this.getEndpoint(), "form", "email"])}
errors={this.props.auth.getIn(["emailSignIn", this.getEndpoint(), "errors", "email"])}
onChange={this.handleInput.bind(this, "email")}
{...this.props.inputProps.email} />
<ButtonLoader loading={this.props.auth.getIn(["emailSignIn", this.getEndpoint(), "loading"])}
type="submit"
icon={<Glyphicon glyph="log-in" />}
className='email-sign-in-submit pull-right'
disabled={disabled}
onClick={this.handleSubmit.bind(this)}
{...this.props.inputProps.submit}>
Sign In
</ButtonLoader>
</form>
);
}
}
export default connect(({auth}) => ({auth}))(EmailSignInForm);

View File

@@ -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"])
);
/*
* <Input type="password"
label="Password"
placeholder="Password"
className="email-sign-up-password"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "password"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "password"])}
onChange={this.handleInput.bind(this, "password")}
{...this.props.inputProps.password} />
<Input type="password"
label="Password Confirmation"
placeholder="Password Confirmation"
className="email-sign-up-password-confirmation"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "password_confirmation"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "password_confirmation"])}
onChange={this.handleInput.bind(this, "password_confirmation")}
{...this.props.inputProps.passwordConfirmation} />
*/
return (
<form className='redux-auth email-sign-up-form clearfix'
onSubmit={this.handleSubmit.bind(this)}>
<Input type="text"
label="First name"
placeholder="First name"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "fname"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "fname"])}
onChange={this.handleInput.bind(this, "fname")}
{...this.props.inputProps.fname} />
<Input type="text"
label="Last name"
placeholder="Last name"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "lname"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "lname"])}
onChange={this.handleInput.bind(this, "lname")}
{...this.props.inputProps.lname} />
<Input type="text"
label="Email"
placeholder="Email"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "email"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "email"])}
onChange={this.handleInput.bind(this, "email")}
{...this.props.inputProps.email} />
<Input type="text"
label="SSN"
placeholder="SSN"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "ssn"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "ssn"])}
onChange={this.handleInput.bind(this, "ssn")}
{...this.props.inputProps.ssn} />
<Input type="text"
label="Phone"
placeholder="Phone"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "phone"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "phone"])}
onChange={this.handleInput.bind(this, "phone")}
{...this.props.inputProps.phone} />
<Input type="text"
label="Address 1"
placeholder="Address 1"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "address1"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "address1"])}
onChange={this.handleInput.bind(this, "address1")}
{...this.props.inputProps.address1} />
<Input type="text"
label="Address 2"
placeholder="Address 2"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "address2"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "address2"])}
onChange={this.handleInput.bind(this, "address2")}
{...this.props.inputProps.address2} />
<Input type="text"
label="City"
placeholder="City"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "city"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "city"])}
onChange={this.handleInput.bind(this, "city")}
{...this.props.inputProps.city} />
<Input type="text"
label="State"
placeholder="State"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "state"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "state"])}
onChange={this.handleInput.bind(this, "state")}
{...this.props.inputProps.state} />
<Input type="text"
label="ZIP"
placeholder="ZIP"
className="email-sign-up-email"
disabled={disabled}
value={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "form", "zip"])}
errors={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "errors", "zip"])}
onChange={this.handleInput.bind(this, "zip")}
{...this.props.inputProps.zip} />
<ButtonLoader loading={this.props.auth.getIn(["emailSignUp", this.getEndpoint(), "loading"])}
type="submit"
className="email-sign-up-submit pull-right"
icon={<Glyphicon glyph="send" />}
disabled={disabled}
onClick={this.handleSubmit.bind(this)}
{...this.props.inputProps.submit}>
Sign Up
</ButtonLoader>
</form>
);
}
}
export default connect(({auth}) => ({auth}))(EmailSignUpForm);

View File

@@ -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 (
<div className='auth-error-message has-error'>
{this.props.errors.map((err, i) => {
return (
<p className="control-label inline-error-item"
style={{paddingLeft: "20px", position: "relative", marginBottom: "28px"}}
key={i}>
<Glyphicon glyph="exclamation-sign"
style={{
position: "absolute",
left: 0,
top: 2
}}
/> {this.props.label} {err}
</p>
);
})}
</div>
);
} else {
return <span />;
}
}
render () {
return (
<div>
<Input {...this.props}
bsStyle={(this.props.errors.size) ? "error" : null}
onChange={this.handleInput.bind(this)} />
{this.renderErrorList()}
</div>
);
}
}
export default AuthInput;

View File

@@ -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 <EmailSignInForm />;
//return (
// <div>

View File

@@ -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 <EmailSignUpForm />;
//return (
// <div>
// <PageHeader>Sign Up Page</PageHeader>
// <p>Here you can register.</p>
// </div>
//);
return <EmailSignUpForm endpoint="default" />;
}
}
export default connect(({routes}) => ({routes}))(SignUp);

View File

@@ -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: {