diff --git a/client/coral-admin/src/components/Comment.js b/client/coral-admin/src/components/Comment.js index 7cba85788..b499dc1c6 100644 --- a/client/coral-admin/src/components/Comment.js +++ b/client/coral-admin/src/components/Comment.js @@ -5,14 +5,15 @@ import styles from './CommentList.css'; import I18n from 'coral-framework/modules/i18n/i18n'; import translations from '../translations.json'; import Linkify from 'react-linkify'; -import {FabButton} from 'coral-ui'; import {Icon} from 'react-mdl'; +import {FabButton, Button} from 'coral-ui'; const linkify = new Linkify(); // Render a single comment for the list export default props => { const links = linkify.getMatches(props.comment.get('body')); + const banned = props.comment.get('banned'); return (
  • @@ -27,15 +28,13 @@ export default props => { {links ? Contains Link : null}
    - {props.actions.map((action, i) => canShowAction(action, props.comment) ? ( - props.onClickAction(props.actionsMap[action].status, props.comment.get('id'))} - /> - ) : null)} + {props.actions.map((action, i) => getActionButton(action, i, props))}
    +
    + {banned ? + Banned User : null} +
    @@ -48,15 +47,28 @@ export default props => { ); }; -// Check if an action can be performed over a comment -const canShowAction = (action, comment) => { - const status = comment.get('status'); - const flagged = comment.get('flagged'); +// Get the button of the action performed over a comment if any +const getActionButton = (action, i, props) => { + const status = props.comment.get('status'); + const flagged = props.comment.get('flagged'); if (action === 'flag' && (status || flagged === true)) { - return false; + return null; } - return true; + if (action === 'ban') { + return ( + + ); + } + return ( + props.onClickAction(props.actionsMap[action].status, props.comment.get('id'))} + /> + ); }; const linkStyles = { diff --git a/client/coral-admin/src/components/CommentList.css b/client/coral-admin/src/components/CommentList.css index 2c58c81cf..fddee7553 100644 --- a/client/coral-admin/src/components/CommentList.css +++ b/client/coral-admin/src/components/CommentList.css @@ -122,7 +122,6 @@ } - .hasLinks { color: #f00; text-align: right; @@ -133,3 +132,14 @@ margin-right: 5px; } } + +.banned { + color: #f00; + text-align: left; + display: flex; + align-items: center; + + i { + margin-right: 5px; + } +} diff --git a/client/coral-admin/src/components/CommentList.js b/client/coral-admin/src/components/CommentList.js index e4682252d..95b6c4117 100644 --- a/client/coral-admin/src/components/CommentList.js +++ b/client/coral-admin/src/components/CommentList.js @@ -9,7 +9,8 @@ import Comment from 'components/Comment'; const actions = { 'reject': {status: 'rejected', icon: 'close', key: 'r'}, 'approve': {status: 'accepted', icon: 'done', key: 't'}, - 'flag': {status: 'flagged', icon: 'flag', filter: 'Untouched'} + 'flag': {status: 'flagged', icon: 'flag', filter: 'Untouched'}, + 'ban': {status: 'ban'} }; // Renders a comment list and allow performing actions diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js b/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js index a4d82fddc..2de7d7d13 100644 --- a/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js +++ b/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js @@ -6,6 +6,7 @@ import ModerationKeysModal from 'components/ModerationKeysModal'; import CommentList from 'components/CommentList'; import {updateStatus} from 'actions/comments'; +import {updateUserStatus} from 'actions/users'; import styles from './ModerationQueue.css'; import I18n from 'coral-framework/modules/i18n/i18n'; @@ -51,8 +52,15 @@ class ModerationQueue extends React.Component { } // Dispatch the update status action - onCommentAction (status, id) { - this.props.dispatch(updateStatus(status, id)); + onCommentAction (action, id) { + // if we are banning a user by the action then dispatch updateUserStatus + // action = 'banned' in the case of banning + if (action === 'banned') { + this.props.dispatch(updateUserStatus(action, id)); + } + + // If not banning then change the status to approved or flagged as action = status + this.props.dispatch(updateStatus(action, id)); } onTabClick (activeTab) { @@ -61,7 +69,7 @@ class ModerationQueue extends React.Component { // Render the tabbed lists moderation queues render () { - const {comments} = this.props; + const {comments, commenters} = this.props; const {activeTab, singleView, modalOpen} = this.state; return ( @@ -86,8 +94,9 @@ class ModerationQueue extends React.Component { .get('status')) } comments={comments.get('byId')} + commenters={commenters} onClickAction={(action, id) => this.onCommentAction(action, id)} - actions={['reject', 'approve']} + actions={['reject', 'approve', 'ban']} loading={comments.loading} />
    @@ -104,6 +113,7 @@ class ModerationQueue extends React.Component { .get('status') === 'rejected') } comments={comments.get('byId')} + commenters={commenters} onClickAction={(action, id) => this.onCommentAction(action, id)} actions={['approve']} loading={comments.loading} /> @@ -117,6 +127,7 @@ class ModerationQueue extends React.Component { return !data.get('status') && data.get('flagged') === true; })} comments={comments.get('byId')} + commenters={commenters} onClickAction={(action, id) => this.onCommentAction(action, id)} actions={['reject', 'approve']} loading={comments.loading} /> diff --git a/client/coral-admin/src/reducers/users.js b/client/coral-admin/src/reducers/users.js deleted file mode 100644 index ded230760..000000000 --- a/client/coral-admin/src/reducers/users.js +++ /dev/null @@ -1,23 +0,0 @@ - -import {Map, List} from 'immutable'; - -const initialState = Map({ - byId: Map(), - ids: List(), - loading: false -}); - -// Handle the users actions -export default (state = initialState, action) => { - switch (action.type) { - case 'SET_COMMENTER_STATUS': return updateUserStatus(state, action); - default: return state; - } -}; - -// Update a user status -const updateUserStatus = (state, action) => { - const byId = state.get('byId'); - const data = byId.get(action.id).set('status', action.status.toLowerCase()); - return state.set('byId', byId.set(action.id, data)); -}; diff --git a/client/coral-admin/src/services/talk-adapter.js b/client/coral-admin/src/services/talk-adapter.js index 6b872d12d..d810e27dc 100644 --- a/client/coral-admin/src/services/talk-adapter.js +++ b/client/coral-admin/src/services/talk-adapter.js @@ -24,6 +24,9 @@ export default store => next => action => { case 'COMMENT_CREATE': createComment(store, action.name, action.body); break; + case 'BAN_USER': + banUser(store, action.comment); + break; } next(action); @@ -68,3 +71,11 @@ const createComment = (store, name, comment) => { .then(res => store.dispatch({type: 'COMMENT_CREATE_SUCCESS', comment: res})) .catch(error => store.dispatch({type: 'COMMENT_CREATE_FAILED', error})); }; + +// Ban a user +const banUser = (store, comment) => { + fetch(`${base}/user/${comment.get('author_id')}/status`, getInit('POST', {status: comment.get('status')})) + .then(handleResp) + .then(res => store.dispatch({type: 'USER_BAN_SUCESSS', res})) + .catch(error => store.dispatch({type: 'USER_BAN_FAILED', error})); +}; diff --git a/client/coral-admin/src/translations.json b/client/coral-admin/src/translations.json index 53207a05b..b70c232bc 100644 --- a/client/coral-admin/src/translations.json +++ b/client/coral-admin/src/translations.json @@ -32,7 +32,8 @@ }, "comment": { "flagged": "flagged", - "anon": "Anonymous" + "anon": "Anonymous", + "ban_user": "Ban User" }, "embedlink": { "copy": "Copy to Clipboard" @@ -76,7 +77,8 @@ }, "comment": { "flagged": "marcado", - "anon": "Anónimo" + "anon": "Anónimo", + "ban_user": "Suspender Usuario" }, "configure": { "enable-pre-moderation": "Habilitar pre-moderación", diff --git a/routes/api/user/index.js b/routes/api/user/index.js index bbb8c071b..d02276da8 100644 --- a/routes/api/user/index.js +++ b/routes/api/user/index.js @@ -62,7 +62,7 @@ router.post('/:user_id/role', authorization.needed('admin'), (req, res, next) => router.post('/:user_id/status', (req, res, next) => { User - .setStatus(req.params.user_id, req.body.status) + .setStatus(req.params.user_id, req.body.status, res.body.comment_id) .then(status => { res.send(status); })