mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-04 20:25:22 +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,
|
||||
"targets": {
|
||||
"browsers": "> 1%",
|
||||
"browsers": ["last 2 versions"],
|
||||
"uglify": true
|
||||
},
|
||||
"useBuiltIns": true
|
||||
|
|
|
@ -42,114 +42,118 @@ module ClientApi
|
|||
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
|
||||
def update
|
||||
binding.pry
|
||||
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
|
||||
# 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
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import axios from "../../config/axios";
|
||||
|
||||
import {
|
||||
CHANGE_USER_FULL_NAME_PATH,
|
||||
CURRENT_USER_PATH,
|
||||
CHANGE_USER_INITIALS_PATH,
|
||||
CHANGE_USER_EMAIL_PATH,
|
||||
CHANGE_USER_PASSWORD_PATH,
|
||||
CHANGE_USER_TIMEZONE_PATH,
|
||||
CHANGE_USER_ASSIGNEMENTS_NOTIFICATION_PATH,
|
||||
CHANGE_USER_ASSIGNMENTS_NOTIFICATION_EMAIL_PATH,
|
||||
|
@ -16,11 +12,6 @@ import {
|
|||
|
||||
import {
|
||||
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_ASSIGNMENTS_NOTIFICATION,
|
||||
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 }) {
|
||||
return {
|
||||
type: CHANGE_CURRENT_USER_TIMEZONE,
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import {
|
||||
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_ASSIGNMENTS_NOTIFICATION,
|
||||
CHANGE_ASSIGNMENTS_NOTIFICATION_EMAIL,
|
||||
|
@ -33,18 +28,6 @@ export function currentUser(
|
|||
switch (action.type) {
|
||||
case SET_CURRENT_USER:
|
||||
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:
|
||||
return Object.assign({}, state, { timezone: action.payload });
|
||||
case CHANGE_ASSIGNMENTS_NOTIFICATION:
|
||||
|
|
|
@ -9,11 +9,6 @@ export const DESTROY_GLOBAL_ACTIVITIES_DATA = "DESTROY_GLOBAL_ACTIVITIES_DATA";
|
|||
|
||||
// users
|
||||
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_ASSIGNMENTS_NOTIFICATION =
|
||||
"CHANGE_ASSIGNMENTS_NOTIFICATION";
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { string, func } from "prop-types";
|
||||
import styled from "styled-components";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { FormGroup, FormControl, ControlLabel, Button } 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";
|
||||
|
@ -30,20 +31,21 @@ class InputEnabled extends Component {
|
|||
};
|
||||
} else {
|
||||
this.state = {
|
||||
value: this.props.inputValue
|
||||
value: this.props.inputValue,
|
||||
errorMessage: ""
|
||||
};
|
||||
}
|
||||
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleChange2 = this.handleChange2.bind(this);
|
||||
this.handleUpdate = this.handleUpdate.bind(this);
|
||||
this.handleKeyPress = this.handleKeyPress.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
}
|
||||
|
||||
handleKeyPress(event) {
|
||||
if (event.charCode === ENTER_KEY_CODE) {
|
||||
event.preventDefault();
|
||||
this.handleUpdate();
|
||||
this.handleSubmit(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,11 +59,14 @@ class InputEnabled extends Component {
|
|||
|
||||
handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
handleUpdate() {
|
||||
this.props.saveData(this.state.value);
|
||||
this.props.disableEdit();
|
||||
updateUser({[this.props.dataField]: this.state.value })
|
||||
.then(() => {
|
||||
this.props.reloadInfo();
|
||||
this.props.disableEdit();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
confirmationField() {
|
||||
|
@ -84,9 +89,11 @@ class InputEnabled extends Component {
|
|||
}
|
||||
|
||||
errorMsg() {
|
||||
return this.state.value !== this.state.value2
|
||||
? <ErrorMsg>Passwords do not match!</ErrorMsg>
|
||||
: "";
|
||||
return this.state.value !== this.state.value2 ? (
|
||||
<ErrorMsg>Passwords do not match!</ErrorMsg>
|
||||
) : (
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
inputField() {
|
||||
|
@ -136,14 +143,12 @@ class InputEnabled extends Component {
|
|||
<FormattedMessage id={this.props.labelTitle} />
|
||||
</h4>
|
||||
{this.confirmationField()}
|
||||
<ControlLabel>
|
||||
{this.props.labelValue}
|
||||
</ControlLabel>
|
||||
<ControlLabel>{this.props.labelValue}</ControlLabel>
|
||||
{this.inputField()}
|
||||
<Button bsStyle="primary" onClick={this.props.disableEdit}>
|
||||
<FormattedMessage id="general.cancel" />
|
||||
</Button>
|
||||
<Button bsStyle="default" onClick={this.handleUpdate}>
|
||||
<Button bsStyle="default" type="submit">
|
||||
<FormattedMessage id="general.update" />
|
||||
</Button>
|
||||
</FormGroup>
|
||||
|
@ -154,12 +159,13 @@ class InputEnabled extends Component {
|
|||
}
|
||||
|
||||
InputEnabled.propTypes = {
|
||||
inputType: PropTypes.string.isRequired,
|
||||
labelValue: PropTypes.string.isRequired,
|
||||
inputValue: PropTypes.string.isRequired,
|
||||
disableEdit: PropTypes.func.isRequired,
|
||||
saveData: PropTypes.func.isRequired,
|
||||
labelTitle: PropTypes.string.isRequired
|
||||
inputType: string.isRequired,
|
||||
labelValue: string.isRequired,
|
||||
inputValue: string.isRequired,
|
||||
disableEdit: func.isRequired,
|
||||
reloadInfo: func.isRequired,
|
||||
labelTitle: string.isRequired,
|
||||
dataField: string.isRequired
|
||||
};
|
||||
|
||||
export default InputEnabled;
|
||||
|
|
|
@ -62,11 +62,12 @@ export default class SettingsPage extends Component {
|
|||
<Route
|
||||
exact
|
||||
path={SETTINGS_PATH}
|
||||
render={() =>
|
||||
render={() => (
|
||||
<Redirect
|
||||
to={SETTINGS_ACCOUNT_PROFILE}
|
||||
component={SettingsPreferences}
|
||||
/>}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<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 { connect } from "react-redux";
|
||||
import PropTypes from "prop-types";
|
||||
import { func } from "prop-types";
|
||||
import styled from "styled-components";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { getUserProfileInfo } from "../../../../../services/api/users_api";
|
||||
|
||||
import Avatar from "./Avatar";
|
||||
import InputDisabled from "../../../components/InputDisabled";
|
||||
import InputEnabled from "../../../components/InputEnabled";
|
||||
|
||||
import {
|
||||
changeFullName,
|
||||
changeInitials,
|
||||
changeEmail,
|
||||
changePassword,
|
||||
changeAvatar
|
||||
} from "../../../../../components/actions/UsersActions";
|
||||
import AvatarInputField from "./AvatarInputField";
|
||||
import ProfileInputField from "./ProfileInputField";
|
||||
|
||||
const AvatarLabel = styled.h4`
|
||||
margin-top: 15px;
|
||||
|
@ -32,171 +23,27 @@ class MyProfile extends Component {
|
|||
initials: "",
|
||||
email: "",
|
||||
timeZone: "",
|
||||
newEmail: "",
|
||||
isFullNameEditable: false,
|
||||
areInitialsEditable: false,
|
||||
isEmailEditable: false,
|
||||
isPasswordEditable: false,
|
||||
isAvatarEditable: false
|
||||
newEmail: ""
|
||||
};
|
||||
|
||||
this.toggleIsEditable = this.toggleIsEditable.bind(this);
|
||||
this.getProfileInfo = this.getProfileInfo.bind(this);
|
||||
this.setData = this.setData.bind(this);
|
||||
this.loadInfo = this.loadInfo.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getProfileInfo();
|
||||
this.loadInfo();
|
||||
}
|
||||
|
||||
setData({ data }) {
|
||||
const user = data.user;
|
||||
|
||||
// TODO move this transformation to seperate method
|
||||
|
||||
const newData = {
|
||||
fullName: user.full_name,
|
||||
initials: user.initials,
|
||||
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 });
|
||||
loadInfo() {
|
||||
getUserProfileInfo()
|
||||
.then(data => {
|
||||
const { fullName, initials, email, avatarThumb, timeZone } = data;
|
||||
this.setState({ fullName, initials, email, avatarThumb, timeZone });
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
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 (
|
||||
<div>
|
||||
<h2>
|
||||
|
@ -205,42 +52,45 @@ class MyProfile extends Component {
|
|||
<AvatarLabel>
|
||||
<FormattedMessage id="settings_page.avatar" />
|
||||
</AvatarLabel>
|
||||
{avatarField}
|
||||
{fullNameField}
|
||||
{initialsField}
|
||||
{emailField}
|
||||
{passwordField}
|
||||
<AvatarInputField imgSource={this.state.avatarThumb} />
|
||||
|
||||
<ProfileInputField
|
||||
value={this.state.fullName}
|
||||
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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MyProfile.propTypes = {
|
||||
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);
|
||||
export default 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
|
||||
}
|
||||
});
|
||||
|
||||
// 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
|
||||
export const USER_PROFILE_INFO = "/client_api/users/profile_info";
|
||||
export const UPDATE_USER_PATH = "/client_api/users/update";
|
||||
|
||||
// info dropdown_title
|
||||
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.full_name user.full_name
|
||||
json.fullName user.full_name
|
||||
json.initials user.initials
|
||||
json.email user.email
|
||||
json.avatar_thumb_path avatar_path(user, :thumb)
|
||||
json.time_zone user.time_zone
|
||||
json.avatarThumb avatar_path(user, :thumb)
|
||||
json.timeZone user.time_zone
|
||||
end
|
||||
|
|
|
@ -36,7 +36,7 @@ Rails.application.routes.draw do
|
|||
get '/profile_info', to: 'users#profile_info'
|
||||
# get '/statistics_info', to: 'users#statistics_info'
|
||||
get '/preferences_info', to: 'users#preferences_info'
|
||||
|
||||
post '/update', to: 'users#update'
|
||||
# delete '/leave_team', to: 'user_teams#leave_team'
|
||||
# post '/change_full_name', to: 'users#change_full_name'
|
||||
# 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"
|
||||
|
||||
prettier@^1.5.3:
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.5.3.tgz#59dadc683345ec6b88f88b94ed4ae7e1da394bfe"
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.7.0.tgz#47481588f41f7c90f63938feb202ac82554e7150"
|
||||
|
||||
prettysize@^0.1.0:
|
||||
version "0.1.0"
|
||||
|
|
Loading…
Add table
Reference in a new issue