mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-08 14:15:35 +08:00
fixed profile info inputs
This commit is contained in:
parent
c636ca4276
commit
ed2beefc08
17 changed files with 344 additions and 506 deletions
2
.babelrc
2
.babelrc
|
@ -5,7 +5,7 @@
|
||||||
{
|
{
|
||||||
"modules": false,
|
"modules": false,
|
||||||
"targets": {
|
"targets": {
|
||||||
"browsers": "> 1%",
|
"browsers": ["last 2 versions"],
|
||||||
"uglify": true
|
"uglify": true
|
||||||
},
|
},
|
||||||
"useBuiltIns": true
|
"useBuiltIns": true
|
||||||
|
|
|
@ -42,114 +42,118 @@ module ClientApi
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_password
|
def update
|
||||||
user = User.find(current_user.id)
|
binding.pry
|
||||||
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
|
end
|
||||||
|
|
||||||
def change_assignements_notification
|
# def change_password
|
||||||
change_notification(:assignments_notification, params)
|
# user = User.find(current_user.id)
|
||||||
end
|
# is_saved = user.update(user_params)
|
||||||
|
#
|
||||||
def change_assignements_notification_email
|
# if is_saved
|
||||||
change_notification(:assignments_notification_email, params)
|
# bypass_sign_in(user)
|
||||||
end
|
# res = "success"
|
||||||
|
# else
|
||||||
def change_recent_notification
|
# res = "could not change password"
|
||||||
change_notification(:recent_notification, params)
|
# end
|
||||||
end
|
#
|
||||||
|
# respond_to do |format|
|
||||||
def change_recent_notification_email
|
# if is_saved
|
||||||
change_notification(:recent_notification_email, params)
|
# format.json { render json: { msg: res} }
|
||||||
end
|
# else
|
||||||
|
# format.json { render json: { msg: res}, status: 422 }
|
||||||
def change_system_notification_email
|
# end
|
||||||
change_notification(:system_message_notification_email, params)
|
# end
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def change_timezone
|
# def change_assignements_notification
|
||||||
user = current_user
|
# change_notification(:assignments_notification, params)
|
||||||
errors = { timezone_errors: [] }
|
# end
|
||||||
user.time_zone = params['timezone']
|
#
|
||||||
|
# def change_assignements_notification_email
|
||||||
timezone = if user.save
|
# change_notification(:assignments_notification_email, params)
|
||||||
user.time_zone
|
# end
|
||||||
else
|
#
|
||||||
msg = 'You need to select valid TimeZone.'
|
# def change_recent_notification
|
||||||
user.reload.time_zone
|
# change_notification(:recent_notification, params)
|
||||||
errors[:timezone_errors] << msg
|
# end
|
||||||
end
|
#
|
||||||
|
# def change_recent_notification_email
|
||||||
respond_to do |format|
|
# change_notification(:recent_notification_email, params)
|
||||||
format.json { render json: { timezone: timezone, errors: errors}}
|
# end
|
||||||
end
|
#
|
||||||
end
|
# def change_system_notification_email
|
||||||
|
# change_notification(:system_message_notification_email, params)
|
||||||
def change_email
|
# end
|
||||||
user = current_user
|
#
|
||||||
current_email = current_user.email
|
# def change_timezone
|
||||||
errors = { current_password_email_field: []}
|
# user = current_user
|
||||||
|
# errors = { timezone_errors: [] }
|
||||||
if user.valid_password? params['passwrd']
|
# user.time_zone = params['timezone']
|
||||||
user.email = params['email']
|
#
|
||||||
saved_email = if user.save
|
# timezone = if user.save
|
||||||
user.email
|
# user.time_zone
|
||||||
else
|
# else
|
||||||
user.reload.email
|
# msg = 'You need to select valid TimeZone.'
|
||||||
end
|
# user.reload.time_zone
|
||||||
else
|
# errors[:timezone_errors] << msg
|
||||||
errors[:current_password_email_field] << 'Wrong password.'
|
# end
|
||||||
end
|
#
|
||||||
|
# respond_to do |format|
|
||||||
respond_to do |format|
|
# format.json { render json: { timezone: timezone, errors: errors}}
|
||||||
resp = { email: saved_email || current_email, errors: errors }
|
# end
|
||||||
format.json { render json: resp }
|
# end
|
||||||
end
|
#
|
||||||
end
|
# def change_email
|
||||||
|
# user = current_user
|
||||||
def change_full_name
|
# current_email = current_user.email
|
||||||
user = current_user
|
# errors = { current_password_email_field: []}
|
||||||
user.name = params['fullName']
|
#
|
||||||
saved_name = if user.save
|
# if user.valid_password? params['passwrd']
|
||||||
user.name
|
# user.email = params['email']
|
||||||
else
|
# saved_email = if user.save
|
||||||
user.reload.name
|
# user.email
|
||||||
end
|
# else
|
||||||
|
# user.reload.email
|
||||||
respond_to do |format|
|
# end
|
||||||
resp = { fullName: saved_name, errors: user.errors.messages }
|
# else
|
||||||
format.json { render json: resp }
|
# errors[:current_password_email_field] << 'Wrong password.'
|
||||||
end
|
# end
|
||||||
end
|
#
|
||||||
|
# respond_to do |format|
|
||||||
def change_initials
|
# resp = { email: saved_email || current_email, errors: errors }
|
||||||
user = current_user
|
# format.json { render json: resp }
|
||||||
user.initials = params['initials']
|
# end
|
||||||
saved_initials = if user.save
|
# end
|
||||||
user.initials
|
#
|
||||||
else
|
# def change_full_name
|
||||||
user.reload.initials
|
# user = current_user
|
||||||
end
|
# user.name = params['fullName']
|
||||||
|
# saved_name = if user.save
|
||||||
respond_to do |format|
|
# user.name
|
||||||
format.json { render json: { initials: saved_initials } }
|
# else
|
||||||
end
|
# user.reload.name
|
||||||
end
|
# 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
|
private
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import axios from "../../config/axios";
|
import axios from "../../config/axios";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CHANGE_USER_FULL_NAME_PATH,
|
|
||||||
CURRENT_USER_PATH,
|
CURRENT_USER_PATH,
|
||||||
CHANGE_USER_INITIALS_PATH,
|
|
||||||
CHANGE_USER_EMAIL_PATH,
|
|
||||||
CHANGE_USER_PASSWORD_PATH,
|
|
||||||
CHANGE_USER_TIMEZONE_PATH,
|
CHANGE_USER_TIMEZONE_PATH,
|
||||||
CHANGE_USER_ASSIGNEMENTS_NOTIFICATION_PATH,
|
CHANGE_USER_ASSIGNEMENTS_NOTIFICATION_PATH,
|
||||||
CHANGE_USER_ASSIGNMENTS_NOTIFICATION_EMAIL_PATH,
|
CHANGE_USER_ASSIGNMENTS_NOTIFICATION_EMAIL_PATH,
|
||||||
|
@ -16,11 +12,6 @@ import {
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SET_CURRENT_USER,
|
SET_CURRENT_USER,
|
||||||
CHANGE_CURRENT_USER_FULL_NAME,
|
|
||||||
CHANGE_CURRENT_USER_INITIALS,
|
|
||||||
CHANGE_CURRENT_USER_EMAIL,
|
|
||||||
CHANGE_CURRENT_USER_PASSWORD,
|
|
||||||
CHANGE_CURRENT_USER_AVATAR,
|
|
||||||
CHANGE_CURRENT_USER_TIMEZONE,
|
CHANGE_CURRENT_USER_TIMEZONE,
|
||||||
CHANGE_ASSIGNMENTS_NOTIFICATION,
|
CHANGE_ASSIGNMENTS_NOTIFICATION,
|
||||||
CHANGE_ASSIGNMENTS_NOTIFICATION_EMAIL,
|
CHANGE_ASSIGNMENTS_NOTIFICATION_EMAIL,
|
||||||
|
@ -49,99 +40,6 @@ export function getCurrentUser() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveFullName({ fullName }) {
|
|
||||||
return {
|
|
||||||
type: CHANGE_CURRENT_USER_FULL_NAME,
|
|
||||||
payload: fullName
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function changeFullName(name) {
|
|
||||||
return dispatch => {
|
|
||||||
axios
|
|
||||||
.post(CHANGE_USER_FULL_NAME_PATH, {
|
|
||||||
withCredentials: true,
|
|
||||||
fullName: name
|
|
||||||
})
|
|
||||||
.then(({ data }) => {
|
|
||||||
dispatch(saveFullName(data));
|
|
||||||
})
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function saveInitials({ initials }) {
|
|
||||||
return {
|
|
||||||
type: CHANGE_CURRENT_USER_INITIALS,
|
|
||||||
payload: initials
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function changeInitials(initials) {
|
|
||||||
return dispatch => {
|
|
||||||
axios
|
|
||||||
.post(CHANGE_USER_INITIALS_PATH, {
|
|
||||||
withCredentials: true,
|
|
||||||
initials
|
|
||||||
})
|
|
||||||
.then(({ data }) => {
|
|
||||||
dispatch(saveInitials(data));
|
|
||||||
})
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function saveEmail({ email }) {
|
|
||||||
return {
|
|
||||||
type: CHANGE_CURRENT_USER_EMAIL,
|
|
||||||
payload: email
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function changeEmail(email) {
|
|
||||||
return dispatch => {
|
|
||||||
axios
|
|
||||||
.post(CHANGE_USER_EMAIL_PATH, {
|
|
||||||
withCredentials: true,
|
|
||||||
email
|
|
||||||
})
|
|
||||||
.then(({ data }) => {
|
|
||||||
dispatch(saveEmail(data));
|
|
||||||
})
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function savePassword(password) {
|
|
||||||
return {
|
|
||||||
type: CHANGE_CURRENT_USER_PASSWORD,
|
|
||||||
payload: password
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function changePassword(password) {
|
|
||||||
return dispatch => {
|
|
||||||
axios
|
|
||||||
.post(CHANGE_USER_PASSWORD_PATH, {
|
|
||||||
user: {
|
|
||||||
withCredentials: true,
|
|
||||||
password
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(({ data }) => {
|
|
||||||
dispatch(savePassword(data));
|
|
||||||
})
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function changeAvatar(avatarSrc) {
|
|
||||||
return {
|
|
||||||
type: CHANGE_CURRENT_USER_AVATAR,
|
|
||||||
payload: avatarSrc
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function saveTimezone({ timezone }) {
|
export function saveTimezone({ timezone }) {
|
||||||
return {
|
return {
|
||||||
type: CHANGE_CURRENT_USER_TIMEZONE,
|
type: CHANGE_CURRENT_USER_TIMEZONE,
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
import {
|
import {
|
||||||
SET_CURRENT_USER,
|
SET_CURRENT_USER,
|
||||||
CHANGE_CURRENT_USER_FULL_NAME,
|
|
||||||
CHANGE_CURRENT_USER_INITIALS,
|
|
||||||
CHANGE_CURRENT_USER_EMAIL,
|
|
||||||
CHANGE_CURRENT_USER_PASSWORD,
|
|
||||||
CHANGE_CURRENT_USER_AVATAR,
|
|
||||||
CHANGE_CURRENT_USER_TIMEZONE,
|
CHANGE_CURRENT_USER_TIMEZONE,
|
||||||
CHANGE_ASSIGNMENTS_NOTIFICATION,
|
CHANGE_ASSIGNMENTS_NOTIFICATION,
|
||||||
CHANGE_ASSIGNMENTS_NOTIFICATION_EMAIL,
|
CHANGE_ASSIGNMENTS_NOTIFICATION_EMAIL,
|
||||||
|
@ -33,18 +28,6 @@ export function currentUser(
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case SET_CURRENT_USER:
|
case SET_CURRENT_USER:
|
||||||
return Object.assign({}, state, action.payload);
|
return Object.assign({}, state, action.payload);
|
||||||
case CHANGE_CURRENT_USER_FULL_NAME:
|
|
||||||
return Object.assign({}, state, { fullName: action.payload });
|
|
||||||
case CHANGE_CURRENT_USER_INITIALS:
|
|
||||||
return Object.assign({}, state, { initials: action.payload });
|
|
||||||
case CHANGE_CURRENT_USER_EMAIL:
|
|
||||||
return Object.assign({}, state, { email: action.payload });
|
|
||||||
case CHANGE_CURRENT_USER_PASSWORD:
|
|
||||||
console.log("handle sending password to the server");
|
|
||||||
// return Object.assign({}, state, { password: action.payload });
|
|
||||||
return state;
|
|
||||||
case CHANGE_CURRENT_USER_AVATAR:
|
|
||||||
return Object.assign({}, state, { avatar: action.payload });
|
|
||||||
case CHANGE_CURRENT_USER_TIMEZONE:
|
case CHANGE_CURRENT_USER_TIMEZONE:
|
||||||
return Object.assign({}, state, { timezone: action.payload });
|
return Object.assign({}, state, { timezone: action.payload });
|
||||||
case CHANGE_ASSIGNMENTS_NOTIFICATION:
|
case CHANGE_ASSIGNMENTS_NOTIFICATION:
|
||||||
|
|
|
@ -9,11 +9,6 @@ export const DESTROY_GLOBAL_ACTIVITIES_DATA = "DESTROY_GLOBAL_ACTIVITIES_DATA";
|
||||||
|
|
||||||
// users
|
// users
|
||||||
export const SET_CURRENT_USER = "SET_CURRENT_USER";
|
export const SET_CURRENT_USER = "SET_CURRENT_USER";
|
||||||
export const CHANGE_CURRENT_USER_FULL_NAME = "CHANGE_CURRENT_USER_FULL_NAME";
|
|
||||||
export const CHANGE_CURRENT_USER_INITIALS = "CHANGE_CURRENT_USER_INITIALS";
|
|
||||||
export const CHANGE_CURRENT_USER_EMAIL = "CHANGE_CURRENT_USER_EMAIL";
|
|
||||||
export const CHANGE_CURRENT_USER_PASSWORD = "CHANGE_CURRENT_USER_PASSWORD";
|
|
||||||
export const CHANGE_CURRENT_USER_AVATAR = "CHANGE_CURRENT_USER_AVATAR";
|
|
||||||
export const CHANGE_CURRENT_USER_TIMEZONE = "CHANGE_CURRENT_USER_TIMEZONE";
|
export const CHANGE_CURRENT_USER_TIMEZONE = "CHANGE_CURRENT_USER_TIMEZONE";
|
||||||
export const CHANGE_ASSIGNMENTS_NOTIFICATION =
|
export const CHANGE_ASSIGNMENTS_NOTIFICATION =
|
||||||
"CHANGE_ASSIGNMENTS_NOTIFICATION";
|
"CHANGE_ASSIGNMENTS_NOTIFICATION";
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import PropTypes from "prop-types";
|
import { string, func } from "prop-types";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import { FormGroup, FormControl, ControlLabel, Button } from "react-bootstrap";
|
import { FormGroup, FormControl, ControlLabel, Button } from "react-bootstrap";
|
||||||
|
import { updateUser } from "../../../services/api/users_api";
|
||||||
|
|
||||||
import { BORDER_LIGHT_COLOR } from "../../../config/constants/colors";
|
import { BORDER_LIGHT_COLOR } from "../../../config/constants/colors";
|
||||||
import { ENTER_KEY_CODE } from "../../../config/constants/numeric";
|
import { ENTER_KEY_CODE } from "../../../config/constants/numeric";
|
||||||
|
@ -30,20 +31,21 @@ class InputEnabled extends Component {
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
this.state = {
|
this.state = {
|
||||||
value: this.props.inputValue
|
value: this.props.inputValue,
|
||||||
|
errorMessage: ""
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleChange = this.handleChange.bind(this);
|
this.handleChange = this.handleChange.bind(this);
|
||||||
this.handleChange2 = this.handleChange2.bind(this);
|
this.handleChange2 = this.handleChange2.bind(this);
|
||||||
this.handleUpdate = this.handleUpdate.bind(this);
|
|
||||||
this.handleKeyPress = this.handleKeyPress.bind(this);
|
this.handleKeyPress = this.handleKeyPress.bind(this);
|
||||||
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyPress(event) {
|
handleKeyPress(event) {
|
||||||
if (event.charCode === ENTER_KEY_CODE) {
|
if (event.charCode === ENTER_KEY_CODE) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.handleUpdate();
|
this.handleSubmit(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,11 +59,14 @@ class InputEnabled extends Component {
|
||||||
|
|
||||||
handleSubmit(event) {
|
handleSubmit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
updateUser({[this.props.dataField]: this.state.value })
|
||||||
|
.then(() => {
|
||||||
handleUpdate() {
|
this.props.reloadInfo();
|
||||||
this.props.saveData(this.state.value);
|
this.props.disableEdit();
|
||||||
this.props.disableEdit();
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmationField() {
|
confirmationField() {
|
||||||
|
@ -84,9 +89,11 @@ class InputEnabled extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
errorMsg() {
|
errorMsg() {
|
||||||
return this.state.value !== this.state.value2
|
return this.state.value !== this.state.value2 ? (
|
||||||
? <ErrorMsg>Passwords do not match!</ErrorMsg>
|
<ErrorMsg>Passwords do not match!</ErrorMsg>
|
||||||
: "";
|
) : (
|
||||||
|
""
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inputField() {
|
inputField() {
|
||||||
|
@ -136,14 +143,12 @@ class InputEnabled extends Component {
|
||||||
<FormattedMessage id={this.props.labelTitle} />
|
<FormattedMessage id={this.props.labelTitle} />
|
||||||
</h4>
|
</h4>
|
||||||
{this.confirmationField()}
|
{this.confirmationField()}
|
||||||
<ControlLabel>
|
<ControlLabel>{this.props.labelValue}</ControlLabel>
|
||||||
{this.props.labelValue}
|
|
||||||
</ControlLabel>
|
|
||||||
{this.inputField()}
|
{this.inputField()}
|
||||||
<Button bsStyle="primary" onClick={this.props.disableEdit}>
|
<Button bsStyle="primary" onClick={this.props.disableEdit}>
|
||||||
<FormattedMessage id="general.cancel" />
|
<FormattedMessage id="general.cancel" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button bsStyle="default" onClick={this.handleUpdate}>
|
<Button bsStyle="default" type="submit">
|
||||||
<FormattedMessage id="general.update" />
|
<FormattedMessage id="general.update" />
|
||||||
</Button>
|
</Button>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -154,12 +159,13 @@ class InputEnabled extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
InputEnabled.propTypes = {
|
InputEnabled.propTypes = {
|
||||||
inputType: PropTypes.string.isRequired,
|
inputType: string.isRequired,
|
||||||
labelValue: PropTypes.string.isRequired,
|
labelValue: string.isRequired,
|
||||||
inputValue: PropTypes.string.isRequired,
|
inputValue: string.isRequired,
|
||||||
disableEdit: PropTypes.func.isRequired,
|
disableEdit: func.isRequired,
|
||||||
saveData: PropTypes.func.isRequired,
|
reloadInfo: func.isRequired,
|
||||||
labelTitle: PropTypes.string.isRequired
|
labelTitle: string.isRequired,
|
||||||
|
dataField: string.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default InputEnabled;
|
export default InputEnabled;
|
||||||
|
|
|
@ -62,11 +62,12 @@ export default class SettingsPage extends Component {
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path={SETTINGS_PATH}
|
path={SETTINGS_PATH}
|
||||||
render={() =>
|
render={() => (
|
||||||
<Redirect
|
<Redirect
|
||||||
to={SETTINGS_ACCOUNT_PROFILE}
|
to={SETTINGS_ACCOUNT_PROFILE}
|
||||||
component={SettingsPreferences}
|
component={SettingsPreferences}
|
||||||
/>}
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route path={SETTINGS_TEAM_ROUTE} component={SettingsTeam} />
|
<Route path={SETTINGS_TEAM_ROUTE} component={SettingsTeam} />
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import PropTypes, { string } from "prop-types";
|
|
||||||
import styled from "styled-components";
|
|
||||||
import { FormattedMessage } from "react-intl";
|
|
||||||
|
|
||||||
import {
|
|
||||||
WHITE_COLOR,
|
|
||||||
DARK_GRAY_COLOR
|
|
||||||
} from "../../../../../config/constants/colors";
|
|
||||||
|
|
||||||
const AvatarWrapper = styled.div`
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
`;
|
|
||||||
const EditAvatar = styled.span`
|
|
||||||
color: ${WHITE_COLOR};
|
|
||||||
background-color: ${DARK_GRAY_COLOR};
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
opacity: 0.7;
|
|
||||||
padding: 5px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Avatar = props =>
|
|
||||||
<AvatarWrapper onClick={props.enableEdit}>
|
|
||||||
<img src={props.imgSource} alt="default avatar" />
|
|
||||||
<EditAvatar className="text-center">
|
|
||||||
<span className="glyphicon glyphicon-pencil" />
|
|
||||||
<FormattedMessage id="settings_page.edit_avatar" />
|
|
||||||
</EditAvatar>
|
|
||||||
</AvatarWrapper>;
|
|
||||||
|
|
||||||
Avatar.propTypes = {
|
|
||||||
imgSource: string.isRequired,
|
|
||||||
enableEdit: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Avatar;
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import PropTypes, { string } from "prop-types";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
|
import {
|
||||||
|
WHITE_COLOR,
|
||||||
|
DARK_GRAY_COLOR
|
||||||
|
} from "../../../../../config/constants/colors";
|
||||||
|
|
||||||
|
import InputEnabled from "../../../components/InputEnabled";
|
||||||
|
|
||||||
|
const AvatarWrapper = styled.div`
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
`;
|
||||||
|
const EditAvatar = styled.span`
|
||||||
|
color: ${WHITE_COLOR};
|
||||||
|
background-color: ${DARK_GRAY_COLOR};
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
opacity: 0.7;
|
||||||
|
padding: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
class AvatarInputField extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { disabled: true };
|
||||||
|
this.enableEdit = this.enableEdit.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
enableEdit() {
|
||||||
|
this.setState({ disabled: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.state.disabled) {
|
||||||
|
return (
|
||||||
|
<AvatarWrapper onClick={this.props.enableEdit}>
|
||||||
|
<img src={this.props.imgSource} alt="default avatar" />
|
||||||
|
<EditAvatar className="text-center">
|
||||||
|
<span className="glyphicon glyphicon-pencil" />
|
||||||
|
<FormattedMessage id="settings_page.edit_avatar" />
|
||||||
|
</EditAvatar>
|
||||||
|
</AvatarWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<InputEnabled
|
||||||
|
labelTitle="settings_page.avatar"
|
||||||
|
labelValue="Avatar"
|
||||||
|
inputType="file"
|
||||||
|
inputValue=""
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarInputField.propTypes = {
|
||||||
|
imgSource: string.isRequired,
|
||||||
|
enableEdit: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AvatarInputField;
|
|
@ -1,20 +1,11 @@
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { connect } from "react-redux";
|
import { func } from "prop-types";
|
||||||
import PropTypes from "prop-types";
|
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
import { getUserProfileInfo } from "../../../../../services/api/users_api";
|
||||||
|
|
||||||
import Avatar from "./Avatar";
|
import AvatarInputField from "./AvatarInputField";
|
||||||
import InputDisabled from "../../../components/InputDisabled";
|
import ProfileInputField from "./ProfileInputField";
|
||||||
import InputEnabled from "../../../components/InputEnabled";
|
|
||||||
|
|
||||||
import {
|
|
||||||
changeFullName,
|
|
||||||
changeInitials,
|
|
||||||
changeEmail,
|
|
||||||
changePassword,
|
|
||||||
changeAvatar
|
|
||||||
} from "../../../../../components/actions/UsersActions";
|
|
||||||
|
|
||||||
const AvatarLabel = styled.h4`
|
const AvatarLabel = styled.h4`
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
|
@ -32,171 +23,27 @@ class MyProfile extends Component {
|
||||||
initials: "",
|
initials: "",
|
||||||
email: "",
|
email: "",
|
||||||
timeZone: "",
|
timeZone: "",
|
||||||
newEmail: "",
|
newEmail: ""
|
||||||
isFullNameEditable: false,
|
|
||||||
areInitialsEditable: false,
|
|
||||||
isEmailEditable: false,
|
|
||||||
isPasswordEditable: false,
|
|
||||||
isAvatarEditable: false
|
|
||||||
};
|
};
|
||||||
|
this.loadInfo = this.loadInfo.bind(this)
|
||||||
this.toggleIsEditable = this.toggleIsEditable.bind(this);
|
|
||||||
this.getProfileInfo = this.getProfileInfo.bind(this);
|
|
||||||
this.setData = this.setData.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.getProfileInfo();
|
this.loadInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
setData({ data }) {
|
loadInfo() {
|
||||||
const user = data.user;
|
getUserProfileInfo()
|
||||||
|
.then(data => {
|
||||||
// TODO move this transformation to seperate method
|
const { fullName, initials, email, avatarThumb, timeZone } = data;
|
||||||
|
this.setState({ fullName, initials, email, avatarThumb, timeZone });
|
||||||
const newData = {
|
})
|
||||||
fullName: user.full_name,
|
.catch(error => {
|
||||||
initials: user.initials,
|
console.log(error);
|
||||||
email: user.email,
|
});
|
||||||
avatarThumb: user.avatar_thumb_path,
|
|
||||||
timeZone: user.time_zone
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setState(Object.assign({}, this.state, newData));
|
|
||||||
}
|
|
||||||
|
|
||||||
getProfileInfo() {
|
|
||||||
// axios
|
|
||||||
// .get("/client_api/users/profile_info")
|
|
||||||
// .then(response => this.setData(response))
|
|
||||||
// .catch(error => console.log(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleIsEditable(fieldNameEnabled) {
|
|
||||||
const editableState = this.state[fieldNameEnabled];
|
|
||||||
this.setState({ [fieldNameEnabled]: !editableState });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const areInitialsEditable = "areInitialsEditable";
|
|
||||||
const isFullNameEditable = "isFullNameEditable";
|
|
||||||
const isEmailEditable = "isEmailEditable";
|
|
||||||
const isPasswordEditable = "isPasswordEditable";
|
|
||||||
const isAvatarEditable = "isAvatarEditable";
|
|
||||||
let fullNameField;
|
|
||||||
let initialsField;
|
|
||||||
let emailField;
|
|
||||||
let passwordField;
|
|
||||||
let avatarField;
|
|
||||||
|
|
||||||
if (this.state.isAvatarEditable) {
|
|
||||||
avatarField = (
|
|
||||||
<InputEnabled
|
|
||||||
labelTitle="settings_page.avatar"
|
|
||||||
labelValue="Avatar"
|
|
||||||
inputType="file"
|
|
||||||
inputValue=""
|
|
||||||
disableEdit={() => this.toggleIsEditable(isAvatarEditable)}
|
|
||||||
saveData={avatarSrc => this.props.changeAvatar(avatarSrc)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
avatarField = (
|
|
||||||
<Avatar
|
|
||||||
imgSource={this.state.avatarThumb}
|
|
||||||
enableEdit={() => this.toggleIsEditable(isAvatarEditable)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.isPasswordEditable) {
|
|
||||||
passwordField = (
|
|
||||||
<InputEnabled
|
|
||||||
labelTitle="settings_page.change_password"
|
|
||||||
labelValue="Change password"
|
|
||||||
inputType="password"
|
|
||||||
inputValue=""
|
|
||||||
disableEdit={() => this.toggleIsEditable(isPasswordEditable)}
|
|
||||||
saveData={newPassword => this.props.changePassword(newPassword)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
passwordField = (
|
|
||||||
<InputDisabled
|
|
||||||
labelTitle="settings_page.change_password"
|
|
||||||
inputType="password"
|
|
||||||
inputValue=""
|
|
||||||
enableEdit={() => this.toggleIsEditable(isPasswordEditable)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.isEmailEditable) {
|
|
||||||
emailField = (
|
|
||||||
<InputEnabled
|
|
||||||
labelTitle="settings_page.new_email"
|
|
||||||
labelValue="New email"
|
|
||||||
inputType="email"
|
|
||||||
inputValue={this.state.email}
|
|
||||||
disableEdit={() => this.toggleIsEditable(isEmailEditable)}
|
|
||||||
saveData={newEmail => this.props.changeEmail(newEmail)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
emailField = (
|
|
||||||
<InputDisabled
|
|
||||||
labelTitle="settings_page.new_email"
|
|
||||||
inputValue={this.state.email}
|
|
||||||
inputType="email"
|
|
||||||
enableEdit={() => this.toggleIsEditable(isEmailEditable)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.areInitialsEditable) {
|
|
||||||
initialsField = (
|
|
||||||
<InputEnabled
|
|
||||||
labelTitle="settings_page.initials"
|
|
||||||
labelValue="Initials"
|
|
||||||
inputType="text"
|
|
||||||
inputValue={this.state.initials}
|
|
||||||
disableEdit={() => this.toggleIsEditable(areInitialsEditable)}
|
|
||||||
saveData={newName => this.props.changeInitials(newName)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
initialsField = (
|
|
||||||
<InputDisabled
|
|
||||||
labelTitle="settings_page.initials"
|
|
||||||
inputValue={this.state.initials}
|
|
||||||
inputType="text"
|
|
||||||
enableEdit={() => this.toggleIsEditable(areInitialsEditable)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.isFullNameEditable) {
|
|
||||||
fullNameField = (
|
|
||||||
<InputEnabled
|
|
||||||
labelTitle="settings_page.full_name"
|
|
||||||
labelValue="Full name"
|
|
||||||
inputType="text"
|
|
||||||
inputValue={this.state.fullName}
|
|
||||||
disableEdit={() => this.toggleIsEditable(isFullNameEditable)}
|
|
||||||
saveData={newName => this.props.changeFullName(newName)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
fullNameField = (
|
|
||||||
<InputDisabled
|
|
||||||
labelTitle="settings_page.full_name"
|
|
||||||
inputValue={this.state.fullName}
|
|
||||||
inputType="text"
|
|
||||||
enableEdit={() => this.toggleIsEditable(isFullNameEditable)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>
|
<h2>
|
||||||
|
@ -205,42 +52,45 @@ class MyProfile extends Component {
|
||||||
<AvatarLabel>
|
<AvatarLabel>
|
||||||
<FormattedMessage id="settings_page.avatar" />
|
<FormattedMessage id="settings_page.avatar" />
|
||||||
</AvatarLabel>
|
</AvatarLabel>
|
||||||
{avatarField}
|
<AvatarInputField imgSource={this.state.avatarThumb} />
|
||||||
{fullNameField}
|
|
||||||
{initialsField}
|
<ProfileInputField
|
||||||
{emailField}
|
value={this.state.fullName}
|
||||||
{passwordField}
|
inputType="text"
|
||||||
|
labelTitle="settings_page.full_name"
|
||||||
|
labelValue="Full name"
|
||||||
|
reloadInfo={this.loadInfo}
|
||||||
|
dataField="full_name"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ProfileInputField
|
||||||
|
value={this.state.initials}
|
||||||
|
inputType="text"
|
||||||
|
labelTitle="settings_page.initials"
|
||||||
|
labelValue="Initials"
|
||||||
|
reloadInfo={this.loadInfo}
|
||||||
|
dataField="initials"
|
||||||
|
/>
|
||||||
|
<ProfileInputField
|
||||||
|
value={this.state.email}
|
||||||
|
inputType="email"
|
||||||
|
labelTitle="settings_page.new_email"
|
||||||
|
labelValue="New email"
|
||||||
|
reloadInfo={this.loadInfo}
|
||||||
|
dataField="email"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ProfileInputField
|
||||||
|
value="********"
|
||||||
|
inputType="password"
|
||||||
|
labelTitle="settings_page.change_password"
|
||||||
|
labelValue="password"
|
||||||
|
reloadInfo={this.loadInfo}
|
||||||
|
dataField="password"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyProfile.propTypes = {
|
export default MyProfile;
|
||||||
email: PropTypes.string.isRequired,
|
|
||||||
changeFullName: PropTypes.func.isRequired,
|
|
||||||
changeInitials: PropTypes.func.isRequired,
|
|
||||||
changeEmail: PropTypes.func.isRequired,
|
|
||||||
changePassword: PropTypes.func.isRequired,
|
|
||||||
changeAvatar: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = state => state.current_user;
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
|
||||||
changeFullName(name) {
|
|
||||||
dispatch(changeFullName(name));
|
|
||||||
},
|
|
||||||
changeInitials(initials) {
|
|
||||||
dispatch(changeInitials(initials));
|
|
||||||
},
|
|
||||||
changeEmail(email) {
|
|
||||||
dispatch(changeEmail(email));
|
|
||||||
},
|
|
||||||
changePassword(password) {
|
|
||||||
dispatch(changePassword(password));
|
|
||||||
},
|
|
||||||
changeAvatar(avatarSrc) {
|
|
||||||
dispatch(changeAvatar(avatarSrc));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(MyProfile);
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import { string, func } from "prop-types";
|
||||||
|
|
||||||
|
import InputDisabled from "../../../components/InputDisabled";
|
||||||
|
import InputEnabled from "../../../components/InputEnabled";
|
||||||
|
|
||||||
|
class ProfileInputField extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { disabled: true };
|
||||||
|
this.toggleSate = this.toggleSate.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleSate() {
|
||||||
|
this.setState({ disabled: !this.state.disabled });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.state.disabled) {
|
||||||
|
return (
|
||||||
|
<InputDisabled
|
||||||
|
labelTitle={this.props.labelTitle}
|
||||||
|
inputValue={this.props.value}
|
||||||
|
inputType={this.props.inputType}
|
||||||
|
enableEdit={this.toggleSate}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<InputEnabled
|
||||||
|
labelTitle={this.props.labelTitle}
|
||||||
|
labelValue={this.props.labelValue}
|
||||||
|
inputType={this.props.inputType}
|
||||||
|
inputValue={this.props.value}
|
||||||
|
disableEdit={this.toggleSate}
|
||||||
|
reloadInfo={this.props.reloadInfo}
|
||||||
|
dataField={this.props.dataField}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileInputField.propTypes = {
|
||||||
|
value: string.isRequired,
|
||||||
|
inputType: string.isRequired,
|
||||||
|
labelTitle: string.isRequired,
|
||||||
|
labelValue: string.isRequired,
|
||||||
|
dataField: string.isRequired,
|
||||||
|
reloadInfo: func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProfileInputField;
|
|
@ -6,3 +6,12 @@ export const axiosInstance = axios.create({
|
||||||
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content
|
"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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ export const RECENT_NOTIFICATIONS_PATH = "/client_api/recent_notifications";
|
||||||
|
|
||||||
// users
|
// users
|
||||||
export const USER_PROFILE_INFO = "/client_api/users/profile_info";
|
export const USER_PROFILE_INFO = "/client_api/users/profile_info";
|
||||||
|
export const UPDATE_USER_PATH = "/client_api/users/update";
|
||||||
|
|
||||||
// info dropdown_title
|
// info dropdown_title
|
||||||
export const CUSTOMER_SUPPORT_LINK = "http://scinote.net/support";
|
export const CUSTOMER_SUPPORT_LINK = "http://scinote.net/support";
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { axiosInstance, ResponseError } from "./config";
|
||||||
|
import { USER_PROFILE_INFO, UPDATE_USER_PATH } from "./endpoints";
|
||||||
|
|
||||||
|
export const getUserProfileInfo = () => {
|
||||||
|
return axiosInstance.get(USER_PROFILE_INFO).then(({ data }) => data.user);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateUser = data => {
|
||||||
|
return axiosInstance
|
||||||
|
.post(UPDATE_USER_PATH, { user: data })
|
||||||
|
.then(({ data }) => data.user);
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
json.user do
|
json.user do
|
||||||
json.full_name user.full_name
|
json.fullName user.full_name
|
||||||
json.initials user.initials
|
json.initials user.initials
|
||||||
json.email user.email
|
json.email user.email
|
||||||
json.avatar_thumb_path avatar_path(user, :thumb)
|
json.avatarThumb avatar_path(user, :thumb)
|
||||||
json.time_zone user.time_zone
|
json.timeZone user.time_zone
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,7 +36,7 @@ Rails.application.routes.draw do
|
||||||
get '/profile_info', to: 'users#profile_info'
|
get '/profile_info', to: 'users#profile_info'
|
||||||
# get '/statistics_info', to: 'users#statistics_info'
|
# get '/statistics_info', to: 'users#statistics_info'
|
||||||
get '/preferences_info', to: 'users#preferences_info'
|
get '/preferences_info', to: 'users#preferences_info'
|
||||||
|
post '/update', to: 'users#update'
|
||||||
# delete '/leave_team', to: 'user_teams#leave_team'
|
# delete '/leave_team', to: 'user_teams#leave_team'
|
||||||
# post '/change_full_name', to: 'users#change_full_name'
|
# post '/change_full_name', to: 'users#change_full_name'
|
||||||
# post '/change_initials', to: 'users#change_initials'
|
# post '/change_initials', to: 'users#change_initials'
|
||||||
|
|
|
@ -4513,8 +4513,8 @@ preserve@^0.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
||||||
|
|
||||||
prettier@^1.5.3:
|
prettier@^1.5.3:
|
||||||
version "1.5.3"
|
version "1.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.5.3.tgz#59dadc683345ec6b88f88b94ed4ae7e1da394bfe"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.7.0.tgz#47481588f41f7c90f63938feb202ac82554e7150"
|
||||||
|
|
||||||
prettysize@^0.1.0:
|
prettysize@^0.1.0:
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
|
|
Loading…
Add table
Reference in a new issue