mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-06 05:04:35 +08:00
added frontend validations
This commit is contained in:
parent
39025769ec
commit
1a7f8fc857
7 changed files with 175 additions and 182 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,}))$/;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue