Skip to content

Commit

Permalink
refactor: Simplify account form validation logic
Browse files Browse the repository at this point in the history
Renamed `~/client/src/js/utilties.js` to 'validate-account-form.js'
since the logic in that module were primarily handling submit validation
for forms in AccountForm component and processing the request to backend
server.

Refactored the module to simplify the logic and ease of maintenance. The
module had a broad range of functions; not just handling form submit but
also handling AccountForm component state. AccountForm state is now
handled within its on module to ensure continual encapsulation within
its own module and scope. Message is currently handled with alerts.

Enhanced style of reset-password view.

TODO:
- Add logic for updating user information on server
- Add custom component for alerts
  • Loading branch information
jkwening committed Mar 14, 2018
1 parent 72c1500 commit 8b53674
Show file tree
Hide file tree
Showing 11 changed files with 276 additions and 231 deletions.
122 changes: 60 additions & 62 deletions client/src/components/AccountForm/index.js
Original file line number Diff line number Diff line change
@@ -1,109 +1,108 @@
import { h, Component, render } from 'preact';
import style from './style.css';
import { handleSubmit, clearForms, setStateUserOrRedirectToSignIn } from "../../js/utilities";
import { validateAccountForm, clearForms } from "../../js/validate-account-form";
import { LOGIN_PATH, REGISTER_PATH, RESET_PATH } from '../../../config';
import linkState from "linkstate";
import { route } from 'preact-router';

export default class AccountForm extends Component {
constructor() {
super();
this.state = {
form_message: "",
successMessageMap: this.createMessageMap(),
matchPasswordsMap: this.createMatchPasswordsMap(),
validatePasswordMap: this.createValidatePasswordMap(),
};
this.handleSubmit = handleSubmit.bind(this);
this.routeToRegister = this.routeToRegister.bind(this);
}

createMessageMap = () => {
const messageMap = new Map;
messageMap.set(LOGIN_PATH, 'You have signed in.');
messageMap.set(REGISTER_PATH, 'You have created an account.');
messageMap.set(RESET_PATH, 'You have changed your password.');
return messageMap;
this.routeToRegister = this.routeToRegister.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

createMatchPasswordsMap = () => {
const matchPasswordsMap = new Map;
matchPasswordsMap.set(REGISTER_PATH, ['password','confirm_password']);
matchPasswordsMap.set(RESET_PATH, ['new_password','confirm_password']);
return matchPasswordsMap;
}
/**
* TODO - refactor: simplify
*
* Pass: event, path
* Return: a promise - request result that can be used to here to set 'successMessage'
* via setState
*/
handleSubmit = (event) => {
event.preventDefault();

createValidatePasswordMap = () => {
const validatePasswordMap = new Map;
validatePasswordMap.set(LOGIN_PATH, 'password');
validatePasswordMap.set(REGISTER_PATH, 'password');
validatePasswordMap.set(RESET_PATH, 'new_password');
return validatePasswordMap;
}
const formData = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
new_password: this.state.new_password,
confirm_password: this.state.confirm_password,
}

doSubmit = (event) => {
const args = {
event: event,
path: this.props.path,
message_key: 'form_message',
component: this,
matchPasswordFields: this.state.matchPasswordsMap.get(this.props.path),
passwordToValidate: this.state.validatePasswordMap.get(this.props.path),
successMessage: this.getSuccessMessage(),
};
this.handleSubmit(args);
}
formData,
}

getSuccessMessage = () => {
return this.state.successMessageMap.get(this.props.path);
}
validateAccountForm(args).then((response) => {
console.log('validateAccountForm(): ', response);
if (response.status) {
if (this.props.path === RESET_PATH) {
// TODO - alert with success
console.log('path: ', this.props.path);
alert(response.message);
} else { // redirect to /profile with success for login/registration
console.log('route to profile');
route(`/profile`, true);
}
} else {
// TODO - alert failure to process
alert(response.message);
}
}).catch(function (error) {
alert(error);
});
};

componentWillUnmount = () => {
clearForms();
}

componentDidMount = () => {
if (this.props.path === RESET_PATH) {
setStateUserOrRedirectToSignIn(this);
}
// TODO - remove
console.log('AccountForm.componentDidMount()');
}

routeToRegister() {
route("/register", true);
}

