Skip to content

Instantly share code, notes, and snippets.

@Rolilink
Created October 4, 2017 20:37
Show Gist options
  • Save Rolilink/1674df4ced9aaa194f2bba2129fe80a0 to your computer and use it in GitHub Desktop.
Save Rolilink/1674df4ced9aaa194f2bba2129fe80a0 to your computer and use it in GitHub Desktop.
LoginForm
import React from 'react';
import PropTypes from 'prop-types';
export const getDefaultState = (
{
username = '',
password = '',
shouldRememberUser = false,
error = null,
} = {}
) => ({
username, password, shouldRememberUser, error,
});
export const isValueGreaterOrEqualTo = (value, to) => value >= to;
export default class LoginForm extends React.Component {
static propTypes = {
onSubmit: PropTypes.func.isRequired,
error: PropTypes.string,
isFetching: PropTypes.bool,
}
static defaultProps = {
error: null,
isFetching: false,
}
constructor(props) {
super(props);
this.state = getDefaultState();
}
get errorMessage() {
const error = this.state.error || this.props.error;
if(!error) { return null };
return (
<div className="alert alert-danger" role="alert">
{ error }
</div>
);
}
get loginForm() {
const { username, password, shouldRememberUser } = this.state;
return (
<form onSubmit={this.onSubmitFn}>
{ this.errorMessage }
<div className="form-group">
<label>Username</label>
<input type="text" value={username} onChange={this.getOnStateChangeFn('username')} className="form-control" id="username-input" name="username"/>
</div>
<div className="form-group">
<label>Password</label>
<input type="password" value={password} onChange={this.getOnStateChangeFn('password')} className="form-control" id="password-input" name="password"/>
</div>
<div className="form-check">
<label className="form-check-label">
<input type="checkbox" checked={shouldRememberUser} onChange={this.getOnStateChangeFn('shouldRememberUser')} className="form-check-input" id="remember-me-checkbox" />
<span>Remember Me</span>
</label>
</div>
<div className="form-group">
<div className="row">
<div className="col-md-2">
<button type="submit" className="btn btn-primary">Submit</button>
</div>
<div className="col-md-2">
<a href="#" onClick={this.clearFormFn} className="btn btn-danger">Clear Form</a>
</div>
</div>
</div>
</form>
)
}
get isLoadingMessage() {
return (
<div className="text-center">
Authorizing wait a second ...
</div>
);
}
get onSubmitFn() {
return (e) => {
e.preventDefault();
const { username, password, shouldRememberUser } = this.state;
if (!isValueGreaterOrEqualTo(username.length, 6)) {
return this.setState({ error: 'Username should be at least 6 characters long.' });
}
if (!isValueGreaterOrEqualTo(password.length, 6)) {
return this.setState({ error: 'Password should be at least 6 characters long.' });
}
this.props.onSubmitFn({ username, password, shouldRememberUser });
}
}
get clearFormFn() {
return (e) => {
e.preventDefault();
this.setState(getDefaultState());
}
}
getOnStateChangeFn(field) {
return (e) => {
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
this.setState((prevState) => ({ ...prevState, error: getDefaultState().error, [field]: value }));
}
}
render() {
const { isFetching } = this.props;
return isFetching ? this.isLoadingMessage : this.loginForm;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment