added frontend validations

This commit is contained in:
zmagod 2017-09-22 16:59:38 +02:00
parent 39025769ec
commit 1a7f8fc857
7 changed files with 175 additions and 182 deletions

View file

@ -44,121 +44,23 @@ module ClientApi
def update
binding.pry
respond_to do |format|
if current_user.update(user_params)
sign_in(current_user, bypass: true)
format.json { render json: {}, status: :ok }
else
format.json {
render json: { message: current_user.errors.full_messages },
status: :unprocessable_entity
}
end
end
end
# def change_password
# user = User.find(current_user.id)
# is_saved = user.update(user_params)
#
# if is_saved
# bypass_sign_in(user)
# res = "success"
# else
# res = "could not change password"
# end
#
# respond_to do |format|
# if is_saved
# format.json { render json: { msg: res} }
# else
# format.json { render json: { msg: res}, status: 422 }
# end
# end
# end
#
# def change_assignements_notification
# change_notification(:assignments_notification, params)
# end
#
# def change_assignements_notification_email
# change_notification(:assignments_notification_email, params)
# end
#
# def change_recent_notification
# change_notification(:recent_notification, params)
# end
#
# def change_recent_notification_email
# change_notification(:recent_notification_email, params)
# end
#
# def change_system_notification_email
# change_notification(:system_message_notification_email, params)
# end
#
# def change_timezone
# user = current_user
# errors = { timezone_errors: [] }
# user.time_zone = params['timezone']
#
# timezone = if user.save
# user.time_zone
# else
# msg = 'You need to select valid TimeZone.'
# user.reload.time_zone
# errors[:timezone_errors] << msg
# end
#
# respond_to do |format|
# format.json { render json: { timezone: timezone, errors: errors}}
# end
# end
#
# def change_email
# user = current_user
# current_email = current_user.email
# errors = { current_password_email_field: []}
#
# if user.valid_password? params['passwrd']
# user.email = params['email']
# saved_email = if user.save
# user.email
# else
# user.reload.email
# end
# else
# errors[:current_password_email_field] << 'Wrong password.'
# end
#
# respond_to do |format|
# resp = { email: saved_email || current_email, errors: errors }
# format.json { render json: resp }
# end
# end
#
# def change_full_name
# user = current_user
# user.name = params['fullName']
# saved_name = if user.save
# user.name
# else
# user.reload.name
# end
#
# respond_to do |format|
# resp = { fullName: saved_name, errors: user.errors.messages }
# format.json { render json: resp }
# end
# end
#
# def change_initials
# user = current_user
# user.initials = params['initials']
# saved_initials = if user.save
# user.initials
# else
# user.reload.initials
# end
#
# respond_to do |format|
# format.json { render json: { initials: saved_initials } }
# end
# end
private
def user_params
params.require(:user).permit(:password)
params.require(:user).permit(:password, :initials, :email, :full_name)
end
def change_notification(dinamic_param, params)

View file

@ -1,4 +1,7 @@
export const ENTER_KEY_CODE = 13;
export const NAME_MIN_LENGTH = 2;
export const USER_INITIALS_MAX_LENGTH = 4;
export const PASSWORD_MIN_LENGTH = 8;
export const PASSWORD_MAX_LENGTH = 72;
export const NAME_MAX_LENGTH = 255;
export const TEXT_MAX_LENGTH = 10000;

View file

@ -1,3 +1,4 @@
export const ASSIGNMENT_NOTIFICATION = "ASSIGNMENT";
export const RECENT_NOTIFICATION = "RECENT_NOTIFICATION";
export const SYSTEM_NOTIFICATION = "SYSTEM_NOTIFICATION";
export const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

View file

