From e803593fc7fb204b2a2bcd5a598e38772662f259 Mon Sep 17 00:00:00 2001 From: gaba Date: Mon, 30 Jan 2017 11:34:04 -0800 Subject: [PATCH 01/17] Move stuff around. --- client/coral-embed-stream/src/Embed.js | 11 +- client/coral-framework/actions/auth.js | 14 ++ .../components/CreateDisplayNameDialog.js | 44 ++++++ client/coral-framework/components/styles.css | 140 ++++++++++++++++++ client/coral-framework/constants/auth.js | 3 + .../containers/ChangeDisplayNameContainer.js | 140 ++++++++++++++++++ client/coral-framework/reducers/auth.js | 8 + client/coral-framework/translations.json | 15 ++ services/users.js | 12 ++ 9 files changed, 378 insertions(+), 9 deletions(-) create mode 100644 client/coral-framework/components/CreateDisplayNameDialog.js create mode 100644 client/coral-framework/components/styles.css create mode 100644 client/coral-framework/containers/ChangeDisplayNameContainer.js diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index 5922266fa..b6fee1184 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -19,6 +19,7 @@ import Count from 'coral-plugin-comment-count/CommentCount'; import CommentBox from 'coral-plugin-commentbox/CommentBox'; import UserBox from '../../coral-sign-in/components/UserBox'; import SignInContainer from '../../coral-sign-in/containers/SignInContainer'; +import ChangeDisplayNameContainer from '../../coral-framework/containers/ChangeDisplayNameContainer'; import SuspendedAccount from '../../coral-framework/components/SuspendedAccount'; import SettingsContainer from '../../coral-settings/containers/SettingsContainer'; import RestrictedContent from '../../coral-framework/components/RestrictedContent'; @@ -51,15 +52,6 @@ class Embed extends Component { } componentDidMount () { - - // stream id, logged in user, settings - - // Set up messaging between embedded Iframe an parent component - - // this.props.getStream(path || window.location); - // this.path = window.location.href.split('#')[0]; - // - pym.sendMessage('childReady'); pym.onMessage('DOMContentLoaded', hash => { @@ -138,6 +130,7 @@ class Embed extends Component { :

{asset.settings.closedMessage}

} {!loggedIn && } + {loggedIn && } ({type: actions.SHOW_SIGNIN_DIALOG, offset}); export const hideSignInDialog = () => ({type: actions.HIDE_SIGNIN_DIALOG}); +export const showCreateDisplayNameDialog = () => ({type: actions.SHOW_CREATEDISPLAYNAME_DIALOG}); +export const hideCreateDisplayNameDialog = () => ({type: actions.HIDE_CREATEDISPLAYNAME_DIALOG}); +export const createDisplayName = (formData) => (dispatch) => { + coralApi('/users', {method: 'POST', body: formData}) + .then(() => { + dispatch(createDisplayNameSuccess()); + dispatch(hideCreateDisplayNameDialog()); + }) + .catch(() => dispatch(createDisplayNameFailure(lang.t('createdisplay.errorCreate')))); +}; +const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS}); +const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error}); + export const changeView = view => dispatch => dispatch({ type: actions.CHANGE_VIEW, @@ -59,6 +72,7 @@ export const facebookCallback = (err, data) => dispatch => { const user = JSON.parse(data); dispatch(signInFacebookSuccess(user)); dispatch(hideSignInDialog()); + dispatch(showCreateDisplayNameDialog()); dispatch(addItem(user, 'users')); } catch (err) { dispatch(signInFacebookFailure(err)); diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-framework/components/CreateDisplayNameDialog.js new file mode 100644 index 000000000..8b61989aa --- /dev/null +++ b/client/coral-framework/components/CreateDisplayNameDialog.js @@ -0,0 +1,44 @@ +import React from 'react'; +import {Dialog} from 'coral-ui'; +import styles from './styles.css'; +import I18n from 'coral-framework/modules/i18n/i18n'; +import translations from '../translations'; +const lang = new I18n(translations); + +const CreateDisplayNameDialog = ({open, handleClose, offset, loggedIn}) => ( + + × +
+
+

+ {lang.t('createdisplay.writeyourusername')} +

+ Logged {loggedIn} +
+
+
+); + +//
+// +//
+// +//
+// + +export default CreateDisplayNameDialog; diff --git a/client/coral-framework/components/styles.css b/client/coral-framework/components/styles.css new file mode 100644 index 000000000..f9d0aec6d --- /dev/null +++ b/client/coral-framework/components/styles.css @@ -0,0 +1,140 @@ +.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: 280px; + top: 10px; +} + +.header { + margin-bottom: 20px; +} + +.header h1, .separator h1{ + text-align: center; + font-size: 1.2em; +} + +.formField { + margin-top: 15px; +} + +.formField label { + font-size: 1.08em; + font-weight: bold; + margin-bottom: 5px; +} + +.formField input { + width: 100%; + display: block; + border: none; + outline: none; + border: 1px solid rgba(0,0,0,.12); + padding: 10px 6px; + box-sizing: border-box; + border-radius: 2px; + margin: 5px auto; +} + +.footer { + margin: 20px auto 10px; + text-align: center; +} + +.footer span { + display: block; + margin-bottom: 5px; +} + +.footer a { + color: #2c69b6; + cursor: pointer; + margin: 0 5px; +} + +.socialConnections { + margin-bottom: 20px; +} + +.signInButton { + margin-top: 10px; +} + +.close { + font-size: 20px; + line-height: 14px; + top: 10px; + right: 10px; + position: absolute; + display: block; + font-weight: bold; + color: #363636; + cursor: pointer; +} + +.close:hover { + color: #6b6b6b; +} + +input.error{ + border: solid 2px #f44336; +} + +.errorMsg, .hint { + color: grey; + font-weight: 600; + padding: 3px 0 16px; +} + +.alert { + padding: 10px; + margin-bottom: 20px; + border-radius: 2px; +} + +.alert--success { + border: solid 1px #1ec00e; + background: #cbf1b8; + color: #006900; +} + +.alert--error { + background: #FFEBEE; + color: #B71C1C; +} + +.userBox { + padding: 10px 0 20px; + letter-spacing: 0.1px; +} + +.userBox a { + color: black; + font-weight: bold; + cursor: pointer; + margin: 0px; + margin-left: 4px; + padding-bottom: 2px; + border-bottom: solid 1px black; +} + +.attention { + display: inline-block; + width: 15px; + height: 15px; + background: #B71C1C; + color: #FFEBEE; + font-weight: bolder; + padding: 4px; + vertical-align: middle; + border-radius: 20px; + box-sizing: border-box; + font-size: 9px; + line-height: 7px; + text-align: center; + margin-right: 5px; +} + +.action { + margin-top: 15px; +} diff --git a/client/coral-framework/constants/auth.js b/client/coral-framework/constants/auth.js index 5742adf75..27fa8890f 100644 --- a/client/coral-framework/constants/auth.js +++ b/client/coral-framework/constants/auth.js @@ -4,6 +4,9 @@ export const CLEAN_STATE = 'CLEAN_STATE'; export const SHOW_SIGNIN_DIALOG = 'SHOW_SIGNIN_DIALOG'; export const HIDE_SIGNIN_DIALOG = 'HIDE_SIGNIN_DIALOG'; +export const SHOW_CREATEDISPLAYNAME_DIALOG = 'SHOW_CREATEDISPLAYNAME_DIALOG'; +export const HIDE_CREATEDISPLAYNAME_DIALOG = 'HIDE_CREATEDISPLAYNAME_DIALOG'; + export const FETCH_SIGNUP_REQUEST = 'FETCH_SIGNUP_REQUEST'; export const FETCH_SIGNUP_FAILURE = 'FETCH_SIGNUP_FAILURE'; export const FETCH_SIGNUP_SUCCESS = 'FETCH_SIGNUP_SUCCESS'; diff --git a/client/coral-framework/containers/ChangeDisplayNameContainer.js b/client/coral-framework/containers/ChangeDisplayNameContainer.js new file mode 100644 index 000000000..17e681388 --- /dev/null +++ b/client/coral-framework/containers/ChangeDisplayNameContainer.js @@ -0,0 +1,140 @@ +import React, {Component} from 'react'; +import {connect} from 'react-redux'; + +import CreateDisplayNameDialog from '../components/CreateDisplayNameDialog'; + +// import validate from 'coral-framework/helpers/validate'; +// import errorMsj from 'coral-framework/helpers/error'; +import I18n from 'coral-framework/modules/i18n/i18n'; +import translations from '../translations'; +const lang = new I18n(translations); + +import { + showCreateDisplayNameDialog, + hideCreateDisplayNameDialog, + invalidForm, + validForm, + createDisplayName +} from '../../coral-framework/actions/auth'; + +class ChangeDisplayNameContainer extends Component { + initialState = { + formData: { + displayName: '', + }, + errors: {}, + showErrors: false + }; + + constructor(props) { + super(props); + this.state = this.initialState; + this.handleChange = this.handleChange.bind(this); + this.handleSubmitForm = this.handleSubmitForm.bind(this); + this.handleClose = this.handleClose.bind(this); + this.addError = this.addError.bind(this); + } + + componentDidMount() { + const {formData} = this.state; + const errors = Object.keys(formData).reduce((map, prop) => { + map[prop] = lang.t('createdisplay.requiredField'); + return map; + }, {}); + this.setState({errors}); + } + + handleChange(e) { + const {name, value} = e.target; + this.setState(state => ({ + ...state, + formData: { + ...state.formData, + [name]: value + } + }), () => { + this.validation(name, value); + }); + } + + addError(name, error) { + return this.setState(state => ({ + errors: { + ...state.errors, + [name]: error + } + })); + } + + validation(name, value) { + const {addError} = this; + + if (!value.length) { + addError(name, lang.t('displayName.requiredField')); + } else { + const { [name]: prop, ...errors } = this.state.errors; // eslint-disable-line + // Removes Error + this.setState(state => ({...state, errors})); + } + } + + isCompleted() { + const {formData} = this.state; + return !Object.keys(formData).filter(prop => !formData[prop].length).length; + } + + displayErrors(show = true) { + this.setState({showErrors: show}); + } + + handleSubmitForm(e) { + e.preventDefault(); + const {errors} = this.state; + const {validForm, invalidForm} = this.props; + this.displayErrors(); + if (this.isCompleted() && !Object.keys(errors).length) { + createDisplayName(this.state.formData); + validForm(); + } else { + invalidForm(lang.t('signIn.checkTheForm')); + } + } + + handleClose() { + this.props.hideCreateDisplayNameDialog(); + } + + render() { + const {loggedIn, auth, offset, user} = this.props; + return ( +
+ +
+ ); + } +} + +const mapStateToProps = state => ({ + auth: state.auth.toJS() +}); + +const mapDispatchToProps = dispatch => ({ + createDisplayName: formData => dispatch(createDisplayName(formData)), + showCreateDisplayNameDialog: () => dispatch(showCreateDisplayNameDialog()), + hideCreateDisplayNameDialog: () => dispatch(hideCreateDisplayNameDialog()), + invalidForm: error => dispatch(invalidForm(error)), + validForm: () => dispatch(validForm()) +}); + +export default connect( + mapStateToProps, + mapDispatchToProps +)(ChangeDisplayNameContainer); diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js index 36f8e0764..ff0f72b4a 100644 --- a/client/coral-framework/reducers/auth.js +++ b/client/coral-framework/reducers/auth.js @@ -7,6 +7,7 @@ const initialState = Map({ isAdmin: false, user: null, showSignInDialog: false, + showCreateDisplayNameDialog: false, view: 'SIGNIN', error: '', passwordRequestSuccess: null, @@ -35,6 +36,13 @@ export default function auth (state = initialState, action) { passwordRequestSuccess: null, successSignUp: false })); + case actions.SHOW_CREATEDISPLAYNAME_DIALOG : + return state + .set('showCreateDisplayNameDialog', true); + case actions.HIDE_CREATEDISPLAYNAME_DIALOG : + return state.merge(Map({ + showCreateDisplayNameDialog: false + })); case actions.CHANGE_VIEW : return state .set('error', '') diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index 5bf9b40a9..5900aad3e 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -4,6 +4,14 @@ "successBioUpdate": "Your Bio has been updated", "contentNotAvailable": "This content is not available", "suspendedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information", + "createdisplay": { + "writeyourusername": "Write your username", + "yourusername": "Your username is publicly visible on all comments you post. A username is needed before you can post your first comment.", + "displayName": "Display Name", + "save": "Save", + "requiredField": "Required field", + "errorCreate": "Error when changing display name" + }, "error": { "email": "Not a valid E-Mail", "password": "Password must be at least 8 characters", @@ -26,6 +34,13 @@ "successBioUpdate": "Tu bio fue actualizada", "contentNotAvailable": "El contenido no se encuentra disponible", "suspendedAccountMsg": "Tu cuenta se encuentra suspendida. Esto significa que no puedes dar Like, Marcar o escribir commentarios. Por favor, contacta moderator@fakeurl for more information", + "createdisplay": { + "writeyourusername": "Escribe tu nombre", + "yourusername": "Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.", + "displayName": "Nombre", + "save": "Guardar", + "requiredField": "Campo necesario" + }, "error": { "email": "No es un email válido", "password": "La contraseña debe tener por lo menos 8 caracteres", diff --git a/services/users.js b/services/users.js index 0bf22e9e0..d1e7dce05 100644 --- a/services/users.js +++ b/services/users.js @@ -156,6 +156,18 @@ module.exports = class UsersService { }); } + static changeDisplayName(id, displayName) { + return UsersService.isValidDisplayName(displayName) + .then((displayName) => { // displayName is valid + return UserModel.update({id}, { + $inc: {__v: 1}, + $set: { + displayName: displayName + } + }); + }); + } + /** * Creates local users. * @param {Array} users Users to create From 80122dfdceb3cd190f1c3de82391efc8d4a9fc0f Mon Sep 17 00:00:00 2001 From: gaba Date: Tue, 31 Jan 2017 13:48:45 -0800 Subject: [PATCH 02/17] Adds formfield to components. --- client/coral-framework/components/FormField.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 client/coral-framework/components/FormField.js diff --git a/client/coral-framework/components/FormField.js b/client/coral-framework/components/FormField.js new file mode 100644 index 000000000..ceb2d939e --- /dev/null +++ b/client/coral-framework/components/FormField.js @@ -0,0 +1,18 @@ +import React from 'react'; +import styles from './styles.css'; + +const FormField = ({className, showErrors = false, errorMsg, label, ...props}) => ( +
+ + + {showErrors && errorMsg && !{errorMsg}} +
+); + +export default FormField; From a377f61bddf12e8ac4c905560eadf419951ab190 Mon Sep 17 00:00:00 2001 From: gaba Date: Tue, 31 Jan 2017 13:51:36 -0800 Subject: [PATCH 03/17] Adds service and endpoint to change displayname. --- routes/api/users/index.js | 9 +++++++++ services/users.js | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/routes/api/users/index.js b/routes/api/users/index.js index 3ea3f3213..50e09aba7 100644 --- a/routes/api/users/index.js +++ b/routes/api/users/index.js @@ -57,6 +57,15 @@ router.post('/:user_id/status', authorization.needed('ADMIN'), (req, res, next) .catch(next); }); +router.post('/:user_id/displayname', authorization.needed(), (req, res, next) => { + UsersService + .setDisplayName(req.params.user_id, req.body.displayName) + .then((status) => { + res.status(201).json(status); + }) + .catch(next); +}); + // /** // * SendEmailConfirmation sends a confirmation email to the user. // * @param {Request} req express request object diff --git a/services/users.js b/services/users.js index d1e7dce05..bc46c5e62 100644 --- a/services/users.js +++ b/services/users.js @@ -358,6 +358,24 @@ module.exports = class UsersService { return UserModel.update({id}, {$set: {status}}); } + /** + * Set the display name of a user. + * @param {String} id id of a user + * @param {String} displayName display name to set + * @param {Function} done callback after the operation is complete + */ + static setDisplayName(id, displayName) { + + // Check to see if that the displayName is not empty. + if (displayName.length < 1) { + + // User displayName is required! Error out here. + return Promise.reject(new Error('display name should not be empty')); + } + + return UserModel.update({id}, {$set: {'displayName': displayName}}); + } + /** * Finds a user with the id. * @param {String} id user id (uuid) From 37eae516416edd9cf51554fbaba535baee5cc095 Mon Sep 17 00:00:00 2001 From: gaba Date: Tue, 31 Jan 2017 13:52:40 -0800 Subject: [PATCH 04/17] Adds component to coral-framework to deal with the change of displayname. --- client/coral-framework/actions/auth.js | 18 +++++++--- client/coral-framework/actions/items.js | 1 - .../components/CreateDisplayNameDialog.js | 33 +++++++++---------- client/coral-framework/constants/auth.js | 6 ++++ client/coral-framework/constants/user.js | 1 + .../containers/ChangeDisplayNameContainer.js | 18 +++++----- client/coral-framework/reducers/auth.js | 11 +++++++ client/coral-framework/translations.json | 8 +++-- 8 files changed, 63 insertions(+), 33 deletions(-) diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index ee6f6a817..f99450901 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -3,22 +3,32 @@ import translations from './../translations'; const lang = new I18n(translations); import * as actions from '../constants/auth'; import coralApi, {base} from '../helpers/response'; -import {addItem} from './items'; +import {addItem, updateItem} from './items'; // Dialog Actions export const showSignInDialog = (offset = 0) => ({type: actions.SHOW_SIGNIN_DIALOG, offset}); export const hideSignInDialog = () => ({type: actions.HIDE_SIGNIN_DIALOG}); +export const createDisplayNameRequest = () => ({type: actions.CREATE_DISPLAYNAME_REQUEST}); export const showCreateDisplayNameDialog = () => ({type: actions.SHOW_CREATEDISPLAYNAME_DIALOG}); export const hideCreateDisplayNameDialog = () => ({type: actions.HIDE_CREATEDISPLAYNAME_DIALOG}); -export const createDisplayName = (formData) => (dispatch) => { - coralApi('/users', {method: 'POST', body: formData}) + +export const updateDisplayName = displayName => ({type: actions.UPDATE_DISPLAYNAME, displayName}); + +export const createDisplayName = (userId, formData) => dispatch => { + dispatch(createDisplayNameRequest()); + coralApi(`/users/${userId}/displayname`, {method: 'POST', body: formData}) .then(() => { dispatch(createDisplayNameSuccess()); dispatch(hideCreateDisplayNameDialog()); + dispatch(updateItem(userId, 'displayName', formData.displayName, 'users')); + dispatch(updateDisplayName(formData.displayName)); }) - .catch(() => dispatch(createDisplayNameFailure(lang.t('createdisplay.errorCreate')))); + .catch(() => { + dispatch(createDisplayNameFailure(lang.t('createdisplay.errorCreate'))); + }); }; + const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS}); const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error}); diff --git a/client/coral-framework/actions/items.js b/client/coral-framework/actions/items.js index e289e9f60..692ec5648 100644 --- a/client/coral-framework/actions/items.js +++ b/client/coral-framework/actions/items.js @@ -203,7 +203,6 @@ export function postItem (item, type, id, mutate) { parent_id: null } }).then(({data}) => { - console.log('it workt'); console.log(data); }); diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-framework/components/CreateDisplayNameDialog.js index 8b61989aa..02c6eae4d 100644 --- a/client/coral-framework/components/CreateDisplayNameDialog.js +++ b/client/coral-framework/components/CreateDisplayNameDialog.js @@ -1,11 +1,13 @@ import React from 'react'; +import FormField from './FormField'; +import Button from 'coral-ui/components/Button'; import {Dialog} from 'coral-ui'; import styles from './styles.css'; import I18n from 'coral-framework/modules/i18n/i18n'; import translations from '../translations'; const lang = new I18n(translations); -const CreateDisplayNameDialog = ({open, handleClose, offset, loggedIn}) => ( +const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSubmitDisplayName, handleChange}) => ( (

{lang.t('createdisplay.writeyourusername')}

- Logged {loggedIn} + +
+

{lang.t('createdisplay.yourusername')}

+
+ + +
); -//
-// -//
-// -//
-// - export default CreateDisplayNameDialog; diff --git a/client/coral-framework/constants/auth.js b/client/coral-framework/constants/auth.js index 27fa8890f..a61975420 100644 --- a/client/coral-framework/constants/auth.js +++ b/client/coral-framework/constants/auth.js @@ -4,6 +4,10 @@ export const CLEAN_STATE = 'CLEAN_STATE'; export const SHOW_SIGNIN_DIALOG = 'SHOW_SIGNIN_DIALOG'; export const HIDE_SIGNIN_DIALOG = 'HIDE_SIGNIN_DIALOG'; +export const CREATE_DISPLAYNAME_REQUEST = 'CREATE_DISPLAYNAME_REQUEST'; +export const CREATEDISPLAYNAME_SUCCESS = 'CREATEDISPLAYNAME_SUCCESS'; +export const CREATEDISPLAYNAME_FAILURE = 'CREATEDISPLAYNAME_FAILURE'; +export const CREATE_DISPLAYNAME = 'CREATE_DISPLAYNAME'; export const SHOW_CREATEDISPLAYNAME_DIALOG = 'SHOW_CREATEDISPLAYNAME_DIALOG'; export const HIDE_CREATEDISPLAYNAME_DIALOG = 'HIDE_CREATEDISPLAYNAME_DIALOG'; @@ -35,3 +39,5 @@ export const CHECK_LOGIN_SUCCESS = 'CHECK_LOGIN_SUCCESS'; export const CHECK_LOGIN_FAILURE = 'CHECK_LOGIN_FAILURE'; export const CHECK_CSRF_TOKEN = 'CHECK_CSRF_TOKEN'; + +export const UPDATE_DISPLAYNAME = 'UPDATE_DISPLAYNAME'; diff --git a/client/coral-framework/constants/user.js b/client/coral-framework/constants/user.js index 9c6f508fe..57f4e706b 100644 --- a/client/coral-framework/constants/user.js +++ b/client/coral-framework/constants/user.js @@ -5,3 +5,4 @@ export const COMMENTS_BY_USER_REQUEST = 'COMMENTS_BY_USER_REQUEST'; export const COMMENTS_BY_USER_SUCCESS = 'COMMENTS_BY_USER_SUCCESS'; export const COMMENTS_BY_USER_FAILURE = 'COMMENTS_BY_USER_FAILURE'; export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS'; +export const UPDATE_DISPLAYNAME = 'UPDATE_DISPLAYNAME'; diff --git a/client/coral-framework/containers/ChangeDisplayNameContainer.js b/client/coral-framework/containers/ChangeDisplayNameContainer.js index 17e681388..e252119de 100644 --- a/client/coral-framework/containers/ChangeDisplayNameContainer.js +++ b/client/coral-framework/containers/ChangeDisplayNameContainer.js @@ -30,12 +30,13 @@ class ChangeDisplayNameContainer extends Component { super(props); this.state = this.initialState; this.handleChange = this.handleChange.bind(this); - this.handleSubmitForm = this.handleSubmitForm.bind(this); + this.handleSubmitDisplayName = this.handleSubmitDisplayName.bind(this); this.handleClose = this.handleClose.bind(this); this.addError = this.addError.bind(this); } componentDidMount() { + window.authCallback = this.props.facebookCallback; const {formData} = this.state; const errors = Object.keys(formData).reduce((map, prop) => { map[prop] = lang.t('createdisplay.requiredField'); @@ -70,7 +71,7 @@ class ChangeDisplayNameContainer extends Component { const {addError} = this; if (!value.length) { - addError(name, lang.t('displayName.requiredField')); + addError(name, lang.t('createdisplay.requiredField')); } else { const { [name]: prop, ...errors } = this.state.errors; // eslint-disable-line // Removes Error @@ -87,16 +88,16 @@ class ChangeDisplayNameContainer extends Component { this.setState({showErrors: show}); } - handleSubmitForm(e) { + handleSubmitDisplayName(e) { e.preventDefault(); const {errors} = this.state; const {validForm, invalidForm} = this.props; this.displayErrors(); if (this.isCompleted() && !Object.keys(errors).length) { - createDisplayName(this.state.formData); + this.props.createDisplayName(this.props.user.id, this.state.formData); validForm(); } else { - invalidForm(lang.t('signIn.checkTheForm')); + invalidForm(lang.t('createdisplay.checkTheForm')); } } @@ -105,15 +106,16 @@ class ChangeDisplayNameContainer extends Component { } render() { - const {loggedIn, auth, offset, user} = this.props; + const {loggedIn, auth, offset} = this.props; return (
@@ -127,7 +129,7 @@ const mapStateToProps = state => ({ }); const mapDispatchToProps = dispatch => ({ - createDisplayName: formData => dispatch(createDisplayName(formData)), + createDisplayName: (userid, formData) => dispatch(createDisplayName(userid, formData)), showCreateDisplayNameDialog: () => dispatch(showCreateDisplayNameDialog()), hideCreateDisplayNameDialog: () => dispatch(hideCreateDisplayNameDialog()), invalidForm: error => dispatch(invalidForm(error)), diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js index ff0f72b4a..cb7b102df 100644 --- a/client/coral-framework/reducers/auth.js +++ b/client/coral-framework/reducers/auth.js @@ -43,6 +43,14 @@ export default function auth (state = initialState, action) { return state.merge(Map({ showCreateDisplayNameDialog: false })); + case actions.CREATEDISPLAYNAME_SUCCESS : + return state.merge(Map({ + showCreateDisplayNameDialog: false, + error: '' + })); + case actions.CREATEDISPLAYNAME_FAILURE : + return state + .set('error', action.error); case actions.CHANGE_VIEW : return state .set('error', '') @@ -109,6 +117,9 @@ export default function auth (state = initialState, action) { return state .set('passwordRequestFailure', 'There was an error sending your password reset email. Please try again soon!') .set('passwordRequestSuccess', null); + case actions.UPDATE_DISPLAYNAME: + return state + .merge({'user': {'displayName': action.displayName}}); default : return state; } diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index 5900aad3e..0e191d89d 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -10,7 +10,8 @@ "displayName": "Display Name", "save": "Save", "requiredField": "Required field", - "errorCreate": "Error when changing display name" + "errorCreate": "Error when changing display name", + "checkTheForm": "Invalid Form. Please, check the fields" }, "error": { "email": "Not a valid E-Mail", @@ -37,9 +38,10 @@ "createdisplay": { "writeyourusername": "Escribe tu nombre", "yourusername": "Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.", - "displayName": "Nombre", + "displayName": "Nombre a mostrar", "save": "Guardar", - "requiredField": "Campo necesario" + "requiredField": "Campo necesario", + "checkTheForm": "Formulario Invalido. Por favor, verifica los campos" }, "error": { "email": "No es un email válido", From 282c7dc4f5ff861e46fa29173b8d00e1ce2632bd Mon Sep 17 00:00:00 2001 From: gaba Date: Tue, 31 Jan 2017 14:04:31 -0800 Subject: [PATCH 05/17] Removes duplicate func and adds tests. --- client/coral-embed-stream/src/Embed.js | 4 ++-- services/users.js | 26 ++++++-------------------- test/services/users.js | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index b6fee1184..1eec07213 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -98,7 +98,7 @@ class Embed extends Component { Settings Configure Stream - {loggedIn && } + {loggedIn && user && } { asset.closedAt === null @@ -130,7 +130,7 @@ class Embed extends Component { :

{asset.settings.closedMessage}

} {!loggedIn && } - {loggedIn && } + {loggedIn && user && } { // displayName is valid - return UserModel.update({id}, { - $inc: {__v: 1}, - $set: { - displayName: displayName - } - }); - }); - } - /** * Creates local users. * @param {Array} users Users to create @@ -366,14 +354,12 @@ module.exports = class UsersService { */ static setDisplayName(id, displayName) { - // Check to see if that the displayName is not empty. - if (displayName.length < 1) { - - // User displayName is required! Error out here. - return Promise.reject(new Error('display name should not be empty')); - } - - return UserModel.update({id}, {$set: {'displayName': displayName}}); + return UsersService.isValidDisplayName(displayName) + .then((displayName) => { // displayName is valid + return UserModel.update( + {id}, + {$set: {'displayName': displayName}}); + }); } /** diff --git a/test/services/users.js b/test/services/users.js index e2e5655e4..ba2bedcc3 100644 --- a/test/services/users.js +++ b/test/services/users.js @@ -178,6 +178,25 @@ describe('services.UsersService', () => { }); }); + describe('#setDisplayName', () => { + it('should set the display name to a new unique one', () => { + return UsersService + .setDisplayName(mockUsers[0].id, 'maria') + .then(() => UsersService.findById(mockUsers[0].id)) + .then((user) => { + expect(user).to.have.property('displayName', 'maria'); + }); + }); + + it('should return an error when the displayName is not unique', () => { + return UsersService + .setDisplayName(mockUsers[0].id, 'marvel') + .catch((error) => { + expect(error).to.not.be.null; + }); + }); + }); + describe('#ban', () => { it('should set the status to banned', () => { return UsersService From c9b12fc5d649750b745690fcc53b079a45b1214b Mon Sep 17 00:00:00 2001 From: gaba Date: Wed, 1 Feb 2017 10:46:32 -0800 Subject: [PATCH 06/17] Thanks git-godesses for the log on finding a bad remove when merging. --- client/coral-framework/actions/auth.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index ab8a7caea..b0574e04c 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -91,6 +91,7 @@ export const facebookCallback = (err, data) => dispatch => { const user = JSON.parse(data); dispatch(signInFacebookSuccess(user)); dispatch(hideSignInDialog()); + dispatch(showCreateDisplayNameDialog()); } catch (err) { dispatch(signInFacebookFailure(err)); return; From a8e4ce466d26b8eef1735b4fae3336fca58e1019 Mon Sep 17 00:00:00 2001 From: gaba Date: Wed, 1 Feb 2017 12:09:27 -0800 Subject: [PATCH 07/17] Adds validation to the dialog. --- client/coral-framework/components/Alert.js | 13 +++++++++++++ .../components/CreateDisplayNameDialog.js | 4 +++- .../containers/ChangeDisplayNameContainer.js | 7 +++++-- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 client/coral-framework/components/Alert.js diff --git a/client/coral-framework/components/Alert.js b/client/coral-framework/components/Alert.js new file mode 100644 index 000000000..019c3456a --- /dev/null +++ b/client/coral-framework/components/Alert.js @@ -0,0 +1,13 @@ +import React from 'react'; +import styles from './styles.css'; + +const Alert = ({cStyle = 'error', children, className, ...props}) => ( +
+ {children} +
+); + +export default Alert; diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-framework/components/CreateDisplayNameDialog.js index 02c6eae4d..8b4a99f9a 100644 --- a/client/coral-framework/components/CreateDisplayNameDialog.js +++ b/client/coral-framework/components/CreateDisplayNameDialog.js @@ -1,5 +1,6 @@ import React from 'react'; import FormField from './FormField'; +import Alert from './Alert'; import Button from 'coral-ui/components/Button'; import {Dialog} from 'coral-ui'; import styles from './styles.css'; @@ -7,7 +8,7 @@ import I18n from 'coral-framework/modules/i18n/i18n'; import translations from '../translations'; const lang = new I18n(translations); -const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSubmitDisplayName, handleChange}) => ( +const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSubmitDisplayName, handleChange, ...props}) => (

{lang.t('createdisplay.yourusername')}

+ { props.auth.error && {props.auth.error} }
Date: Wed, 1 Feb 2017 12:34:02 -0800 Subject: [PATCH 08/17] Adds errors on field when not validated. --- .../coral-framework/components/CreateDisplayNameDialog.js | 1 + .../containers/ChangeDisplayNameContainer.js | 6 ------ client/coral-framework/translations.json | 7 +++++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-framework/components/CreateDisplayNameDialog.js index 8b4a99f9a..6798bad5c 100644 --- a/client/coral-framework/components/CreateDisplayNameDialog.js +++ b/client/coral-framework/components/CreateDisplayNameDialog.js @@ -28,6 +28,7 @@ const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSub

{lang.t('createdisplay.yourusername')}

{ props.auth.error && {props.auth.error} } + { props.errors.displayName && {lang.t('createdisplay.specialCharacters')} } { - map[prop] = lang.t('createdisplay.requiredField'); - return map; - }, {}); - this.setState({errors}); } handleChange(e) { diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index c08c7e717..88886f8d1 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -11,7 +11,8 @@ "save": "Save", "requiredField": "Required field", "errorCreate": "Error when changing display name", - "checkTheForm": "Invalid Form. Please, check the fields" + "checkTheForm": "Invalid Form. Please, check the fields", + "specialCharacters": "Display names can contain letters, numbers and _ only" }, "error": { "emailNotVerified": "Email address {0} not verified.", @@ -42,7 +43,9 @@ "displayName": "Nombre a mostrar", "save": "Guardar", "requiredField": "Campo necesario", - "checkTheForm": "Formulario Invalido. Por favor, verifica los campos" + "errorCreate": "Hubo un error al cambiar el nombre de usuario", + "checkTheForm": "Formulario Invalido. Por favor, verifica los campos", + "specialCharacters": "Sólo pueden contener letras, números y _" }, "error": { "emailNotVerified": "Dirección de correo electrónico {0} no verificada.", From 0c360e62a64d8b5a98c80ae033ffd6c47ae25a22 Mon Sep 17 00:00:00 2001 From: gaba Date: Wed, 1 Feb 2017 13:20:17 -0800 Subject: [PATCH 09/17] Display errors that come from the backend. --- client/coral-framework/actions/auth.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index b0574e04c..bd3b81fdf 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -22,8 +22,8 @@ export const createDisplayName = (userId, formData) => dispatch => { dispatch(hideCreateDisplayNameDialog()); dispatch(updateDisplayName(formData.displayName)); }) - .catch(() => { - dispatch(createDisplayNameFailure(lang.t('createdisplay.errorCreate'))); + .catch(error => { + dispatch(createDisplayNameFailure(lang.t(`error.${error.message}`))); }); }; From 4df09ffbd2728b978cfdb875db833a7cf7d184fb Mon Sep 17 00:00:00 2001 From: gaba Date: Wed, 1 Feb 2017 13:29:47 -0800 Subject: [PATCH 10/17] Validation for the field underneath. --- .../coral-framework/components/CreateDisplayNameDialog.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-framework/components/CreateDisplayNameDialog.js index 6798bad5c..ee3e133e6 100644 --- a/client/coral-framework/components/CreateDisplayNameDialog.js +++ b/client/coral-framework/components/CreateDisplayNameDialog.js @@ -28,7 +28,6 @@ const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSub

{lang.t('createdisplay.yourusername')}

{ props.auth.error && {props.auth.error} } - { props.errors.displayName && {lang.t('createdisplay.specialCharacters')} } - - + { props.errors.displayName && {lang.t('createdisplay.specialCharacters')} } +
+ +
+
From 445eb97d7647dd25fa35e01980d1234e2c8a4679 Mon Sep 17 00:00:00 2001 From: gaba Date: Wed, 1 Feb 2017 14:00:09 -0800 Subject: [PATCH 11/17] Moves create displayname dialog to sign-in plugin. --- client/coral-embed-stream/src/Embed.js | 2 +- client/coral-framework/actions/auth.js | 6 +- client/coral-framework/components/Alert.js | 13 -- .../coral-framework/components/FormField.js | 18 --- client/coral-framework/components/styles.css | 140 ------------------ client/coral-framework/translations.json | 20 --- .../components/CreateDisplayNameDialog.js | 6 +- .../containers/ChangeDisplayNameContainer.js | 0 client/coral-sign-in/translations.js | 24 ++- 9 files changed, 29 insertions(+), 200 deletions(-) delete mode 100644 client/coral-framework/components/Alert.js delete mode 100644 client/coral-framework/components/FormField.js delete mode 100644 client/coral-framework/components/styles.css rename client/{coral-framework => coral-sign-in}/components/CreateDisplayNameDialog.js (84%) rename client/{coral-framework => coral-sign-in}/containers/ChangeDisplayNameContainer.js (100%) diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index a5011f853..43b4eecae 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -19,7 +19,7 @@ import Count from 'coral-plugin-comment-count/CommentCount'; import CommentBox from 'coral-plugin-commentbox/CommentBox'; import UserBox from '../../coral-sign-in/components/UserBox'; import SignInContainer from '../../coral-sign-in/containers/SignInContainer'; -import ChangeDisplayNameContainer from '../../coral-framework/containers/ChangeDisplayNameContainer'; +import ChangeDisplayNameContainer from '../../coral-sign-in/containers/ChangeDisplayNameContainer'; import SuspendedAccount from '../../coral-framework/components/SuspendedAccount'; import SettingsContainer from '../../coral-settings/containers/SettingsContainer'; import RestrictedContent from '../../coral-framework/components/RestrictedContent'; diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index bd3b81fdf..914b88095 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -12,6 +12,9 @@ export const createDisplayNameRequest = () => ({type: actions.CREATE_DISPLAYNAME export const showCreateDisplayNameDialog = () => ({type: actions.SHOW_CREATEDISPLAYNAME_DIALOG}); export const hideCreateDisplayNameDialog = () => ({type: actions.HIDE_CREATEDISPLAYNAME_DIALOG}); +const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS}); +const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error}); + export const updateDisplayName = displayName => ({type: actions.UPDATE_DISPLAYNAME, displayName}); export const createDisplayName = (userId, formData) => dispatch => { @@ -27,9 +30,6 @@ export const createDisplayName = (userId, formData) => dispatch => { }); }; -const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS}); -const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error}); - export const changeView = view => dispatch => dispatch({ type: actions.CHANGE_VIEW, diff --git a/client/coral-framework/components/Alert.js b/client/coral-framework/components/Alert.js deleted file mode 100644 index 019c3456a..000000000 --- a/client/coral-framework/components/Alert.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import styles from './styles.css'; - -const Alert = ({cStyle = 'error', children, className, ...props}) => ( -
- {children} -
-); - -export default Alert; diff --git a/client/coral-framework/components/FormField.js b/client/coral-framework/components/FormField.js deleted file mode 100644 index ceb2d939e..000000000 --- a/client/coral-framework/components/FormField.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import styles from './styles.css'; - -const FormField = ({className, showErrors = false, errorMsg, label, ...props}) => ( -
- - - {showErrors && errorMsg && !{errorMsg}} -
-); - -export default FormField; diff --git a/client/coral-framework/components/styles.css b/client/coral-framework/components/styles.css deleted file mode 100644 index f9d0aec6d..000000000 --- a/client/coral-framework/components/styles.css +++ /dev/null @@ -1,140 +0,0 @@ -.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: 280px; - top: 10px; -} - -.header { - margin-bottom: 20px; -} - -.header h1, .separator h1{ - text-align: center; - font-size: 1.2em; -} - -.formField { - margin-top: 15px; -} - -.formField label { - font-size: 1.08em; - font-weight: bold; - margin-bottom: 5px; -} - -.formField input { - width: 100%; - display: block; - border: none; - outline: none; - border: 1px solid rgba(0,0,0,.12); - padding: 10px 6px; - box-sizing: border-box; - border-radius: 2px; - margin: 5px auto; -} - -.footer { - margin: 20px auto 10px; - text-align: center; -} - -.footer span { - display: block; - margin-bottom: 5px; -} - -.footer a { - color: #2c69b6; - cursor: pointer; - margin: 0 5px; -} - -.socialConnections { - margin-bottom: 20px; -} - -.signInButton { - margin-top: 10px; -} - -.close { - font-size: 20px; - line-height: 14px; - top: 10px; - right: 10px; - position: absolute; - display: block; - font-weight: bold; - color: #363636; - cursor: pointer; -} - -.close:hover { - color: #6b6b6b; -} - -input.error{ - border: solid 2px #f44336; -} - -.errorMsg, .hint { - color: grey; - font-weight: 600; - padding: 3px 0 16px; -} - -.alert { - padding: 10px; - margin-bottom: 20px; - border-radius: 2px; -} - -.alert--success { - border: solid 1px #1ec00e; - background: #cbf1b8; - color: #006900; -} - -.alert--error { - background: #FFEBEE; - color: #B71C1C; -} - -.userBox { - padding: 10px 0 20px; - letter-spacing: 0.1px; -} - -.userBox a { - color: black; - font-weight: bold; - cursor: pointer; - margin: 0px; - margin-left: 4px; - padding-bottom: 2px; - border-bottom: solid 1px black; -} - -.attention { - display: inline-block; - width: 15px; - height: 15px; - background: #B71C1C; - color: #FFEBEE; - font-weight: bolder; - padding: 4px; - vertical-align: middle; - border-radius: 20px; - box-sizing: border-box; - font-size: 9px; - line-height: 7px; - text-align: center; - margin-right: 5px; -} - -.action { - margin-top: 15px; -} diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index 88886f8d1..07b719f6b 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -4,16 +4,6 @@ "successBioUpdate": "Your Bio has been updated", "contentNotAvailable": "This content is not available", "suspendedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information", - "createdisplay": { - "writeyourusername": "Write your username", - "yourusername": "Your username is publicly visible on all comments you post. A username is needed before you can post your first comment.", - "displayName": "Display Name", - "save": "Save", - "requiredField": "Required field", - "errorCreate": "Error when changing display name", - "checkTheForm": "Invalid Form. Please, check the fields", - "specialCharacters": "Display names can contain letters, numbers and _ only" - }, "error": { "emailNotVerified": "Email address {0} not verified.", "email": "Not a valid E-Mail", @@ -37,16 +27,6 @@ "successBioUpdate": "Tu bio fue actualizada", "contentNotAvailable": "El contenido no se encuentra disponible", "suspendedAccountMsg": "Tu cuenta se encuentra suspendida. Esto significa que no puedes dar Like, Marcar o escribir commentarios. Por favor, contacta moderator@fakeurl for more information", - "createdisplay": { - "writeyourusername": "Escribe tu nombre", - "yourusername": "Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.", - "displayName": "Nombre a mostrar", - "save": "Guardar", - "requiredField": "Campo necesario", - "errorCreate": "Hubo un error al cambiar el nombre de usuario", - "checkTheForm": "Formulario Invalido. Por favor, verifica los campos", - "specialCharacters": "Sólo pueden contener letras, números y _" - }, "error": { "emailNotVerified": "Dirección de correo electrónico {0} no verificada.", "email": "No es un email válido", diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-sign-in/components/CreateDisplayNameDialog.js similarity index 84% rename from client/coral-framework/components/CreateDisplayNameDialog.js rename to client/coral-sign-in/components/CreateDisplayNameDialog.js index ee3e133e6..4d8ef9fb3 100644 --- a/client/coral-framework/components/CreateDisplayNameDialog.js +++ b/client/coral-sign-in/components/CreateDisplayNameDialog.js @@ -1,5 +1,5 @@ import React from 'react'; -import FormField from './FormField'; +import FormField from 'coral-ui/components/FormField'; import Alert from './Alert'; import Button from 'coral-ui/components/Button'; import {Dialog} from 'coral-ui'; @@ -25,7 +25,7 @@ const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSub
-

{lang.t('createdisplay.yourusername')}

+ { props.auth.error && {props.auth.error} }
- { props.errors.displayName && {lang.t('createdisplay.specialCharacters')} } + { props.errors.displayName && {lang.t('createdisplay.specialCharacters')} }
diff --git a/client/coral-framework/containers/ChangeDisplayNameContainer.js b/client/coral-sign-in/containers/ChangeDisplayNameContainer.js similarity index 100% rename from client/coral-framework/containers/ChangeDisplayNameContainer.js rename to client/coral-sign-in/containers/ChangeDisplayNameContainer.js diff --git a/client/coral-sign-in/translations.js b/client/coral-sign-in/translations.js index 137141d34..5751370a6 100644 --- a/client/coral-sign-in/translations.js +++ b/client/coral-sign-in/translations.js @@ -26,7 +26,17 @@ export default { passwordsDontMatch: 'Passwords don\'t match.', specialCharacters: 'Display names can contain letters, numbers and _ only', checkTheForm: 'Invalid Form. Please, check the fields' - } + }, + 'createdisplay': { + writeyourusername: 'Write your username', + yourusername: 'Your username is publicly visible on all comments you post. A username is needed before you can post your first comment.', + displayName: 'Display Name', + save: 'Save', + requiredField: 'Required field', + errorCreate: 'Error when changing display name', + checkTheForm: 'Invalid Form. Please, check the fields', + specialCharacters: 'Display names can contain letters, numbers and _ only' + }, }, es: { 'signIn': { @@ -55,6 +65,16 @@ export default { passwordsDontMatch: 'Las contraseñas no coinciden', specialCharacters: 'Los nombres pueden contener letras, números y _', checkTheForm: 'Formulario Inválido. Por favor, completa los campos' - } + }, + 'createdisplay': { + writeyourusername: 'Escribe tu nombre', + yourusername: 'Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.', + displayName: 'Nombre a mostrar', + save: 'Guardar', + requiredField: 'Campo necesario', + errorCreate: 'Hubo un error al cambiar el nombre de usuario', + checkTheForm: 'Formulario Invalido. Por favor, verifica los campos', + specialCharacters: 'Sólo pueden contener letras, números y _' + }, } }; From c272b8834023dd9ebcdc3cec5f0367944a322e81 Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 2 Feb 2017 15:24:55 -0800 Subject: [PATCH 12/17] It returns user now. --- routes/api/users/index.js | 4 ++-- services/users.js | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/routes/api/users/index.js b/routes/api/users/index.js index a7164dd7d..1c7bc7bb2 100644 --- a/routes/api/users/index.js +++ b/routes/api/users/index.js @@ -62,8 +62,8 @@ router.post('/:user_id/status', authorization.needed('ADMIN'), (req, res, next) router.post('/:user_id/displayname', authorization.needed(), (req, res, next) => { UsersService.setDisplayName(req.params.user_id, req.body.displayName) - .then(() => { - res.status(204).end(); + .then((user) => { + res.status(201).json(user); }) .catch(next); }); diff --git a/services/users.js b/services/users.js index c1a31bd45..1876abb7a 100644 --- a/services/users.js +++ b/services/users.js @@ -365,7 +365,10 @@ module.exports = class UsersService { .then((displayName) => { // displayName is valid return UserModel.update( {id}, - {$set: {'displayName': displayName}}); + {$set: {'displayName': displayName}}) + .then(() => { + return UserModel.findOne({'id': id}); + }); }); } From d74d2e9e87b64f5051b129e2153fb3dff15f7e5d Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 2 Feb 2017 15:25:45 -0800 Subject: [PATCH 13/17] Dispatchs the user. --- client/coral-framework/actions/auth.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index 914b88095..d21870ac5 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -20,10 +20,10 @@ export const updateDisplayName = displayName => ({type: actions.UPDATE_DISPLAYNA export const createDisplayName = (userId, formData) => dispatch => { dispatch(createDisplayNameRequest()); coralApi(`/users/${userId}/displayname`, {method: 'POST', body: formData}) - .then(() => { + .then((user) => { dispatch(createDisplayNameSuccess()); dispatch(hideCreateDisplayNameDialog()); - dispatch(updateDisplayName(formData.displayName)); + dispatch(updateDisplayName(user)); }) .catch(error => { dispatch(createDisplayNameFailure(lang.t(`error.${error.message}`))); From 7da141ed29ab569cd683b4220cff0fcde4189cad Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 2 Feb 2017 15:44:45 -0800 Subject: [PATCH 14/17] Dispatch other action to only trigger change when sign up. --- client/coral-framework/actions/auth.js | 13 +++++++++++++ client/coral-framework/constants/auth.js | 1 + client/coral-framework/reducers/auth.js | 11 +++++++++-- client/coral-sign-in/components/SignUpContent.js | 2 +- .../containers/ChangeDisplayNameContainer.js | 6 +----- client/coral-sign-in/containers/SignInContainer.js | 2 ++ 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index d21870ac5..edd04de12 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -82,6 +82,19 @@ export const fetchSignInFacebook = () => dispatch => { ); }; +// Sign Up Facebook + +const signUpFacebookRequest = () => ({type: actions.FETCH_SIGNUP_FACEBOOK_REQUEST}); + +export const fetchSignUpFacebook = () => dispatch => { + dispatch(signUpFacebookRequest()); + window.open( + `${base}/auth/facebook`, + 'Continue with Facebook', + 'menubar=0,resizable=0,width=500,height=500,top=200,left=500' + ); +}; + export const facebookCallback = (err, data) => dispatch => { if (err) { signInFacebookFailure(err); diff --git a/client/coral-framework/constants/auth.js b/client/coral-framework/constants/auth.js index 651c82cd1..2b5f762c1 100644 --- a/client/coral-framework/constants/auth.js +++ b/client/coral-framework/constants/auth.js @@ -23,6 +23,7 @@ export const FETCH_SIGNIN_FACEBOOK_REQUEST = 'FETCH_SIGNIN_FACEBOOK_REQUEST'; export const FETCH_SIGNIN_FACEBOOK_FAILURE = 'FETCH_SIGNIN_FACEBOOK_FAILURE'; export const FETCH_SIGNIN_FACEBOOK_SUCCESS = 'FETCH_SIGNIN_FACEBOOK_SUCCESS'; +export const FETCH_SIGNUP_FACEBOOK_REQUEST = 'FETCH_SIGNUP_FACEBOOK_REQUEST'; export const FETCH_FORGOT_PASSWORD_REQUEST = 'FETCH_FORGOT_PASSWORD_REQUEST'; export const FETCH_FORGOT_PASSWORD_SUCCESS = 'FETCH_FORGOT_PASSWORD_SUCCESS'; export const FETCH_FORGOT_PASSWORD_FAILURE = 'FETCH_FORGOT_PASSWORD_FAILURE'; diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js index dfbaede90..2da589507 100644 --- a/client/coral-framework/reducers/auth.js +++ b/client/coral-framework/reducers/auth.js @@ -15,7 +15,8 @@ const initialState = Map({ emailConfirmationFailure: false, emailConfirmationLoading: false, emailConfirmationSuccess: false, - successSignUp: false + successSignUp: false, + fromSignUp: false }); const purge = user => { @@ -88,6 +89,12 @@ export default function auth (state = initialState, action) { .set('isLoading', false) .set('error', action.error) .set('user', null); + case actions.FETCH_SIGNUP_FACEBOOK_REQUEST: + return state + .set('fromSignUp', true); + case actions.FETCH_SIGNIN_FACEBOOK_REQUEST: + return state + .set('fromSignUp', false); case actions.FETCH_SIGNIN_FACEBOOK_SUCCESS: return state .set('user', purge(action.user)) @@ -125,7 +132,7 @@ export default function auth (state = initialState, action) { .set('passwordRequestSuccess', null); case actions.UPDATE_DISPLAYNAME: return state - .merge({'user': {'displayName': action.displayName}}); + .set('user', purge(action.displayName)); case actions.EMAIL_CONFIRM_ERROR: return state .set('emailConfirmationFailure', true) diff --git a/client/coral-sign-in/components/SignUpContent.js b/client/coral-sign-in/components/SignUpContent.js index 246d9d884..80a6fcde4 100644 --- a/client/coral-sign-in/components/SignUpContent.js +++ b/client/coral-sign-in/components/SignUpContent.js @@ -14,7 +14,7 @@ const SignUpContent = ({handleChange, formData, ...props}) => (
-
diff --git a/client/coral-sign-in/containers/ChangeDisplayNameContainer.js b/client/coral-sign-in/containers/ChangeDisplayNameContainer.js index b1dcde6a6..bc7fe8267 100644 --- a/client/coral-sign-in/containers/ChangeDisplayNameContainer.js +++ b/client/coral-sign-in/containers/ChangeDisplayNameContainer.js @@ -36,10 +36,6 @@ class ChangeDisplayNameContainer extends Component { this.addError = this.addError.bind(this); } - componentDidMount() { - window.authCallback = this.props.facebookCallback; - } - handleChange(e) { const {name, value} = e.target; this.setState(state => ({ @@ -107,7 +103,7 @@ class ChangeDisplayNameContainer extends Component { return (
({ fetchSignUp: formData => dispatch(fetchSignUp(formData)), fetchSignIn: formData => dispatch(fetchSignIn(formData)), fetchSignInFacebook: () => dispatch(fetchSignInFacebook()), + fetchSignUpFacebook: () => dispatch(fetchSignUpFacebook()), fetchForgotPassword: formData => dispatch(fetchForgotPassword(formData)), requestConfirmEmail: email => dispatch(requestConfirmEmail(email)), showSignInDialog: () => dispatch(showSignInDialog()), From b5c9c1c73143a6e219fee80386d423b12d0fcda2 Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 2 Feb 2017 16:03:14 -0800 Subject: [PATCH 15/17] Returns the real displayname and not the one transformed. --- services/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/users.js b/services/users.js index 1876abb7a..fd39a50c1 100644 --- a/services/users.js +++ b/services/users.js @@ -362,7 +362,7 @@ module.exports = class UsersService { static setDisplayName(id, displayName) { return UsersService.isValidDisplayName(displayName) - .then((displayName) => { // displayName is valid + .then(() => { // displayName is valid return UserModel.update( {id}, {$set: {'displayName': displayName}}) From a6f7cf258b7efdf0515c4468212431d28946f572 Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Fri, 3 Feb 2017 10:15:51 -0700 Subject: [PATCH 16/17] attempt to make e2e tests pass --- client/coral-sign-in/components/SignUpContent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-sign-in/components/SignUpContent.js b/client/coral-sign-in/components/SignUpContent.js index 80a6fcde4..2739c27a7 100644 --- a/client/coral-sign-in/components/SignUpContent.js +++ b/client/coral-sign-in/components/SignUpContent.js @@ -77,7 +77,7 @@ const SignUpContent = ({handleChange, formData, ...props}) => (
{lang.t('signIn.alreadyHaveAnAccount')} - props.changeView('SIGNIN')}> + props.changeView('SIGNIN')}> {lang.t('signIn.signIn')} From c4b934a542afbeb8e115f33624394fb9dce79b9c Mon Sep 17 00:00:00 2001 From: Riley Davis Date: Fri, 3 Feb 2017 10:19:18 -0700 Subject: [PATCH 17/17] whoops. commited to the wrong branch --- client/coral-sign-in/components/SignUpContent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-sign-in/components/SignUpContent.js b/client/coral-sign-in/components/SignUpContent.js index 2739c27a7..80a6fcde4 100644 --- a/client/coral-sign-in/components/SignUpContent.js +++ b/client/coral-sign-in/components/SignUpContent.js @@ -77,7 +77,7 @@ const SignUpContent = ({handleChange, formData, ...props}) => (