diff --git a/bin/cli-users b/bin/cli-users index 012eba9d4..adfe3bf23 100755 --- a/bin/cli-users +++ b/bin/cli-users @@ -219,6 +219,7 @@ function listUsers() { 'Display Name', 'Profiles', 'Roles', + 'Status', 'State' ] }); @@ -229,6 +230,7 @@ function listUsers() { user.displayName, user.profiles.map((p) => p.provider).join(', '), user.roles.join(', '), + user.status, user.disabled ? 'Disabled' : 'Enabled' ]); }); @@ -296,6 +298,40 @@ function removeRole(userID, role) { }); } +/** + * Ban a user + * @param {String} userID id of the user to ban + */ +function ban(userID) { + User + .setStatus(userID, 'banned', '') + .then(() => { + console.log(`Banned the User ${userID}.`); + util.shutdown(); + }) + .catch((err) => { + console.error(err); + util.shutdown(1); + }); +} + +/** + * Unban a user + * @param {String} userUD id of the user to remove the role from + */ +function unban(userID) { + User + .setStatus(userID, 'active', '') + .then(() => { + console.log(`Unban the User ${userID}.`); + util.shutdown(); + }) + .catch((err) => { + console.error(err); + util.shutdown(1); + }); +} + /** * Disable a given user. * @param {String} userID the ID of a user to disable @@ -384,6 +420,16 @@ program .description('removes a role from a given user') .action(removeRole); +program + .command('ban ') + .description('ban a given user') + .action(ban); + +program + .command('uban ') + .description('unban a given user') + .action(unban); + program .command('disable ') .description('disable a given user from logging in') diff --git a/client/coral-admin/src/actions/comments.js b/client/coral-admin/src/actions/comments.js index e4a55a893..d4aee034e 100644 --- a/client/coral-admin/src/actions/comments.js +++ b/client/coral-admin/src/actions/comments.js @@ -1,4 +1,3 @@ - /** * Action disptacher related to comments */ @@ -16,3 +15,16 @@ export const flagComment = id => (dispatch, getState) => { export const createComment = (name, body) => dispatch => { dispatch({type: 'COMMENT_CREATE', name, body}); }; + +// Dialog Actions +export const showBanUserDialog = (userId, userName, commentId) => { + return dispatch => { + dispatch({type: 'SHOW_BANUSER_DIALOG', userId, userName, commentId}); + }; +}; + +export const hideBanUserDialog = (showDialog) => { + return dispatch => { + dispatch({type: 'HIDE_BANUSER_DIALOG', showDialog}); + }; +}; diff --git a/client/coral-admin/src/actions/community.js b/client/coral-admin/src/actions/community.js index 8b8e883d8..24c1b403d 100644 --- a/client/coral-admin/src/actions/community.js +++ b/client/coral-admin/src/actions/community.js @@ -6,7 +6,8 @@ import { FETCH_COMMENTERS_FAILURE, SORT_UPDATE, COMMENTERS_NEW_PAGE, - SET_ROLE + SET_ROLE, + SET_COMMENTER_STATUS } from '../constants/community'; import coralApi from '../../../coral-framework/helpers/response'; @@ -46,3 +47,10 @@ export const setRole = (id, role) => dispatch => { return dispatch({type: SET_ROLE, id, role}); }); }; + +export const setCommenterStatus = (id, status) => dispatch => { + return coralApi(`/user/${id}/status`, {method: 'POST', body: {status}}) + .then(() => { + return dispatch({type: SET_COMMENTER_STATUS, id, status}); + }); +}; diff --git a/client/coral-admin/src/actions/users.js b/client/coral-admin/src/actions/users.js new file mode 100644 index 000000000..f2ff37cbd --- /dev/null +++ b/client/coral-admin/src/actions/users.js @@ -0,0 +1,14 @@ + +/** + * Action disptacher related to users + */ +// +// export const banUser = (status, author_id) => (dispatch) => { +// dispatch({type: 'USER_STATUS_UPDATE', author_id, status}); +// }; +export const banUser = (status, userId, commentId) => { + return dispatch => { + dispatch({type: 'USER_BAN', status, userId, commentId}); + dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH'}); + }; +}; diff --git a/client/coral-admin/src/components/BanUserDialog.css b/client/coral-admin/src/components/BanUserDialog.css new file mode 100644 index 000000000..dfac4f194 --- /dev/null +++ b/client/coral-admin/src/components/BanUserDialog.css @@ -0,0 +1,147 @@ +.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 a { + color: #2c69b6; + cursor: pointer; + margin: 0px; +} + +.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; +} + +.passwordRequestSuccess { + border: 1px solid green; + background-color: lightgreen; + padding: 10px; +} + +.passwordRequestFailure { + border: 1px solid orange; + background-color: 1px solid coral; + padding: 10px; +} + +.cancel { + margin: 10px 0; +} diff --git a/client/coral-admin/src/components/BanUserDialog.js b/client/coral-admin/src/components/BanUserDialog.js new file mode 100644 index 000000000..1867b9ac2 --- /dev/null +++ b/client/coral-admin/src/components/BanUserDialog.js @@ -0,0 +1,45 @@ +import React from 'react'; + +import {Dialog} from 'coral-ui'; +import Button from 'coral-ui/components/Button'; + +import styles from './BanUserDialog.css'; + +import I18n from 'coral-framework/modules/i18n/i18n'; +import translations from '../translations'; +const lang = new I18n(translations); + +const BanUserDialog = ({open, handleClose, onClickBanUser, user = {}}) => { + const {userName = '', userId = '', commentId = ''} = user; + + return ( + handleClose()} onCancel={() => handleClose()} title={lang.t('bandialog.ban_user')}> + handleClose()}>× +
+
+

+ {lang.t('bandialog.ban_user')} +

+
+
+

+ {lang.t('bandialog.are_you_sure', userName)} +

+ + {lang.t('bandialog.note')} + +
+
+ + +
+
+
+ ); +}; + +export default BanUserDialog; diff --git a/client/coral-admin/src/components/Comment.js b/client/coral-admin/src/components/Comment.js index 3481ad671..380a001c8 100644 --- a/client/coral-admin/src/components/Comment.js +++ b/client/coral-admin/src/components/Comment.js @@ -1,17 +1,20 @@ - import React from 'react'; import timeago from 'timeago.js'; +import Linkify from 'react-linkify'; + 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 authorStatus = props.author.get('status'); const {comment, author} = props; const links = linkify.getMatches(comment.get('body')); @@ -28,15 +31,13 @@ export default props => { {links ? Contains Link : null}
- {props.actions.map((action, i) => canShowAction(action, comment) ? ( - props.onClickAction(props.actionsMap[action].status, comment.get('id'))} - /> - ) : null)} + {props.actions.map((action, i) => getActionButton(action, i, props))}
+
+ {authorStatus === 'banned' ? + {lang.t('comment.banned_user')} : null} +
@@ -49,15 +50,33 @@ 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'); + const banned = (props.author.get('status') === 'banned'); 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 40b99b892..b4547335e 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: 'banned', icon: 'not interested'} }; // Renders a comment list and allow performing actions @@ -19,6 +20,7 @@ export default class CommentList extends React.Component { this.state = {active: null}; this.onClickAction = this.onClickAction.bind(this); + this.onClickShowBanDialog = this.onClickShowBanDialog.bind(this); } // remove key handlers before leaving @@ -99,7 +101,8 @@ export default class CommentList extends React.Component { // If we are performing an action over a comment (aka removing from the list) we need to select a new active. // TODO: In the future this can be improved and look at the actual state to // resolve since the content of the list could change externally. For now it works as expected - onClickAction (action, id) { + onClickAction (action, id, author_id) { + // activate the next comment if (id === this.state.active) { const {commentIds} = this.props; if (commentIds.last() === this.state.active) { @@ -108,7 +111,11 @@ export default class CommentList extends React.Component { this.setState({active: commentIds.get(Math.min(commentIds.indexOf(this.state.active) + 1, commentIds.size - 1))}); } } - this.props.onClickAction(action, id); + this.props.onClickAction(action, id, author_id); + } + + onClickShowBanDialog(userId, userName, commentId) { + this.props.onClickShowBanDialog(userId, userName, commentId); } render () { @@ -125,6 +132,7 @@ export default class CommentList extends React.Component { key={index} index={index} onClickAction={this.onClickAction} + onClickShowBanDialog={this.onClickShowBanDialog} actions={this.props.actions} actionsMap={actions} isActive={commentId === active} diff --git a/client/coral-admin/src/constants/comments.js b/client/coral-admin/src/constants/comments.js new file mode 100644 index 000000000..856f619d0 --- /dev/null +++ b/client/coral-admin/src/constants/comments.js @@ -0,0 +1,3 @@ +export const SHOW_BANUSER_DIALOG = 'SHOW_BANUSER_DIALOG'; +export const HIDE_BANUSER_DIALOG = 'HIDE_BANUSER_DIALOG'; +export const USER_BAN_SUCESS = 'USER_BAN_SUCESS'; diff --git a/client/coral-admin/src/constants/community.js b/client/coral-admin/src/constants/community.js index 2ea77ea77..e3fd88a71 100644 --- a/client/coral-admin/src/constants/community.js +++ b/client/coral-admin/src/constants/community.js @@ -4,3 +4,4 @@ export const FETCH_COMMENTERS_FAILURE = 'FETCH_COMMENTERS_FAILURE'; export const SORT_UPDATE = 'SORT_UPDATE'; export const COMMENTERS_NEW_PAGE = 'COMMENTERS_NEW_PAGE'; export const SET_ROLE = 'SET_ROLE'; +export const SET_COMMENTER_STATUS = 'SET_COMMENTER_STATUS'; diff --git a/client/coral-admin/src/containers/Community/Community.css b/client/coral-admin/src/containers/Community/Community.css index 63148da7e..b19d0261d 100644 --- a/client/coral-admin/src/containers/Community/Community.css +++ b/client/coral-admin/src/containers/Community/Community.css @@ -1,7 +1,3 @@ -.dataTable { - width: 100%; -} - .roleButton { display: block; } @@ -9,14 +5,13 @@ .searchInput { display: block; padding-left: 40px; - /*border: none;*/ + width: auto; } .searchBox { - /*border: 1px solid rgba(0,0,0,.12);*/ background: white; } .email { display: block; -} \ No newline at end of file +} diff --git a/client/coral-admin/src/containers/Community/Community.js b/client/coral-admin/src/containers/Community/Community.js index f8c24fd3a..e798266f0 100644 --- a/client/coral-admin/src/containers/Community/Community.js +++ b/client/coral-admin/src/containers/Community/Community.js @@ -20,6 +20,10 @@ const tableHeaders = [ title: lang.t('community.account_creation_date'), field: 'created_at' }, + { + title: lang.t('community.status'), + field: 'status' + }, { title: lang.t('community.newsroom_role'), field: 'role' @@ -30,7 +34,7 @@ const Community = ({isFetching, commenters, ...props}) => { const hasResults = !isFetching && !!commenters.length; return ( - +
- + { isFetching && } { !hasResults && } { hasResults && diff --git a/client/coral-admin/src/containers/Community/Table.js b/client/coral-admin/src/containers/Community/Table.js index 89737e33e..1d81b1b2e 100644 --- a/client/coral-admin/src/containers/Community/Table.js +++ b/client/coral-admin/src/containers/Community/Table.js @@ -4,7 +4,7 @@ import {SelectField, Option} from 'react-mdl-selectfield'; import styles from './Community.css'; import I18n from 'coral-framework/modules/i18n/i18n'; import translations from '../../translations'; -import {setRole} from '../../actions/community'; +import {setRole, setCommenterStatus} from '../../actions/community'; const lang = new I18n(translations); @@ -19,6 +19,10 @@ class Table extends Component { this.props.dispatch(setRole(id, role)); } + onCommenterStatusChange (id, status) { + this.props.dispatch(setCommenterStatus(id, status)); + } + render () { const {headers, commenters, onHeaderClickHandler} = this.props; @@ -46,6 +50,14 @@ class Table extends Component { {row.created_at} + + this.onCommenterStatusChange(row.id, status)}> + + + + this.onCommentAction(action, id)} - actions={['reject', 'approve']} + onClickAction={(action, commentId) => this.onCommentAction(action, commentId)} + onClickShowBanDialog={(userId, userName, commentId) => this.showBanUserDialog(userId, userName, commentId)} + actions={['reject', 'approve', 'ban']} loading={comments.loading} /> -
+ this.hideBanUserDialog()} + onClickBanUser={(userId, commentId) => this.banUser(userId, commentId)} + user={comments.get('banUser')}/> +
{ case 'COMMENT_FLAG': return flag(state, action); case 'COMMENT_CREATE_SUCCESS': return addComment(state, action); case 'COMMENT_STREAM_FETCH_SUCCESS': return replaceComments(action, state); + case actions.SHOW_BANUSER_DIALOG: return setBanUser(state, true, action); + case actions.HIDE_BANUSER_DIALOG: return setBanUser(state, false, action); + case actions.USER_BAN_SUCESS: return setBanUser(state, false, action); default: return state; } }; +// hide or show the UI for the dialog confirming the ban +// set the user that is going to set and the comment that is the reason +const setBanUser = (state, showBanUser, action) => { + const banUser = {'userName': action.userName, 'userId': action.userId, 'commentId': action.commentId}; + return state.set('showBanUserDialog', showBanUser) + .set('banUser', banUser); +}; + // Update a comment status const updateStatus = (state, action) => { const byId = state.get('byId'); diff --git a/client/coral-admin/src/reducers/community.js b/client/coral-admin/src/reducers/community.js index 81a09a1cc..367e67b2a 100644 --- a/client/coral-admin/src/reducers/community.js +++ b/client/coral-admin/src/reducers/community.js @@ -5,7 +5,8 @@ import { FETCH_COMMENTERS_FAILURE, FETCH_COMMENTERS_SUCCESS, SORT_UPDATE, - SET_ROLE + SET_ROLE, + SET_COMMENTER_STATUS } from '../constants/community'; const initialState = Map({ @@ -45,6 +46,14 @@ export default function community (state = initialState, action) { commenters[idx].roles[0] = action.role; return state.set('commenters', commenters.map(id => id)); } + case SET_COMMENTER_STATUS: { + const commenters = state.get('commenters'); + const idx = commenters.findIndex(el => el.id === action.id); + + commenters[idx].status = action.status; + return state.set('commenters', commenters.map(id => id)); + + } case SORT_UPDATE : return state .set('field', action.sort.field) diff --git a/client/coral-admin/src/reducers/users.js b/client/coral-admin/src/reducers/users.js index 872ae904a..ef589c155 100644 --- a/client/coral-admin/src/reducers/users.js +++ b/client/coral-admin/src/reducers/users.js @@ -8,6 +8,7 @@ const initialState = Map({ export default (state = initialState, action) => { switch (action.type) { case 'USERS_MODERATION_QUEUE_FETCH_SUCCESS': return replaceUsers(action, state); + case 'USER_STATUS_UPDATE': return updateUserStatus(state, action); default: return state; } }; @@ -18,3 +19,10 @@ const replaceUsers = (action, state) => { return state.set('byId', users) .set('ids', List(users.keys())); }; + +// Update a user status +const updateUserStatus = (state, action) => { + const byId = state.get('byId'); + const data = byId.get(action.author_id).set('status', action.status.toLowerCase()); + return state.set('byId', byId.set(action.author_id, data)); +}; diff --git a/client/coral-admin/src/services/talk-adapter.js b/client/coral-admin/src/services/talk-adapter.js index 5502df7ed..f734d1f72 100644 --- a/client/coral-admin/src/services/talk-adapter.js +++ b/client/coral-admin/src/services/talk-adapter.js @@ -21,6 +21,9 @@ export default store => next => action => { case 'COMMENT_CREATE': createComment(store, action.name, action.body); break; + case 'USER_BAN': + userStatusUpdate(store, action.status, action.userId, action.commentId); + break; } next(action); @@ -81,3 +84,10 @@ 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 userStatusUpdate = (store, status, userId, commentId) => { + return coralApi(`/user/${userId}/status`, {method: 'POST', body: {status: status, comment_id: commentId}}) + .then(res => store.dispatch({type: 'USER_BAN_SUCESS', 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 849ce0c39..88a20e445 100644 --- a/client/coral-admin/src/translations.json +++ b/client/coral-admin/src/translations.json @@ -6,7 +6,14 @@ "newsroom_role": "Newsroom Role", "admin": "Administrator", "moderator": "Moderator", - "role": "Select role..." + "role": "Select role...", + "no-results": "No users found with that user name or email address.", + "status": "Status", + "select-status": "Select status...", + "active": "Active", + "banned": "Banned", + "banned-user": "Banned User", + "loading": "Loading results" }, "modqueue": { "pending": "pending", @@ -25,7 +32,9 @@ }, "comment": { "flagged": "flagged", - "anon": "Anonymous" + "anon": "Anonymous", + "ban_user": "Ban User", + "banned_user": "Banned User" }, "embedlink": { "copy": "Copy to Clipboard" @@ -47,6 +56,13 @@ "community": "Community", "closed-comments-desc": "Write a message for closed threads", "closed-comments-label": "Write a message..." + }, + "bandialog": { + "ban_user": "Ban User?", + "are_you_sure": "Are you sure you would like to ban {0}?", + "note": "Note: Banning this user will also place this comment in the Rejected queue.", + "cancel": "Cancel", + "yes_ban_user": "Yes, Ban User" } }, "es": { @@ -56,7 +72,14 @@ "newsroom_role": "Rol en la redacción", "admin": "Administrador", "moderator": "Moderador", - "role": "Select role..." + "role": "Seleccionar rol...", + "no-results": "No se encontraron usuarios con ese nombre de usuario o correo electronico.", + "status": "Estado", + "select-status": "Seleccionar estado...", + "active": "Activa", + "banned": "Suspendido", + "banned-user": "Usuario Suspendido", + "loading": "Cargando resultados" }, "modqueue": { "pending": "pendiente", @@ -67,7 +90,9 @@ }, "comment": { "flagged": "marcado", - "anon": "Anónimo" + "anon": "Anónimo", + "ban_user": "Suspender Usuario", + "banned_user": "Usuario Suspendido" }, "configure": { "enable-pre-moderation": "Habilitar pre-moderación", @@ -86,6 +111,13 @@ "community": "Comunidad", "closed-comments-desc": "Escribe un mensaje para cuando los comentarios se encuentran cerrados", "closed-comments-label": "Escribe un mensaje..." + }, + "bandialog": { + "ban_user": "Quieres suspender el Usuario?", + "are_you_sure": "Estas segura que quieres suspender a {props.author.displayName}?", + "note": "Nota: Suspender este usuario también va a colocar este comentario en la cola de Rechazados.", + "cancel": "Cancelar", + "yes_ban_user": "Si, Suspendan el usuario" } } } diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js index 294bf9c33..bb59ffa8e 100644 --- a/client/coral-embed-stream/src/CommentStream.js +++ b/client/coral-embed-stream/src/CommentStream.js @@ -93,6 +93,8 @@ class CommentStream extends Component { const {loggedIn, user, showSignInDialog, signInOffset} = this.props.auth; const {status, closedMessage} = this.props.config; const {activeTab} = this.state; + const banned = (this.props.userData.status === 'banned'); + const expandForLogin = showSignInDialog ? { minHeight: document.body.scrollHeight + 150 } : {}; @@ -106,8 +108,6 @@ class CommentStream extends Component { Configure Stream {loggedIn && } - {/* Add to the restricted param a boolean if the user is suspended*/} - }> { status === 'open' @@ -116,6 +116,7 @@ class CommentStream extends Component { content={this.props.config.infoBoxContent} enable={this.props.config.infoBoxEnable} /> + }> +
:

