client/app/pages/users/components/PasswordForm/ChangePasswordDialog.jsx (126 lines of code) (raw):

import { isFunction, get } from "lodash"; import React from "react"; import Form from "antd/lib/form"; import Modal from "antd/lib/modal"; import Input from "antd/lib/input"; import { UserProfile } from "@/components/proptypes"; import { wrap as wrapDialog, DialogPropType } from "@/components/DialogWrapper"; import User from "@/services/user"; import notification from "@/services/notification"; class ChangePasswordDialog extends React.Component { static propTypes = { user: UserProfile.isRequired, dialog: DialogPropType.isRequired, }; constructor(props) { super(props); this.state = { currentPassword: { value: "", error: null, touched: false }, newPassword: { value: "", error: null, touched: false }, repeatPassword: { value: "", error: null, touched: false }, updatingPassword: false, }; } fieldError = (name, value) => { if (value.length === 0) return "This field is required."; if (name !== "currentPassword" && value.length < 6) return "This field is too short."; if (name === "repeatPassword" && value !== this.state.newPassword.value) return "Passwords don't match"; return null; }; validateFields = callback => { const { currentPassword, newPassword, repeatPassword } = this.state; const errors = { currentPassword: this.fieldError("currentPassword", currentPassword.value), newPassword: this.fieldError("newPassword", newPassword.value), repeatPassword: this.fieldError("repeatPassword", repeatPassword.value), }; this.setState({ currentPassword: { ...currentPassword, error: errors.currentPassword }, newPassword: { ...newPassword, error: errors.newPassword }, repeatPassword: { ...repeatPassword, error: errors.repeatPassword }, }); if (isFunction(callback)) { if (errors.currentPassword || errors.newPassword || errors.repeatPassword) { callback(errors); } else callback(null); } }; updatePassword = () => { const { currentPassword, newPassword, updatingPassword } = this.state; if (!updatingPassword) { this.validateFields(err => { if (!err) { const userData = { id: this.props.user.id, old_password: currentPassword.value, password: newPassword.value, }; this.setState({ updatingPassword: true }); User.save(userData) .then(() => { notification.success("Saved."); this.props.dialog.close({ success: true }); }) .catch(error => { notification.error(get(error, "response.data.message", "Failed saving.")); this.setState({ updatingPassword: false }); }); } else { this.setState(prevState => ({ currentPassword: { ...prevState.currentPassword, touched: true }, newPassword: { ...prevState.newPassword, touched: true }, repeatPassword: { ...prevState.repeatPassword, touched: true }, })); } }); } }; handleChange = e => { const { name, value } = e.target; const { error } = this.state[name]; this.setState({ [name]: { value, error, touched: true } }, () => { this.validateFields(); }); }; render() { const { dialog } = this.props; const { currentPassword, newPassword, repeatPassword, updatingPassword } = this.state; const formItemProps = { className: "m-b-10", required: true }; const inputProps = { onChange: this.handleChange, onPressEnter: this.updatePassword, }; return ( <Modal {...dialog.props} okButtonProps={{ loading: updatingPassword }} onOk={this.updatePassword} title="Change Password"> <Form layout="vertical"> <Form.Item {...formItemProps} validateStatus={currentPassword.touched && currentPassword.error ? "error" : null} help={currentPassword.touched ? currentPassword.error : null} label="Current Password"> <Input.Password {...inputProps} name="currentPassword" data-test="CurrentPassword" autoFocus /> </Form.Item> <Form.Item {...formItemProps} validateStatus={newPassword.touched && newPassword.error ? "error" : null} help={newPassword.touched ? newPassword.error : null} label="New Password"> <Input.Password {...inputProps} name="newPassword" data-test="NewPassword" /> </Form.Item> <Form.Item {...formItemProps} validateStatus={repeatPassword.touched && repeatPassword.error ? "error" : null} help={repeatPassword.touched ? repeatPassword.error : null} label="Repeat New Password"> <Input.Password {...inputProps} name="repeatPassword" data-test="RepeatPassword" /> </Form.Item> </Form> </Modal> ); } } export default wrapDialog(ChangePasswordDialog);