From ba9f034bfbba573e75000ed723cfb805cb83bec0 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 16 Apr 2018 17:37:08 -0600 Subject: [PATCH 01/21] Allow a user to change their own username --- models/action.js | 4 +- perms/reducers/mutation.js | 21 ++- services/users.js | 133 ++++++++++++------ test/server/graph/mutations/changeUsername.js | 2 +- test/server/services/users.js | 58 ++++++++ 5 files changed, 172 insertions(+), 46 deletions(-) diff --git a/models/action.js b/models/action.js index f3414f3ea..773bccf7e 100644 --- a/models/action.js +++ b/models/action.js @@ -22,8 +22,8 @@ const ActionSchema = new Schema( item_id: String, user_id: String, - // The element that summaries will additionally group on in addtion to their action_type, item_type, and - // item_id. + // The element that summaries will additionally group on in addition to + // their action_type, item_type, and item_id. group_id: String, // Additional metadata stored on the field. diff --git a/perms/reducers/mutation.js b/perms/reducers/mutation.js index d0841ef99..f063fe1c2 100644 --- a/perms/reducers/mutation.js +++ b/perms/reducers/mutation.js @@ -1,4 +1,5 @@ -const { isString } = require('lodash'); +const { get, isString } = require('lodash'); +const moment = require('moment'); const { check } = require('../utils'); const types = require('../constants'); @@ -12,8 +13,22 @@ module.exports = (user, perm) => { isString(user.password) && user.password.length > 0 ); - case types.CHANGE_USERNAME: - return user.status.username.status === 'REJECTED'; + + case types.CHANGE_USERNAME: { + // Only users who have their usernames rejected or those users who + // not changed their usernames within 14 days can change their usernames. + const now = moment(); + return ( + user.status.username.status === 'REJECTED' || + get(user, 'status.username.history', []) + .filter(({ status }) => status === 'CHANGED') + .every(({ created_at }) => + moment(created_at) + .add(14, 'days') + .isAfter(now) + ) + ); + } case types.SET_USERNAME: return user.status.username.status === 'UNSET'; diff --git a/services/users.js b/services/users.js index 657be737a..b860acfeb 100644 --- a/services/users.js +++ b/services/users.js @@ -1,4 +1,5 @@ const uuid = require('uuid'); +const moment = require('moment'); const bcrypt = require('bcryptjs'); const { ErrMaxRateLimit, @@ -234,57 +235,64 @@ class Users { return user; } - static async _setUsername( - id, - username, - fromStatus, - toStatus, - assignedBy, - resetAllowed = false - ) { + static async setUsername(id, username, assignedBy) { try { + const oldestEditTime = moment().subtract(14, 'days'); + + // A username can be set if: + // + // - The previous status was 'UNSET' + // - The username has not been changed within the last 14 days. const query = { id, - 'status.username.status': fromStatus, - }; - if (!resetAllowed) { - query.username = { $ne: username }; - } - - let user = await User.findOneAndUpdate( - query, - { - $set: { - username, - lowercaseUsername: username.toLowerCase(), - 'status.username.status': toStatus, + $or: [ + { + 'status.username.status': 'UNSET', }, - $push: { - 'status.username.history': { - status: toStatus, - assigned_by: assignedBy, - created_at: Date.now(), + { + 'status.username.status': { $in: ['APPROVED', 'SET'] }, + 'status.username.history.created_at': { + $not: { + $gte: oldestEditTime, + }, }, }, + ], + }; + + const update = { + $set: { + username, + lowercaseUsername: username.toLowerCase(), + 'status.username.status': 'SET', }, - { - new: true, - } - ); + $push: { + 'status.username.history': { + status: 'SET', + assigned_by: assignedBy, + created_at: Date.now(), + }, + }, + }; + + let user = await User.findOneAndUpdate(query, update, { + new: true, + }); if (!user) { user = await Users.findById(id); if (user === null) { throw new ErrNotFound(); } - if (user.status.username.status !== fromStatus) { + if ( + !['UNSET', 'APPROVED', 'SET'].includes(user.status.username.status) || + !user.status.username.history.every(({ created_at }) => + oldestEditTime.isAfter(created_at) + ) + ) { throw new ErrPermissionUpdateUsername(); } - if (!resetAllowed && user.username === username) { - throw new ErrSameUsernameProvided(); - } - throw new Error('edit username failed for an unexpected reason'); } @@ -298,12 +306,57 @@ class Users { } } - static async setUsername(id, username, assignedBy) { - return Users._setUsername(id, username, 'UNSET', 'SET', assignedBy, true); - } - static async changeUsername(id, username, assignedBy) { - return Users._setUsername(id, username, 'REJECTED', 'CHANGED', assignedBy); + try { + const query = { + id, + username: { $ne: username }, + 'status.username.status': 'REJECTED', + }; + + const update = { + $set: { + username, + lowercaseUsername: username.toLowerCase(), + 'status.username.status': 'CHANGED', + }, + $push: { + 'status.username.history': { + status: 'CHANGED', + assigned_by: assignedBy, + created_at: Date.now(), + }, + }, + }; + + let user = await User.findOneAndUpdate(query, update, { + new: true, + }); + if (!user) { + user = await Users.findById(id); + if (user === null) { + throw new ErrNotFound(); + } + + if (user.status.username.status !== 'REJECTED') { + throw new ErrPermissionUpdateUsername(); + } + + if (user.username === username) { + throw new ErrSameUsernameProvided(); + } + + throw new Error('edit username failed for an unexpected reason'); + } + + return user; + } catch (err) { + if (err.code === 11000) { + throw new ErrUsernameTaken(); + } + + throw err; + } } /** diff --git a/test/server/graph/mutations/changeUsername.js b/test/server/graph/mutations/changeUsername.js index eaff85434..a5c3daed8 100644 --- a/test/server/graph/mutations/changeUsername.js +++ b/test/server/graph/mutations/changeUsername.js @@ -89,7 +89,7 @@ describe('graph.mutations.changeUsername', () => { expect(res.data.changeUsername.errors).to.have.length(1); expect(res.data.changeUsername.errors[0]).to.have.property( 'translation_key', - 'NOT_AUTHORIZED' + 'EDIT_USERNAME_NOT_AUTHORIZED' ); // Set the user to the desired status. diff --git a/test/server/services/users.js b/test/server/services/users.js index e8a0172f7..a7d7475e9 100644 --- a/test/server/services/users.js +++ b/test/server/services/users.js @@ -2,6 +2,8 @@ const UsersService = require('../../../services/users'); const SettingsService = require('../../../services/settings'); const mailer = require('../../../services/mailer'); const Context = require('../../../graph/context'); +const timekeeper = require('timekeeper'); +const moment = require('moment'); const chai = require('chai'); chai.use(require('chai-as-promised')); @@ -303,6 +305,62 @@ describe('services.UsersService', () => { } }); }); + + if (func === 'setUsername') { + it('should let a user set their username from UNSET', async () => { + const user = mockUsers[0]; + + // Set the user to the desired status. + await UsersService.setUsernameStatus(user.id, 'UNSET'); + await UsersService.setUsername(user.id, 'new_username', null); + }); + + describe('time based', () => { + afterEach(() => { + timekeeper.reset(); + }); + + ['SET', 'APPROVED'].forEach(status => { + it(`should not allow users to change their username if it was changed within 14 of today from ${status}`, async () => { + const user = mockUsers[0]; + + // Set the user to the desired status. + await UsersService.setUsernameStatus(user.id, status); + + timekeeper.travel( + moment() + .add(5, 'days') + .toDate() + ); + + try { + await UsersService.setUsername(user.id, 'new_username', null); + throw new Error('edit was processed successfully'); + } catch (err) { + expect(err).have.property( + 'translation_key', + 'EDIT_USERNAME_NOT_AUTHORIZED' + ); + } + }); + + it(`allows users to change their username if it was changed 14 days before today from ${status}`, async () => { + const user = mockUsers[0]; + + // Set the user to the desired status. + await UsersService.setUsernameStatus(user.id, status); + + timekeeper.travel( + moment() + .add(15, 'days') + .toDate() + ); + + await UsersService.setUsername(user.id, 'new_username', null); + }); + }); + }); + } }); describe('#isValidUsername', () => { From b60e62f9769bf78f47d09d684d69180537bb624c Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 19 Apr 2018 09:21:12 -0600 Subject: [PATCH 02/21] small fixes for db logic --- services/users.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/users.js b/services/users.js index b860acfeb..a3301be10 100644 --- a/services/users.js +++ b/services/users.js @@ -237,7 +237,9 @@ class Users { static async setUsername(id, username, assignedBy) { try { - const oldestEditTime = moment().subtract(14, 'days'); + const oldestEditTime = moment() + .subtract(14, 'days') + .toDate(); // A username can be set if: // @@ -252,9 +254,7 @@ class Users { { 'status.username.status': { $in: ['APPROVED', 'SET'] }, 'status.username.history.created_at': { - $not: { - $gte: oldestEditTime, - }, + $lte: oldestEditTime, }, }, ], From 15817712c07af7d22d9082d98c81e37c3f4aa3c3 Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 24 Apr 2018 13:58:28 -0300 Subject: [PATCH 03/21] Introducing profileHeader slot --- .../src/tabs/profile/components/Profile.js | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/client/coral-embed-stream/src/tabs/profile/components/Profile.js b/client/coral-embed-stream/src/tabs/profile/components/Profile.js index 0bc90be0a..e73ebe455 100644 --- a/client/coral-embed-stream/src/tabs/profile/components/Profile.js +++ b/client/coral-embed-stream/src/tabs/profile/components/Profile.js @@ -4,13 +4,31 @@ import Slot from 'coral-framework/components/Slot'; import styles from './Profile.css'; import TabPanel from '../containers/TabPanel'; +const DefaultProfileHeader = ({ username, emailAddress }) => ( +
+

{username}

+ {emailAddress ?

{emailAddress}

: null} +
+); + +DefaultProfileHeader.propTypes = { + username: PropTypes.string, + emailAddress: PropTypes.string, +}; + const Profile = ({ username, emailAddress, root, slotPassthrough }) => { return (
-
-

{username}

- {emailAddress ?

{emailAddress}

: null} -
+
From 89114ecd13aad5fde9b19eae618bc6ec2daabe56 Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 24 Apr 2018 14:13:24 -0300 Subject: [PATCH 04/21] Adding withChangeUsername to plugin hocs, wip and more --- plugin-api/beta/client/hocs/index.js | 1 + plugins/talk-plugin-auth/client/index.js | 2 + .../components/ChangeUsername.css | 20 ++++++++ .../components/ChangeUsername.js | 51 +++++++++++++++++++ .../containers/ChangeUsername.js | 12 +++++ 5 files changed, 86 insertions(+) create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js create mode 100644 plugins/talk-plugin-auth/client/profile-settings/containers/ChangeUsername.js diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js index 41ede8445..d7ca5fce9 100644 --- a/plugin-api/beta/client/hocs/index.js +++ b/plugin-api/beta/client/hocs/index.js @@ -26,5 +26,6 @@ export { withStopIgnoringUser, withSetCommentStatus, withChangePassword, + withChangeUsername, } from 'coral-framework/graphql/mutations'; export { compose } from 'recompose'; diff --git a/plugins/talk-plugin-auth/client/index.js b/plugins/talk-plugin-auth/client/index.js index 039f0f936..8fedb8033 100644 --- a/plugins/talk-plugin-auth/client/index.js +++ b/plugins/talk-plugin-auth/client/index.js @@ -5,6 +5,7 @@ import translations from './translations.yml'; import Login from './login/containers/Main'; import reducer from './login/reducer'; import ChangePassword from './profile-settings/containers/ChangePassword'; +import ChangeUsername from './profile-settings/containers/ChangeUsername'; export default { reducer, @@ -12,6 +13,7 @@ export default { slots: { stream: [UserBox, SignInButton, SetUsernameDialog], login: [Login], + profileHeader: [ChangeUsername], profileSettings: [ChangePassword], }, }; diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css new file mode 100644 index 000000000..c28cc163c --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css @@ -0,0 +1,20 @@ +.container { + margin-bottom: 20px; +} + +.email { + margin: 0; +} + +.username { + margin-bottom: 4px; +} + +.actions { + position: absolute; + top: 10px; + right: 10px; + display: flex; + flex-direction: column; + align-items: center; +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js new file mode 100644 index 000000000..59eadb1c4 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -0,0 +1,51 @@ +import React from 'react'; +import cn from 'classnames'; +import PropTypes from 'prop-types'; +import styles from './ChangeUsername.css'; +import { Button } from 'plugin-api/beta/client/components/ui'; + +const initialState = { + editing: false, +}; + +class ChangeUsername extends React.Component { + state = initialState; + + render() { + const { username, emailAddress } = this.props; + return ( +
+
+

{username}

+ {emailAddress ?

{emailAddress}

: null} +
+
+ + + Cancel + +
+
+ +
+
+ ); + } +} + +ChangeUsername.propTypes = { + changeUsername: PropTypes.func.isRequired, + username: PropTypes.string, + emailAddress: PropTypes.string, +}; + +export default ChangeUsername; diff --git a/plugins/talk-plugin-auth/client/profile-settings/containers/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/containers/ChangeUsername.js new file mode 100644 index 000000000..87e1e18b5 --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/containers/ChangeUsername.js @@ -0,0 +1,12 @@ +import { compose } from 'react-apollo'; +import { bindActionCreators } from 'redux'; +import { connect } from 'plugin-api/beta/client/hocs'; +import ChangeUsername from '../components/ChangeUsername'; +import { notify } from 'coral-framework/actions/notification'; +import { withChangeUsername } from 'plugin-api/beta/client/hocs'; + +const mapDispatchToProps = dispatch => bindActionCreators({ notify }, dispatch); + +export default compose(connect(null, mapDispatchToProps), withChangeUsername)( + ChangeUsername +); From 754b5c5fbb6216e8344e744a7fb10ba49e9af1e7 Mon Sep 17 00:00:00 2001 From: okbel Date: Wed, 25 Apr 2018 12:20:51 -0300 Subject: [PATCH 05/21] Adding Dialog, styles and more --- .../components/ChangePassword.css | 2 +- .../components/ChangeUsername.css | 121 ++++++++++++- .../components/ChangeUsername.js | 170 +++++++++++++++--- .../components/ChangeUsernameDialog.css | 82 +++++++++ .../components/ChangeUsernameDialog.js | 57 ++++++ 5 files changed, 398 insertions(+), 34 deletions(-) create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css create mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.css index e94247ac1..6c7f9ae41 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.css @@ -47,7 +47,7 @@ border: 1px solid #787d80; background-color: transparent; height: 30px; - font-size: 1em; + font-size: 0.9em; line-height: normal; } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css index c28cc163c..8ab9eb5cd 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css @@ -1,20 +1,123 @@ .container { margin-bottom: 20px; + display: flex; + position: relative; + color: #202020; + padding: 10px; + border-radius: 2px; + box-sizing: border-box; + justify-content: space-between; + + &.editing { + background-color: #EDEDED; + } } +.content { + flex-grow: 1; +} + +.actions { + flex-grow: 0; + display: flex; + flex-direction: column; + align-items: center; +} + .email { margin: 0; } -.username { +.username { margin-bottom: 4px; +} + +.button { + border: 1px solid #787d80; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; } -.actions { - position: absolute; - top: 10px; - right: 10px; - display: flex; - flex-direction: column; - align-items: center; -} \ No newline at end of file +.saveButton { + background-color: #3498DB; + border-color: #3498DB; + color: white; + + > i { + font-size: 17px; + } + + &:hover { + background-color: #399ee2; + color: white; + } + + &:disabled { + border-color: #e0e0e0; + + &:hover { + background-color: #e0e0e0; + color: #4f5c67; + cursor: default; + } + } +} + +.cancelButton { + color:#787D80; + margin-top: 6px; + font-size: 0.9em; + + &:hover { + cursor: pointer; + } +} + +.detailLabel { + border: solid 1px #787D80; + border-radius: 2px; + background-color: white; + height: 30px; + display: inline-block; + width: 230px; + display: flex; + + > .detailLabelIcon { + font-size: 1.2em; + padding: 0 5px; + color: #787D80; + line-height: 30px; + } + + &.disabled { + background-color: #E0E0E0; + } +} + +.detailValue { + background: transparent; + border: none; + font-size: 1em; + color: #000; + height: 30px; + outline: none; + flex: 1; +} + +.bottomText { + color: #474747; + font-size: 0.9em; + display: block; +} + +.detailList { + list-style: none; + margin: 0; + padding: 0; +} + +.detailItem { + margin-bottom: 8px; +} diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js index 59eadb1c4..42349e3e9 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -2,41 +2,163 @@ import React from 'react'; import cn from 'classnames'; import PropTypes from 'prop-types'; import styles from './ChangeUsername.css'; -import { Button } from 'plugin-api/beta/client/components/ui'; +import { Icon, Button } from 'plugin-api/beta/client/components/ui'; +import ChangeUsernameDialog from './ChangeUsernameDialog'; const initialState = { editing: false, + formData: {}, + showDialog: false, }; class ChangeUsername extends React.Component { state = initialState; + clearForm = () => { + this.setState(initialState); + }; + + enableEditing = () => { + this.setState({ + editing: true, + }); + }; + + disableEditing = () => { + this.setState({ + editing: false, + }); + }; + + cancel = () => { + this.clearForm(); + this.disableEditing(); + }; + + showDialog = () => { + this.setState({ + showDialog: true, + }); + }; + + onSave = async () => { + this.showDialog(); + // this.clearForm(); + // this.disableEditing(); + }; + + onChange = e => { + const { name, value } = e.target; + this.setState( + state => ({ + formData: { + ...state.formData, + [name]: value, + }, + }), + () => { + console.log(this.state.formData); + // Validation + // this.fieldValidation(value, type, name); + // // Perform equality validation if password fields have changed + // if (name === 'newPassword' || name === 'confirmNewPassword') { + // this.equalityValidation('newPassword', 'confirmNewPassword'); + // } + } + ); + }; + + closeDialog = () => { + this.setState({ + showDialog: false, + }); + }; + render() { const { username, emailAddress } = this.props; + const { editing } = this.state; + + console.log('loading xxxx'); + return ( -
-
-

{username}

- {emailAddress ?

{emailAddress}

: null} -
-
- - - Cancel - -
-
- -
+
+ + + {editing ? ( +
+
    +
  • + + + Usernames can be changed every 14 days + +
  • +
  • + +
  • +
+
+ ) : ( +
+

{username}

+ {emailAddress ? ( +

{emailAddress}

+ ) : null} +
+ )} + + {editing ? ( +
+ + + Cancel + +
+ ) : ( +
+ +
+ )}
); } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css new file mode 100644 index 000000000..b3c4524fe --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css @@ -0,0 +1,82 @@ +.dialog { + border: none; + box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); + width: 320px; + top: 10px; + font-family: Helvetica, 'Helvetica Neue', Verdana, sans-serif; + font-size: 14px; + border-radius: 4px; + padding: 12px 20px; +} + +.close { + font-size: 20px; + line-height: 14px; + top: 10px; + right: 10px; + position: absolute; + display: block; + font-weight: bold; + color: #363636; + cursor: pointer; + + &:hover { + color: #6b6b6b; + } +} + +.title { + font-size: 1.3em; + margin-bottom: 8px; +} + +.description { + font-size: 1em; + line-height: 20px; + margin: 0; +} + +.item { + display: block; + color: #4C4C4D; + font-size: 1em; + margin-bottom: 2px; +} + +.bottomNote { + font-size: 0.9em; + line-height: 20px; +} + +.bottomActions { + text-align: right; +} + +.usernamesChange { + margin: 18px 0; +} + +.cancel { + border: 1px solid #787d80; + background-color: transparent; + height: 30px; + font-size: 0.9em; + line-height: normal; + + &:hover { + background-color: #eaeaea; + } +} + +.confirmChanges { + background-color: #3498DB; + border-color: #3498DB; + color: white; + height: 30px; + font-size: 0.9em; + + &:hover { + background-color: #3ba3ec; + color: white; + } +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js new file mode 100644 index 000000000..e0c08ec3e --- /dev/null +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js @@ -0,0 +1,57 @@ +import React from 'react'; +import cn from 'classnames'; +import styles from './ChangeUsernameDialog.css'; +import InputField from './InputField'; +import Form from './Form'; +import { Button, Dialog } from 'plugin-api/beta/client/components/ui'; + +class ChangeUsernameDialog extends React.Component { + render() { + return ( + + + × + +

Confirm Username Change

+
+

+ You are attempting to change your username. Your new username will + appear on all of your past and future comments. +

+
+ + Old Username: {this.props.username} + + + New Username: {this.props.formData.newUsername} + +
+
+ + + Note: You will not be able to change your username again for 14 + days + + +
+
+ + +
+
+
+ ); + } +} + +export default ChangeUsernameDialog; From a79d71da7d78b634c8095303e4adfe03db8c967b Mon Sep 17 00:00:00 2001 From: okbel Date: Wed, 25 Apr 2018 12:53:03 -0300 Subject: [PATCH 06/21] Full functionality, needs translation --- .../components/ChangeUsername.css | 3 +- .../components/ChangeUsername.js | 11 +++--- .../components/ChangeUsernameDialog.css | 2 ++ .../components/ChangeUsernameDialog.js | 34 ++++++++++++++++++- .../components/ErrorMessage.css | 1 - .../components/InputField.css | 16 +++++++-- .../profile-settings/components/InputField.js | 14 ++++++-- 7 files changed, 68 insertions(+), 13 deletions(-) diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css index 8ab9eb5cd..5b4631ecf 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.css @@ -109,7 +109,6 @@ .bottomText { color: #474747; font-size: 0.9em; - display: block; } .detailList { @@ -119,5 +118,5 @@ } .detailItem { - margin-bottom: 8px; + margin-bottom: 12px; } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js index 42349e3e9..a146ea5f9 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -43,8 +43,10 @@ class ChangeUsername extends React.Component { onSave = async () => { this.showDialog(); - // this.clearForm(); - // this.disableEditing(); + }; + + saveChanges = async () => { + // savechanges }; onChange = e => { @@ -78,8 +80,6 @@ class ChangeUsername extends React.Component { const { username, emailAddress } = this.props; const { editing } = this.state; - console.log('loading xxxx'); - return (
Save diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css index b3c4524fe..af681d596 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.css @@ -46,6 +46,8 @@ .bottomNote { font-size: 0.9em; line-height: 20px; + padding-top: 10px; + display: block; } .bottomActions { diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js index e0c08ec3e..b337af007 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js @@ -6,6 +6,28 @@ import Form from './Form'; import { Button, Dialog } from 'plugin-api/beta/client/components/ui'; class ChangeUsernameDialog extends React.Component { + state = { + showErrors: false, + }; + + showErrors = () => { + this.setState({ + showErrors: true, + }); + }; + + confirmChanges = async () => { + if (this.formHasError()) { + this.showErrors(); + } else { + // await this.props.saveChanges + this.props.closeDialog(); + } + }; + + formHasError = () => + this.props.formData.confirmNewUsername !== this.props.formData.newUsername; + render() { return ( Note: You will not be able to change your username again for 14 @@ -46,7 +73,12 @@ class ChangeUsernameDialog extends React.Component {
- +
diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.css b/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.css index d7a1b6d45..abcf692fe 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ErrorMessage.css @@ -1,6 +1,5 @@ .errorMsg { color: #FA4643; - padding-left: 4px; font-size: 0.9em; } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css index be25a44b9..b2648e116 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css @@ -7,6 +7,14 @@ display: flex; } +.columnDisplay { + flex-direction: column; + + .detailItemMessage { + padding: 4px 0 0; + } +} + .detailItemContent { min-width: 280px; } @@ -28,13 +36,17 @@ color: #979797; box-sizing: border-box; width: 100%; + + &.error { + border-color: #FA4643; + } } .detailItemMessage { flex-grow: 1; display: flex; align-items: center; - padding-left: 2px; + padding-left: 6px; padding-top: 16px; .warningIcon, .checkIcon { @@ -48,4 +60,4 @@ .warningIcon { color: #FA4643; -} +} \ No newline at end of file diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js index ed9c394ee..5818bfd2c 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import cn from 'classnames'; import styles from './InputField.css'; import ErrorMessage from './ErrorMessage'; import { Icon } from 'plugin-api/beta/client/components/ui'; @@ -15,10 +16,16 @@ const InputField = ({ hasError = false, errorMsg = '', children, + columnDisplay = false, + showSuccess = true, }) => { return (
  • -
    +
    {!hasError && + showSuccess && value && } {hasError && showError && {errorMsg}}
    @@ -55,6 +63,8 @@ InputField.propTypes = { hasError: PropTypes.bool, errorMsg: PropTypes.string, children: PropTypes.node, + columnDisplay: PropTypes.bool, + showSuccess: PropTypes.bool, }; export default InputField; From aefac2056edb1037444a7f80b6f4a8b02cc85e95 Mon Sep 17 00:00:00 2001 From: okbel Date: Wed, 25 Apr 2018 13:36:00 -0300 Subject: [PATCH 07/21] wip more validations --- .../components/ChangeUsername.js | 61 ++++++++++++++++--- .../components/ChangeUsernameDialog.js | 1 + .../profile-settings/components/InputField.js | 5 +- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js index a146ea5f9..d9f2fc15d 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -4,11 +4,15 @@ import PropTypes from 'prop-types'; import styles from './ChangeUsername.css'; import { Icon, Button } from 'plugin-api/beta/client/components/ui'; import ChangeUsernameDialog from './ChangeUsernameDialog'; +import validate from 'coral-framework/helpers/validate'; +import errorMsj from 'coral-framework/helpers/error'; +import { t } from 'plugin-api/beta/client/services'; const initialState = { editing: false, - formData: {}, showDialog: false, + errors: {}, + formData: {}, }; class ChangeUsername extends React.Component { @@ -49,8 +53,50 @@ class ChangeUsername extends React.Component { // savechanges }; + fieldValidation = (value, type, name) => { + if (!value.length) { + this.addError({ + [name]: t('talk-plugin-auth.change_password.required_field'), + }); + } else if (!validate[type](value)) { + this.addError({ [name]: errorMsj[type] }); + } else { + this.removeError(name); + } + }; + + hasError = err => { + return Object.keys(this.state.errors).indexOf(err) !== -1; + }; + + addError = err => { + this.setState( + ({ errors }) => ({ + errors: { ...errors, ...err }, + }), + () => { + console.log(this.state); + } + ); + }; + + removeError = errKey => { + this.setState( + state => { + const { [errKey]: _, ...errors } = state.errors; + return { + errors, + }; + }, + () => { + console.log(this.state); + } + ); + }; + onChange = e => { - const { name, value } = e.target; + const { name, value, type, dataset: { validationType } } = e.target; + this.setState( state => ({ formData: { @@ -59,13 +105,9 @@ class ChangeUsername extends React.Component { }, }), () => { - console.log(this.state.formData); - // Validation - // this.fieldValidation(value, type, name); - // // Perform equality validation if password fields have changed - // if (name === 'newPassword' || name === 'confirmNewPassword') { - // this.equalityValidation('newPassword', 'confirmNewPassword'); - // } + const fieldType = !validationType ? type : validationType; + this.fieldValidation(value, fieldType, name); + // the username cannot be the same } ); }; @@ -103,6 +145,7 @@ class ChangeUsername extends React.Component { Note: You will not be able to change your username again for 14 diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js index 5818bfd2c..511b89227 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js @@ -18,6 +18,7 @@ const InputField = ({ children, columnDisplay = false, showSuccess = true, + validationType = '', }) => { return (
  • @@ -34,10 +35,11 @@ const InputField = ({ id={id} type={type} name={name} - className={cn(styles.detailValue, styles.error)} + className={cn(styles.detailValue, { [styles.error]: hasError })} onChange={onChange} value={value} autoComplete="off" + data-validation-type={validationType} />
    @@ -65,6 +67,7 @@ InputField.propTypes = { children: PropTypes.node, columnDisplay: PropTypes.bool, showSuccess: PropTypes.bool, + validationType: PropTypes.string, }; export default InputField; From 8f6691f7a4ea9448d55675fc74a5414f46ecfb0e Mon Sep 17 00:00:00 2001 From: okbel Date: Thu, 26 Apr 2018 11:15:18 -0300 Subject: [PATCH 08/21] InputField refactor --- .../components/ChangeUsername.js | 44 ++++++++----------- .../components/ChangeUsernameDialog.js | 12 ++--- .../components/InputField.css | 39 ++++++++++------ .../profile-settings/components/InputField.js | 41 ++++++++++++----- 4 files changed, 81 insertions(+), 55 deletions(-) diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js index d9f2fc15d..b5bd8916b 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -7,6 +7,7 @@ import ChangeUsernameDialog from './ChangeUsernameDialog'; import validate from 'coral-framework/helpers/validate'; import errorMsj from 'coral-framework/helpers/error'; import { t } from 'plugin-api/beta/client/services'; +import InputField from './InputField'; const initialState = { editing: false, @@ -139,34 +140,27 @@ class ChangeUsername extends React.Component { {editing ? (
      -
    • - + Usernames can be changed every 14 days -
    • -
    • - -
    • + +
    ) : ( diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js index d5e50b4e8..22c74bce3 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js @@ -7,18 +7,18 @@ import { Button, Dialog } from 'plugin-api/beta/client/components/ui'; class ChangeUsernameDialog extends React.Component { state = { - showErrors: false, + showError: false, }; - showErrors = () => { + showError = () => { this.setState({ - showErrors: true, + showError: true, }); }; confirmChanges = async () => { if (this.formHasError()) { - this.showErrors(); + this.showError(); } else { // await this.props.saveChanges this.props.closeDialog(); @@ -59,9 +59,9 @@ class ChangeUsernameDialog extends React.Component { type="text" onChange={this.props.onChange} value={this.props.formData.confirmNewUsername} - hasError={this.formHasError() && this.state.showErrors} + hasError={this.formHasError() && this.state.showError} errorMsg={'Username does not match'} - showErrors={this.state.showErrors} + showError={this.state.showError} columnDisplay showSuccess={false} validationType="username" diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css index b2648e116..f76970045 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css @@ -16,7 +16,24 @@ } .detailItemContent { - min-width: 280px; + border: solid 1px #787D80; + border-radius: 2px; + background-color: white; + height: 30px; + display: inline-block; + width: 230px; + display: flex; + + > .detailIcon { + font-size: 1.2em; + padding: 0 5px; + color: #787D80; + line-height: 30px; + } + + &.disabled { + background-color: #E0E0E0; + } } .detailLabel { @@ -27,19 +44,13 @@ } .detailValue { - padding: 6px 2px; - border: solid 1px #979797; - display: block; - font-size: 1.1em; - border-radius: 2px; - background-color: #ffffff; - color: #979797; - box-sizing: border-box; - width: 100%; - - &.error { - border-color: #FA4643; - } + background: transparent; + border: none; + font-size: 1em; + color: #000; + height: 30px; + outline: none; + flex: 1; } .detailItemMessage { diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js index 511b89227..7fa9a368a 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js @@ -11,35 +11,53 @@ const InputField = ({ type = 'text', name = '', onChange = () => {}, - value = '', showError = true, hasError = false, errorMsg = '', children, columnDisplay = false, - showSuccess = true, + showSuccess = false, validationType = '', + icon = '', + value = '', + defaultValue = '', + disabled = false, }) => { + const inputValue = { + ...(value ? { value } : {}), + ...(defaultValue ? { defaultValue } : {}), + }; + return ( -
  • +
    -
    + {label && ( + )} +
    + {icon && }
    @@ -50,17 +68,20 @@ const InputField = ({
    {children} -
  • + ); }; InputField.propTypes = { - id: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - type: PropTypes.string.isRequired, + id: PropTypes.string, + disabled: PropTypes.boolean, + label: PropTypes.string, + type: PropTypes.string, name: PropTypes.string.isRequired, onChange: PropTypes.func, value: PropTypes.string, + defaultValue: PropTypes.string, + icon: PropTypes.string, showError: PropTypes.bool, hasError: PropTypes.bool, errorMsg: PropTypes.string, From 2db9489646a9f87de1a68d6c809ef4d9d3b2c2cc Mon Sep 17 00:00:00 2001 From: okbel Date: Thu, 26 Apr 2018 11:15:35 -0300 Subject: [PATCH 09/21] Adding translations --- .../components/ChangePassword.js | 5 +- .../components/ChangeUsername.js | 79 ++++--------------- .../components/ChangeUsernameDialog.js | 14 +++- .../profile-settings/components/Form.css | 5 -- .../profile-settings/components/Form.js | 16 ---- .../talk-plugin-auth/client/translations.yml | 7 ++ 6 files changed, 34 insertions(+), 92 deletions(-) delete mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/Form.css delete mode 100644 plugins/talk-plugin-auth/client/profile-settings/components/Form.js diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.js index 3479b5dd9..90940728d 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangePassword.js @@ -7,7 +7,6 @@ import validate from 'coral-framework/helpers/validate'; import errorMsj from 'coral-framework/helpers/error'; import isEqual from 'lodash/isEqual'; import { t } from 'plugin-api/beta/client/services'; -import Form from './Form'; import InputField from './InputField'; import { getErrorMessages } from 'coral-framework/utils'; @@ -148,7 +147,7 @@ class ChangePassword extends React.Component { {t('talk-plugin-auth.change_password.change_password')} {editing && ( -
    + - + )} {editing ? (
    diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js index b5bd8916b..4fcca70fd 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -2,17 +2,14 @@ import React from 'react'; import cn from 'classnames'; import PropTypes from 'prop-types'; import styles from './ChangeUsername.css'; -import { Icon, Button } from 'plugin-api/beta/client/components/ui'; +import { Button } from 'plugin-api/beta/client/components/ui'; import ChangeUsernameDialog from './ChangeUsernameDialog'; -import validate from 'coral-framework/helpers/validate'; -import errorMsj from 'coral-framework/helpers/error'; import { t } from 'plugin-api/beta/client/services'; import InputField from './InputField'; const initialState = { editing: false, showDialog: false, - errors: {}, formData: {}, }; @@ -54,63 +51,15 @@ class ChangeUsername extends React.Component { // savechanges }; - fieldValidation = (value, type, name) => { - if (!value.length) { - this.addError({ - [name]: t('talk-plugin-auth.change_password.required_field'), - }); - } else if (!validate[type](value)) { - this.addError({ [name]: errorMsj[type] }); - } else { - this.removeError(name); - } - }; - - hasError = err => { - return Object.keys(this.state.errors).indexOf(err) !== -1; - }; - - addError = err => { - this.setState( - ({ errors }) => ({ - errors: { ...errors, ...err }, - }), - () => { - console.log(this.state); - } - ); - }; - - removeError = errKey => { - this.setState( - state => { - const { [errKey]: _, ...errors } = state.errors; - return { - errors, - }; - }, - () => { - console.log(this.state); - } - ); - }; - onChange = e => { - const { name, value, type, dataset: { validationType } } = e.target; + const { name, value } = e.target; - this.setState( - state => ({ - formData: { - ...state.formData, - [name]: value, - }, - }), - () => { - const fieldType = !validationType ? type : validationType; - this.fieldValidation(value, fieldType, name); - // the username cannot be the same - } - ); + this.setState(state => ({ + formData: { + ...state.formData, + [name]: value, + }, + })); }; closeDialog = () => { @@ -139,7 +88,7 @@ class ChangeUsername extends React.Component { {editing ? (
    -
      +
      - Usernames can be changed every 14 days + {t('talk-plugin-auth.change_username.change_username_note')} -
    +
    ) : (
    @@ -180,10 +129,10 @@ class ChangeUsername extends React.Component { onClick={this.onSave} disabled={!this.state.formData.newUsername} > - Save + {t('talk-plugin-auth.change_username.save')} - Cancel + {t('talk-plugin-auth.change_username.cancel')}
    ) : ( @@ -193,7 +142,7 @@ class ChangeUsername extends React.Component { icon="settings" onClick={this.enableEditing} > - Edit Profile + {t('talk-plugin-auth.change_username.edit_profile')} )} diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js index 22c74bce3..a561106c9 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js @@ -1,8 +1,8 @@ import React from 'react'; +import PropTypes from 'prop-types'; import cn from 'classnames'; import styles from './ChangeUsernameDialog.css'; import InputField from './InputField'; -import Form from './Form'; import { Button, Dialog } from 'plugin-api/beta/client/components/ui'; class ChangeUsernameDialog extends React.Component { @@ -51,7 +51,7 @@ class ChangeUsernameDialog extends React.Component { New Username: {this.props.formData.newUsername} -
    + -
    +
    diff --git a/plugins/talk-plugin-auth/client/translations.yml b/plugins/talk-plugin-auth/client/translations.yml index 84dc4e320..0d05d45c5 100644 --- a/plugins/talk-plugin-auth/client/translations.yml +++ b/plugins/talk-plugin-auth/client/translations.yml @@ -145,6 +145,12 @@ en: save: "Save" edit_profile: "Edit Profile" cancel: "Cancel" + confirm_username_change: "Confirm Username Change" + description: "You are attempting to change your username. Your new username will appear on all of your past and future comments." + old_username: "Old Username" + new_username: "New Username" + bottom_note: "Note: You will not be able to change your username again for 14 days" + confirm_changes: "Confirm Changes" de: talk-plugin-auth: login: From ba7de6bf81f2cb96095a5a5061119451aee2fec8 Mon Sep 17 00:00:00 2001 From: okbel Date: Thu, 26 Apr 2018 11:25:40 -0300 Subject: [PATCH 11/21] Translations --- .../client/profile-settings/components/ChangeUsername.js | 5 ++++- .../profile-settings/components/ChangeUsernameDialog.js | 2 +- .../client/profile-settings/components/InputField.css | 4 ++++ .../client/profile-settings/components/InputField.js | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js index 4fcca70fd..fbc8bfb1b 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -127,7 +127,10 @@ class ChangeUsername extends React.Component { className={cn(styles.button, styles.saveButton)} icon="save" onClick={this.onSave} - disabled={!this.state.formData.newUsername} + disabled={ + !this.state.formData.newUsername && + this.state.formData.newUsername !== username + } > {t('talk-plugin-auth.change_username.save')} diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js index 244dba00a..5bcc43241 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsernameDialog.js @@ -92,7 +92,7 @@ class ChangeUsernameDialog extends React.Component { ChangeUsernameDialog.propTypes = { closeDialog: PropTypes.func, - showDialog: PropTypes.func, + showDialog: PropTypes.bool, onChange: PropTypes.func, username: PropTypes.string, formData: PropTypes.object, diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css index f76970045..ff0b47cf1 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css +++ b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.css @@ -31,6 +31,10 @@ line-height: 30px; } + &.error { + border: solid 2px #FA4643; + } + &.disabled { background-color: #E0E0E0; } diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js index 7fa9a368a..34c314c20 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/InputField.js @@ -74,7 +74,7 @@ const InputField = ({ InputField.propTypes = { id: PropTypes.string, - disabled: PropTypes.boolean, + disabled: PropTypes.bool, label: PropTypes.string, type: PropTypes.string, name: PropTypes.string.isRequired, From ab02b1b6ca5ecce778f2f7bb785a34120c1a3c47 Mon Sep 17 00:00:00 2001 From: okbel Date: Thu, 26 Apr 2018 17:00:08 -0300 Subject: [PATCH 12/21] No empty username, no same username --- .../client/profile-settings/components/ChangeUsername.js | 5 ++--- .../client/profile-settings/components/InputField.css | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js index fbc8bfb1b..8423ed403 100644 --- a/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js +++ b/plugins/talk-plugin-auth/client/profile-settings/components/ChangeUsername.js @@ -120,7 +120,6 @@ class ChangeUsername extends React.Component { ) : null} )} - {editing ? (
    +