{closedMessage}

} @@ -142,7 +146,9 @@ class CommentStream extends Component { + currentUser={this.props.auth.user} + showReply={comment.showReply} + banned={banned}/> + currentUser={this.props.auth.user} + banned={banned}/>
{ @@ -192,6 +201,8 @@ class CommentStream extends Component { + currentUser={this.props.auth.user} + banned={banned}/>
; }) @@ -258,7 +273,6 @@ class CommentStream extends Component { /> - ( - {lang.t('suspendedAccountMsg')} +
+ {lang.t('suspendedAccountMsg')} +
); diff --git a/client/coral-plugin-flags/FlagButton.js b/client/coral-plugin-flags/FlagButton.js index dd5979888..92e0769fe 100644 --- a/client/coral-plugin-flags/FlagButton.js +++ b/client/coral-plugin-flags/FlagButton.js @@ -4,7 +4,7 @@ import translations from './translations.json'; const name = 'coral-plugin-flags'; -const FlagButton = ({flag, id, postAction, deleteAction, addItem, showSignInDialog, updateItem, addNotification, currentUser}) => { +const FlagButton = ({flag, id, postAction, deleteAction, addItem, showSignInDialog, updateItem, addNotification, currentUser, banned}) => { const flagged = flag && flag.current_user; const onFlagClick = () => { if (!currentUser) { @@ -12,6 +12,9 @@ const FlagButton = ({flag, id, postAction, deleteAction, addItem, showSignInDial showSignInDialog(offset); return; } + if (banned) { + return; + } if (!flagged) { postAction(id, 'flag', currentUser.id, 'comments') .then((action) => { diff --git a/client/coral-plugin-likes/LikeButton.js b/client/coral-plugin-likes/LikeButton.js index 0672da071..73a945c7e 100644 --- a/client/coral-plugin-likes/LikeButton.js +++ b/client/coral-plugin-likes/LikeButton.js @@ -4,7 +4,7 @@ import translations from './translations.json'; const name = 'coral-plugin-flags'; -const LikeButton = ({like, id, postAction, deleteAction, addItem, showSignInDialog, updateItem, currentUser}) => { +const LikeButton = ({like, id, postAction, deleteAction, addItem, showSignInDialog, updateItem, currentUser, banned}) => { const liked = like && like.current_user; const onLikeClick = () => { if (!currentUser) { @@ -12,6 +12,9 @@ const LikeButton = ({like, id, postAction, deleteAction, addItem, showSignInDial showSignInDialog(offset); return; } + if (banned) { + return; + } if (!liked) { postAction(id, 'like', currentUser.id, 'comments') .then((action) => { diff --git a/client/coral-plugin-replies/ReplyButton.js b/client/coral-plugin-replies/ReplyButton.js index 8e39af663..c44012cdb 100644 --- a/client/coral-plugin-replies/ReplyButton.js +++ b/client/coral-plugin-replies/ReplyButton.js @@ -6,7 +6,12 @@ const name = 'coral-plugin-replies'; const ReplyButton = (props) =>