diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js
index 870ea93ad..cf8df6e0d 100644
--- a/client/coral-embed-stream/src/CommentStream.js
+++ b/client/coral-embed-stream/src/CommentStream.js
@@ -33,26 +33,6 @@ const {addItem, updateItem, postItem, getStream, postAction, deleteAction, appen
const {addNotification, clearNotification} = notificationActions;
const {logout} = authActions;
-const mapStateToProps = state => ({
- config: state.config.toJS(),
- items: state.items.toJS(),
- notification: state.notification.toJS(),
- auth: state.auth.toJS()
-});
-
-const mapDispatchToProps = (dispatch) => ({
- addItem: (item, itemType) => dispatch(addItem(item, itemType)),
- updateItem: (id, property, value, itemType) => dispatch(updateItem(id, property, value, itemType)),
- postItem: (data, type, id) => dispatch(postItem(data, type, id)),
- getStream: (rootId) => dispatch(getStream(rootId)),
- addNotification: (type, text) => dispatch(addNotification(type, text)),
- clearNotification: () => dispatch(clearNotification()),
- postAction: (item, action, user, itemType) => dispatch(postAction(item, action, user, itemType)),
- deleteAction: (item, action, user, itemType) => dispatch(deleteAction(item, action, user, itemType)),
- appendItemArray: (item, property, value, addToFront, itemType) => dispatch(appendItemArray(item, property, value, addToFront, itemType)),
- logout: () => dispatch(logout())
-});
-
class CommentStream extends Component {
constructor (props) {
@@ -105,6 +85,7 @@ class CommentStream extends Component {
const {actions, users, comments} = this.props.items;
const {loggedIn, user, showSignInDialog} = this.props.auth;
const {activeTab} = this.state;
+
return
{
rootItem
@@ -246,7 +227,10 @@ class CommentStream extends Component {
/>
-
+
@@ -257,4 +241,25 @@ class CommentStream extends Component {
}
}
+const mapStateToProps = state => ({
+ config: state.config.toJS(),
+ items: state.items.toJS(),
+ notification: state.notification.toJS(),
+ auth: state.auth.toJS(),
+ userData: state.user.toJS()
+});
+
+const mapDispatchToProps = (dispatch) => ({
+ addItem: (item, itemType) => dispatch(addItem(item, itemType)),
+ updateItem: (id, property, value, itemType) => dispatch(updateItem(id, property, value, itemType)),
+ postItem: (data, type, id) => dispatch(postItem(data, type, id)),
+ getStream: (rootId) => dispatch(getStream(rootId)),
+ addNotification: (type, text) => dispatch(addNotification(type, text)),
+ clearNotification: () => dispatch(clearNotification()),
+ postAction: (item, action, user, itemType) => dispatch(postAction(item, action, user, itemType)),
+ deleteAction: (item, action, user, itemType) => dispatch(deleteAction(item, action, user, itemType)),
+ appendItemArray: (item, property, value, addToFront, itemType) => dispatch(appendItemArray(item, property, value, addToFront, itemType)),
+ logout: () => dispatch(logout())
+});
+
export default connect(mapStateToProps, mapDispatchToProps)(CommentStream);
diff --git a/client/coral-framework/actions/user.js b/client/coral-framework/actions/user.js
index 5afbee14d..04d5c9238 100644
--- a/client/coral-framework/actions/user.js
+++ b/client/coral-framework/actions/user.js
@@ -2,12 +2,12 @@ import * as actions from '../constants/user';
import {base, handleResp, getInit} from '../helpers/response';
const saveBioRequest = () => ({type: actions.SAVE_BIO_REQUEST});
-const saveBioSuccess = bio => ({type: actions.SAVE_BIO_SUCCESS, bio});
+const saveBioSuccess = user => ({type: actions.SAVE_BIO_SUCCESS, user});
const saveBioFailure = error => ({type: actions.SAVE_BIO_FAILURE, error});
-export const saveBio = (formData) => dispatch => {
+export const saveBio = (user_id, formData) => dispatch => {
dispatch(saveBioRequest());
- fetch(`${base}/auth/local`, getInit('POST', formData))
+ fetch(`${base}/${user_id}/bio`, getInit('POST', formData))
.then(handleResp)
.then(({user}) => {
dispatch(saveBioSuccess(user));
diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js
index a445fc663..a4803fa96 100644
--- a/client/coral-framework/reducers/auth.js
+++ b/client/coral-framework/reducers/auth.js
@@ -13,6 +13,11 @@ const initialState = Map({
successSignUp: false
});
+const purge = user => {
+ const {settings, profiles, ...userData} = user; // eslint-disable-line
+ return userData;
+};
+
export default function auth (state = initialState, action) {
switch (action.type) {
case actions.SHOW_SIGNIN_DIALOG :
@@ -44,11 +49,11 @@ export default function auth (state = initialState, action) {
case actions.CHECK_LOGIN_SUCCESS:
return state
.set('loggedIn', true)
- .set('user', action.user);
+ .set('user', purge(action.user));
case actions.FETCH_SIGNIN_SUCCESS:
return state
.set('loggedIn', true)
- .set('user', action.user);
+ .set('user', purge(action.user));
case actions.FETCH_SIGNIN_FAILURE:
return state
.set('isLoading', false)
@@ -56,7 +61,7 @@ export default function auth (state = initialState, action) {
.set('user', null);
case actions.FETCH_SIGNIN_FACEBOOK_SUCCESS:
return state
- .set('user', action.user)
+ .set('user', purge(action.user))
.set('loggedIn', true);
case actions.FETCH_SIGNIN_FACEBOOK_FAILURE:
return state
diff --git a/client/coral-framework/reducers/index.js b/client/coral-framework/reducers/index.js
index 90eaa7cb7..a2f439028 100644
--- a/client/coral-framework/reducers/index.js
+++ b/client/coral-framework/reducers/index.js
@@ -5,6 +5,7 @@ import config from './config';
import items from './items';
import notification from './notification';
import auth from './auth';
+import user from './user';
/**
* Expose the combined main reducer
@@ -15,4 +16,5 @@ export default combineReducers({
items,
notification,
auth,
+ user
});
diff --git a/client/coral-framework/reducers/user.js b/client/coral-framework/reducers/user.js
index 42a71df3b..96307b293 100644
--- a/client/coral-framework/reducers/user.js
+++ b/client/coral-framework/reducers/user.js
@@ -1,19 +1,35 @@
import {Map} from 'immutable';
-import {FETCH_SIGNIN_SUCCESS} from '../constants/auth';
+import * as authActions from '../constants/auth';
import * as actions from '../constants/user';
const initialState = Map({
- bio: ''
+ displayName: '',
+ profiles: [],
+ settings: []
});
+const purge = user => {
+ const {_id, created_at, updated_at, __v, roles, ...userData} = user; // eslint-disable-line
+ return userData;
+};
+
export default function user (state = initialState, action) {
switch (action.type) {
- case FETCH_SIGNIN_SUCCESS :
+ case authActions.CHECK_LOGIN_SUCCESS:
+ return state.merge(Map(purge(action.user)));
+ case authActions.CHECK_LOGIN_FAILURE:
+ return initialState;
+ case authActions.FETCH_SIGNIN_SUCCESS:
+ return state.merge(Map(purge(action.user)));
+ case authActions.FETCH_SIGNIN_FAILURE:
+ return initialState;
+ case authActions.FETCH_SIGNIN_FACEBOOK_SUCCESS:
+ return state.merge(Map(purge(action.user)));
+ case authActions.FETCH_SIGNIN_FACEBOOK_FAILURE:
+ return initialState;
+ case actions.SAVE_BIO_SUCCESS:
return state
.set('bio', action.user.bio);
- case actions.SAVE_BIO_SUCCESS :
- return state
- .set('bio', action.bio);
default :
return state;
}
diff --git a/client/coral-settings/components/Bio.js b/client/coral-settings/components/Bio.js
index 7310db114..36c3855df 100644
--- a/client/coral-settings/components/Bio.js
+++ b/client/coral-settings/components/Bio.js
@@ -2,14 +2,14 @@ import React from 'react';
import styles from './Bio.css';
import {Button} from '../../coral-ui';
-export default ({user, handleSaveBio}) => (
+export default ({userData, bio, handleSave, handleChange}) => (
Bio
Tell the community about yourself
-
);
diff --git a/client/coral-settings/components/SettingsHeader.js b/client/coral-settings/components/SettingsHeader.js
index c48f13cf4..b55f008ad 100644
--- a/client/coral-settings/components/SettingsHeader.js
+++ b/client/coral-settings/components/SettingsHeader.js
@@ -1,10 +1,10 @@
import React from 'react';
import styles from './SettingsHeader.css';
-export default ({user}) => (
+export default ({userData}) => (
-
{user.displayName}
- {user.profiles.map(profile => profile.id)}
+ {userData.displayName}
+ {userData.profiles.map(profile => profile.id)}
);
diff --git a/client/coral-settings/containers/BioContainer.js b/client/coral-settings/containers/BioContainer.js
new file mode 100644
index 000000000..d3a04e14b
--- /dev/null
+++ b/client/coral-settings/containers/BioContainer.js
@@ -0,0 +1,35 @@
+import React, {Component} from 'react';
+import Bio from '../components/Bio';
+
+export default class BioContainer extends Component {
+ constructor (props) {
+ super(props);
+
+ this.state = {
+ bio: ''
+ };
+
+ this.handleSave = this.handleSave.bind(this);
+ this.handleBioChange = this.handleBioChange.bind(this);
+ }
+
+ handleBioChange(e) {
+ this.setState({
+ bio: e.target.value
+ });
+ }
+
+ handleSave () {
+ // const {bio} = this.state;
+ // this.props.saveBio(user_id, bio);
+ }
+
+ render () {
+ return ;
+ }
+}
diff --git a/client/coral-settings/containers/SettingsContainer.js b/client/coral-settings/containers/SettingsContainer.js
index ecd3747df..1013f7a39 100644
--- a/client/coral-settings/containers/SettingsContainer.js
+++ b/client/coral-settings/containers/SettingsContainer.js
@@ -1,26 +1,26 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
-import {TabBar, Tab, TabContent} from '../../coral-ui';
+import {saveBio} from 'coral-framework/actions/user';
-import Bio from '../components/Bio';
+import BioContainer from './BioContainer';
+import NotLoggedIn from '../components/NotLoggedIn';
+import {TabBar, Tab, TabContent} from '../../coral-ui';
import CommentHistory from '../components/CommentHistory';
import SettingsHeader from '../components/SettingsHeader';
-import NotLoggedIn from '../components/NotLoggedIn';
import RestrictedContent from 'coral-framework/components/RestrictedContent';
class SignInContainer extends Component {
constructor (props) {
super(props);
this.state = {
- activeTab: 0
+ activeTab: 0,
};
this.handleTabChange = this.handleTabChange.bind(this);
}
componentWillMount () {
- // Get Bio
// Fetch commentHistory
}
@@ -44,7 +44,7 @@ class SignInContainer extends Component {
-
+
);
@@ -55,7 +55,7 @@ const mapStateToProps = () => ({
});
const mapDispatchToProps = dispatch => ({
- handleSaveBio: () => dispatch(),
+ saveBio: (user_id, formData) => dispatch(saveBio(user_id, formData)),
getHistory: () => dispatch(),
});
diff --git a/models/user.js b/models/user.js
index ff615b74a..6e9300ec0 100644
--- a/models/user.js
+++ b/models/user.js
@@ -75,8 +75,20 @@ const UserSchema = new mongoose.Schema({
// Roles provides an array of roles (as strings) that is associated with a
// user.
roles: [String],
- // User's bio
- bio: String,
+
+ // User's settings
+ settings: [
+ new mongoose.Schema({
+ id: {
+ type: String,
+ required: true
+ },
+ value: {
+ type: String,
+ required: true
+ }
+ })
+ ]
}, {
// This will ensure that we have proper timestamps available on this model.
@@ -524,3 +536,18 @@ UserService.count = () => {
UserService.all = () => {
return UserModel.find();
};
+
+/**
+ * Adds a new User bio
+ * @return {Promise}
+ */
+
+UserService.addBio = (id, bio) => (
+ UserModel.update({
+ id
+ }, {
+ $addToSet: {
+ bio
+ }
+ })
+);
diff --git a/routes/api/user/index.js b/routes/api/user/index.js
index 43d3b8ac0..3c7e651bb 100644
--- a/routes/api/user/index.js
+++ b/routes/api/user/index.js
@@ -140,4 +140,23 @@ router.post('/request-password-reset', (req, res, next) => {
});
});
+router.post('/:user_id/bio', (req, res, next) => {
+ const {user_id} = req.params;
+ const {bio} = req.body;
+
+ if (!bio) {
+ return next('You must submit a new bio');
+ }
+
+ User
+ .addBio(user_id, bio)
+ .then(() => {
+ res.status(204).end();
+ })
+ .catch(error => {
+ const errorMsg = typeof error === 'string' ? error : error.message;
+ res.status(500).json({error: errorMsg});
+ });
+});
+
module.exports = router;