mirror of
https://github.com/wassname/talk.git
synced 2026-07-19 11:28:50 +08:00
D
ividing userData from userAuth
This commit is contained in:
@@ -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 <div className={showSignInDialog ? 'expandForSignin' : ''}>
|
||||
{
|
||||
rootItem
|
||||
@@ -246,7 +227,10 @@ class CommentStream extends Component {
|
||||
/>
|
||||
</TabContent>
|
||||
<TabContent show={activeTab === 1}>
|
||||
<SettingsContainer loggedIn={loggedIn} user={user} />
|
||||
<SettingsContainer
|
||||
loggedIn={loggedIn}
|
||||
userData={this.props.userData}
|
||||
/>
|
||||
</TabContent>
|
||||
</RestrictedContent>
|
||||
</div>
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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}) => (
|
||||
<div className={styles.bio}>
|
||||
<h1>Bio</h1>
|
||||
<p>Tell the community about yourself</p>
|
||||
<textarea defaultValue={user.bio}/>
|
||||
<textarea defaultValue={userData.bio} value={bio} onChange={handleChange} />
|
||||
<div className={styles.actions}>
|
||||
<Button cStyle='cancel' raised>Cancel</Button>
|
||||
<Button cStyle='success' onClick={handleSaveBio}>Save Changes</Button>
|
||||
<Button cStyle='success' onClick={handleSave}>Save Changes</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import styles from './SettingsHeader.css';
|
||||
|
||||
export default ({user}) => (
|
||||
export default ({userData}) => (
|
||||
<div className={styles.header}>
|
||||
<h1>{user.displayName}</h1>
|
||||
<h2>{user.profiles.map(profile => profile.id)}</h2>
|
||||
<h1>{userData.displayName}</h1>
|
||||
<h2>{userData.profiles.map(profile => profile.id)}</h2>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -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 <Bio
|
||||
handleSave={this.handleSave}
|
||||
handleChange={this.handleChange}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
<CommentHistory {...this.props}/>
|
||||
</TabContent>
|
||||
<TabContent show={activeTab === 1}>
|
||||
<Bio {...this.props} />
|
||||
<BioContainer handleSave={this.handleSave} {...this.props} />
|
||||
</TabContent>
|
||||
</RestrictedContent>
|
||||
);
|
||||
@@ -55,7 +55,7 @@ const mapStateToProps = () => ({
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
handleSaveBio: () => dispatch(),
|
||||
saveBio: (user_id, formData) => dispatch(saveBio(user_id, formData)),
|
||||
getHistory: () => dispatch(),
|
||||
});
|
||||
|
||||
|
||||
+29
-2
@@ -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
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user