@ -1,12 +1,29 @@
import React, { Component } from "react";
import { string, func } from "prop-types";
import _ from "lodash";
import styled from "styled-components";
import { FormattedMessage } from "react-intl";
import { FormGroup, FormControl, ControlLabel, Button } from "react-bootstrap";
import {
FormGroup,
FormControl,
ControlLabel,
Button,
HelpBlock
} from "react-bootstrap";
import { updateUser } from "../../../services/api/users_api";
import { BORDER_LIGHT_COLOR } from "../../../config/constants/colors";
import { ENTER_KEY_CODE } from "../../../config/constants/numeric";
import {
BORDER_LIGHT_COLOR,
COLOR_APPLE_BLOSSOM
} from "../../../config/constants/colors";
import {
ENTER_KEY_CODE,
USER_INITIALS_MAX_LENGTH,
NAME_MAX_LENGTH,
PASSWORD_MAX_LENGTH,
PASSWORD_MIN_LENGTH
} from "../../../config/constants/numeric";
import { EMAIL_REGEX } from "../../../config/constants/strings";
const StyledInputEnabled = styled.div`
border: 1px solid ${BORDER_LIGHT_COLOR};
@ -18,92 +35,174 @@ const StyledInputEnabled = styled.div`
}
`;
const StyledHelpBlock = styled(HelpBlock)`color: ${COLOR_APPLE_BLOSSOM};`;
const ErrorMsg = styled.div`color: red;`;
class InputEnabled extends Component {
constructor(props) {
super(props);
if (props.inputType === "password") {
this.state = {
value: "",
value2: ""
};
} else {
this.state = {
value: this.props.inputValue,
errorMessage: ""
};
}
this.state = {
value: this.props.inputValue,
password_confirmation: "",
errorMessage: ""
};
this.handleChange = this.handleChange.bind(this);
this.handleChange2 = this.handleChange2.bind(this);
this.handlePasswordConfirmation = this.handlePasswordConfirmation.bind(
this
);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.confirmationField = this.confirmationField.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.getValidationState = this.getValidationState.bind(this);
this.handleFullNameValidation = this.handleFullNameValidation.bind(this);
this.handleEmailValidation = this.handleEmailValidation.bind(this);
this.handleInitialsValidation = this.handleInitialsValidation.bind(this);
this.handlePasswordConfirmationValidation = this.handlePasswordConfirmationValidation.bind(
this
);
}
getValidationState() {
return this.state.errorMessage.length > 0 ? "error" : null;
}
handleKeyPress(event) {
if (event.charCode === ENTER_KEY_CODE) {
event.preventDefault();
this.handleSubmit(event)
this.handleSubmit(event);
}
}
handleChange(event) {
this.setState({ value: event.target.value });
switch (this.props.dataField) {
case "full_name":
this.handleFullNameValidation(event);
break;
case "email":
this.handleEmailValidation(event);
break;
case "initials":
this.handleInitialsValidation(event);
break;
case "password":
this.handlePasswordValidation(event);
break;
default:
this.setState({ value: event.target.value, errorMessage: "" });
}
}
handleChange2(event) {
this.setState({ value2: event.target.value });
handlePasswordConfirmation(event) {
const { value } = event.target;
if (value.length === 0) {
this.setState({ password_confirmation: value, errorMessage: "Banana" });
}
this.setState({ password_confirmation: value });
}
handleFullNameValidation(event) {
const { value } = event.target;
if (value.length > NAME_MAX_LENGTH) {
this.setState({ value, errorMessage: "Banana" });
} else if (value.length === 0) {
this.setState({ value, errorMessage: "Banana" });
} else {
this.setState({ value, errorMessage: "" });
}
}
handleEmailValidation(event) {
const { value } = event.target;
if (!EMAIL_REGEX.test(value)) {
this.setState({ value, errorMessage: "Banana" });
} else if (value.length === 0) {
this.setState({ value, errorMessage: "Banana" });
} else {
this.setState({ value, errorMessage: "" });
}
}
handleInitialsValidation(event) {
const { value } = event.target;
if (value.length > USER_INITIALS_MAX_LENGTH) {
this.setState({ value, errorMessage: "Banana" });
} else if (value.length === 0) {
this.setState({ value, errorMessage: "Banana" });
} else {
this.setState({ value, errorMessage: "" });
}
}
handlePasswordValidation(event) {
const { value } = event.target;
if (value.length > PASSWORD_MAX_LENGTH) {
this.setState({ value, errorMessage: "Banana" });
} else if (value.length < PASSWORD_MIN_LENGTH) {
this.setState({ value, errorMessage: "Banana" });
} else {
this.setState({ value, errorMessage: "" });
}
}
handlePasswordConfirmationValidation(event) {
const { value } = event.target;
if (value.length !== this.state.value) {
this.setState({ value, errorMessage: "Banana" });
} else {
this.setState({ value, errorMessage: "" });
}
}
handleSubmit(event) {
event.preventDefault();
updateUser({[this.props.dataField]: this.state.value })
const { dataField } = this.props;
let params = { [dataField]: this.state.value };
if (dataField === "email" || dataField === "password") {
params = _.merge(params, {
password_confirmation: this.state.password_confirmation
});
}
updateUser(params)
.then(() => {
this.props.reloadInfo();
this.props.disableEdit();
})
.catch(error => {
console.log(error);
.catch(({ response }) => {
this.setState({ errorMessage: response.data.message.toString() });
});
}
confirmationField() {
let inputs;
const type = this.props.inputType;
if (type === "email" || type === "password") {
inputs = (
if (type === "email") {
return (
<div>
<p>
Current password (we need your current password to confirm your
changes)
</p>
<FormControl type="password" />
<FormControl
type="password"
value={this.state.password_confirmation}
onChange={this.handlePasswordConfirmation}
/>
</div>
);
}
return inputs;
}
errorMsg() {
return this.state.value !== this.state.value2 ? (
<ErrorMsg>Passwords do not match!</ErrorMsg>
) : (
""
);
return "";
}
inputField() {
let input;
if (this.props.inputType === "password") {
input = (
const { inputType } = this.props;
if (inputType === "password") {
return (
<div>
<FormControl
type={this.props.inputType}
type={inputType}
value={this.state.value}
onChange={this.handleChange}
onKeyPress={this.handleKeyPress}
@ -111,40 +210,37 @@ class InputEnabled extends Component {
/>
<p>New password confirmation</p>
<FormControl
type={this.props.inputType}
value={this.state.value2}
onChange={this.handleChange2}
type={inputType}
value={this.state.password_confirmation}
onChange={this.handlePasswordConfirmationValidation}
/>
{this.errorMsg()}
</div>
);
} else {
input = (
<FormControl
type={this.props.inputType}
value={this.state.value}
onChange={this.handleChange}
onKeyPress={this.handleKeyPress}
autoFocus
/>
);
}
return input;
return (
<FormControl
type={this.props.inputType}
value={this.state.value}
onChange={this.handleChange}
onKeyPress={this.handleKeyPress}
autoFocus
/>
);
}
render() {
return (
<StyledInputEnabled>
<form onSubmit={this.handleSubmit}>
<FormGroup>
<FormGroup validationState={this.getValidationState()}>
<h4>
<FormattedMessage id="settings_page.change" />{" "}
<FormattedMessage id="settings_page.change" />
<FormattedMessage id={this.props.labelTitle} />
</h4>
{this.confirmationField()}
<ControlLabel>{this.props.labelValue}</ControlLabel>
{this.inputField()}
{this.confirmationField()}
<StyledHelpBlock>{this.state.errorMessage}</StyledHelpBlock>
<Button bsStyle="primary" onClick={this.props.disableEdit}>
<FormattedMessage id="general.cancel" />
</Button>

View file

@ -9,7 +9,7 @@ import {
SETTINGS_TEAMS_ROUTE,
SETTINGS_TEAM_ROUTE,
SETTINGS_ACCOUNT_PROFILE,
SETTINGS_ACCOUNT_PREFERENCES
SETTINGS_ACCOUNT_PREFERENCES,
SETTINGS_NEW_TEAM_ROUTE
} from "../../config/routes";

View file

@ -6,12 +6,3 @@ export const axiosInstance = axios.create({
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content
}
});
// handles unsuccessful responses
export class ResponseError extends Error {
constructor(response = "", ...args) {
super(...args);
this.response = response;
}
}

View file

@ -1,4 +1,4 @@
import { axiosInstance, ResponseError } from "./config";
import { axiosInstance } from "./config";
import { USER_PROFILE_INFO, UPDATE_USER_PATH } from "./endpoints";
export const getUserProfileInfo = () => {
@ -8,5 +8,5 @@ export const getUserProfileInfo = () => {
export const updateUser = data => {
return axiosInstance
.post(UPDATE_USER_PATH, { user: data })
.then(({ data }) => data.user);
.then(({ data }) => data.user)
};