render({path},{ form_message, user, name, email, password, new_password, confirm_password }) {
render({ path },{ name, email, password, new_password, confirm_password }) {

//DEFAULT TO LOGIN_PATH
let display =
<div class={style.display}>
<form class={style.form} onSubmit={this.doSubmit}>
<input class={style.formChild} id="email" name="email" type="text" placeholder='email address'
value={email} onInput={linkState(this, 'email')}/>
<form class={style.form} onSubmit={this.handleSubmit}>
<input class={style.formChild} id="email" name="email" type="email" placeholder='email address'
value={email} onInput={linkState(this, 'email')} required/>
<input class={style.formChild} id="password" name="password" type="password" placeholder='password'
value={password} onInput={linkState(this, 'password')}/>
value={password} onInput={linkState(this, 'password')} required/>
<div>
<button class={style.formChild}>LOGIN</button>
<div class={style.strike}>
<span>OR</span>
</div>
<button type="button" className={[style.formChild, style.regBtn].join(' ')}
onClick={this.routeToRegister}>CREATE AN ACCOUNT</button>
</div>
</form>
<div class={style.form}>
<div class={style.strike}>
<span>OR</span>
</div>
<button type="button" className={[style.formChild, style.regBtn].join(' ')}
onClick={this.routeToRegister}>CREATE AN ACCOUNT</button>
</div>
<p class={style.link2}><a href="/forgot-password">forgot password?</a></p>
</div>;

if(path === REGISTER_PATH){
display =
<div class={style.display}>
<form class={style.form} onSubmit={this.doSubmit}>
<form class={style.form} onSubmit={this.handleSubmit}>
<input class={style.formChild} name="name" type="text" placeholder="firstname lastname"
value={name} onInput={linkState(this, 'name')} required/>
<input class={style.formChild} id="email" name="email" type="text" placeholder='email address'
value={email} onInput={linkState(this, 'email')}/>
<input class={style.formChild} id="email" name="email" type="email" placeholder='email address'
value={email} onInput={linkState(this, 'email')} required/>
<input class={style.formChild} id="password" name="password" type="password" placeholder='password'
value={password} onInput={linkState(this, 'password')}/>
value={password} onInput={linkState(this, 'password')} required/>
<input class={style.formChild} name="confirm_password" type="password" placeholder="confirm password"
value={confirm_password} onInput={linkState(this, 'confirm_password')} required/>
<button class={style.formChild}>SUBMIT</button>
Expand All @@ -114,15 +113,15 @@ export default class AccountForm extends Component {
if(path === RESET_PATH){
display =
<div>
<form class={style.form} onSubmit={this.doSubmit}>
<form class={style.form} onSubmit={this.handleSubmit}>
<p>To change user info:</p>
<input class={style.formChildReset} name="name" type="text" placeholder="Enter new name"
value={name} onInput={linkState(this, 'name')}/>
<input class={style.formChildReset} id="email" name="email" type="email" placeholder='Enter new email address'
value={email} onInput={linkState(this, 'email')}/>
<button class={style.formChildReset}>Update Info</button>
</form>
<form class={style.form} onSubmit={this.doSubmit}>
<form class={style.form} onSubmit={this.handleSubmit}>
<p>To change password:</p>
<input class={style.formChildReset} id="password" name="password" type="password" placeholder="Enter current password"
value={password} onInput={linkState(this, 'password')} required/>
Expand All @@ -137,7 +136,6 @@ export default class AccountForm extends Component {
return (
<div class={style.inherit}>
<img class={style.logo} src='../../assets/icons/leaflet/SVG/darkLogo.svg' alt='Navi logo' />
<div>{form_message}</div>
{display}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/ProfileCard/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {h, Component} from 'preact';
import style from './style';
import {setStateUserOrRedirectToSignIn} from "../../js/utilities";
import {setStateUserOrRedirectToSignIn} from "../../js/validate-account-form";

export default class ProfileCard extends Component {
constructor() {
Expand Down
15 changes: 0 additions & 15 deletions client/src/js/server-requests-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,3 @@ export const makeRequest = (method='GET', baseEndPoint, endPointAddon='', bodyDa

return axios.request(config);
}


/*
Incomplete Function...
import { url } from 'inspector';
const AXIOS_INSTANCE = axios.create({
baseURL: API_SERVER
});
exports.postAutocomplete = (input='') => { //ERR: url is read only
// return AXIOS_INSTANCE.post(url=BASE_ENDPOINTS.autocomplete, {input});
}
*/
129 changes: 0 additions & 129 deletions client/src/js/utilities.js

This file was deleted.

Loading

0 comments on commit 8b53674

Please sign in to comment.