Suspend User dialog.

This commit is contained in:
gaba
2017-03-02 09:27:53 -08:00
parent 3626d2678e
commit 1899dcbb7e
12 changed files with 155 additions and 122 deletions
+2 -2
View File
@@ -63,8 +63,8 @@ export const setCommenterStatus = (id, status) => (dispatch) => {
// Ban User Dialog
export const showBanUserDialog = (user) => ({type: SHOW_BANUSER_DIALOG, user});
export const hideBanUserDialog = (showDialog) => ({type: HIDE_BANUSER_DIALOG, showDialog});
export const hideBanUserDialog = () => ({type: HIDE_BANUSER_DIALOG});
// Suspend User Dialog
export const showSuspendUserDialog = (user) => ({type: SHOW_SUSPENDUSER_DIALOG, user});
export const hideSuspendUserDialog = (showDialog) => ({type: HIDE_SUSPENDUSER_DIALOG, showDialog});
export const hideSuspendUserDialog = () => ({type: HIDE_SUSPENDUSER_DIALOG});
@@ -1,4 +1,3 @@
import React from 'react';
import {Button, Icon} from 'react-mdl';
import styles from './Modal.css';
@@ -11,12 +11,13 @@ import {
newPage,
showBanUserDialog,
hideBanUserDialog,
showSuspendUserDialog,
hideSuspendUserDialog
} from '../../actions/community';
import CommunityMenu from './components/CommunityMenu';
import BanUserDialog from './components/BanUserDialog';
import SuspendUserModal from './components/SuspendUserModal';
import SuspendUserDialog from './components/SuspendUserDialog';
import People from './People';
import FlaggedAccounts from './FlaggedAccounts';
@@ -93,6 +94,7 @@ class CommunityContainer extends Component {
);
}
console.log('debug props', props);
return (
<div>
<FlaggedAccounts
@@ -101,7 +103,7 @@ class CommunityContainer extends Component {
error={data.error}
showBanUserDialog={props.showBanUserDialog}
approveUser={props.approveUser}
rejectUser={props.rejectUser}
showSuspendUserDialog={props.showSuspendUserDialog}
{...this}
/>
<BanUserDialog
@@ -110,10 +112,11 @@ class CommunityContainer extends Component {
handleClose={props.hideBanUserDialog}
handleBanUser={props.banUser}
/>
<SuspendUserModal
stage={0}
<SuspendUserDialog
open={community.suspendDialog}
onClose={props.hideSuspendUserDialog}
suspendUser={props.rejectUser}
user={community.user}
suspendUser={props.suspendUser}
/>
</div>
);
@@ -143,7 +146,8 @@ const mapDispatchToProps = dispatch => ({
fetchAccounts: query => dispatch(fetchAccounts(query)),
showBanUserDialog: (user) => dispatch(showBanUserDialog(user)),
hideBanUserDialog: () => dispatch(hideBanUserDialog(false)),
hideSuspendUserDialog: () => dispatch(hideSuspendUserDialog(false))
showSuspendUserDialog: () => dispatch(showSuspendUserDialog()),
hideSuspendUserDialog: () => dispatch(hideSuspendUserDialog())
});
export default compose(
@@ -27,8 +27,8 @@ const FlaggedAccounts = ({...props}) => {
index={index}
modActionButtons={['REJECT', 'APPROVE']}
showBanUserDialog={props.showBanUserDialog}
showSuspendUserDialog={props.showSuspendUserDialog}
approveUser={props.approveUser}
rejectUser={props.rejectUser}
/>;
})
: <EmptyCard>{lang.t('community.no-flagged-accounts')}</EmptyCard>
@@ -15,7 +15,7 @@ const ActionButton = ({type = '', user, ...props}) => {
cStyle={type.toLowerCase()}
icon={menuActionsMap[type].icon}
onClick={() => {
type === 'APPROVE' ? props.approveUser({userId: user.id}) : props.rejectUser({userId: user.id});
type === 'APPROVE' ? props.approveUser({userId: user.id}) : props.showSuspendUserDialog({user: user});
}}
/>
);
@@ -0,0 +1,119 @@
import React, {Component, PropTypes} from 'react';
import {Dialog, Button} from 'coral-ui';
import styles from './SuspendUserDialog.css';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../../../translations.json';
const lang = new I18n(translations);
const stages = [
{
title: 'suspenduser.title_0',
description: 'suspenduser.description_0',
options: {
'j': 'suspenduser.no_cancel',
'k': 'suspenduser.yes_suspend'
}
},
{
title: 'suspenduser.title_1',
description: 'suspenduser.description_1',
options: {
'j': 'bandialog.cancel',
'k': 'suspenduser.send'
}
}
];
class SuspendUserDialog extends Component {
state = {email: '', stage: 0}
static propTypes = {
stage: PropTypes.number,
onClose: PropTypes.func.isRequired,
suspendUser: PropTypes.func.isRequired
}
componentDidMount() {
this.setState({email: lang.t('suspenduser.email'), about: lang.t('suspenduser.username')});
}
/*
* When an admin clicks to suspend a user a dialog is shown, this function
* handles the possible actions for that dialog.
*/
onActionClick = (stage, menuOption) => () => {
const {suspendUser, user} = this.props;
const {stage, email} = this.state;
console.log('DEBUG props --> ', this.props);
console.log('DEBUG user', user);
const cancel = this.props.onClose;
const next = () => this.setState({stage: stage + 1});
const suspend = () => {
suspendUser({userId: user.id, email})
.then(() => {
this.props.onClose;
});
};
const suspendModalActions = [
[ cancel, next ],
[ cancel, suspend ]
];
return suspendModalActions[stage][menuOption]();
}
onEmailChange = (e) => {
console.log('debug', e.target);
this.setState({email: e.target.value});
}
render () {
const {open, onClose} = this.props;
const {stage} = this.state;
return <Dialog
className={styles.suspendDialog}
id="suspendUserDialog"
open={open}
onClose={onClose}
onCancel={onClose}
title={lang.t('suspenduser.title')}>
<div className={styles.title}>
{lang.t(stages[stage].title, lang.t('suspenduser.username'))}
</div>
<div className={styles.container}>
<div className={styles.description}>
{lang.t(stages[stage].description, lang.t('suspenduser.username'))}
</div>
{
stage === 1 &&
<div className={styles.writeContainer}>
<div className={styles.emailMessage}>{lang.t('suspenduser.write_message')}</div>
<div className={styles.emailContainer}>
<textarea
rows={5}
className={styles.emailInput}
value={this.state.email}
onChange={this.onEmailChange}/>
</div>
</div>
}
<div className={styles.modalButtons}>
{Object.keys(stages[stage].options).map((key, i) => (
<Button key={i} onClick={this.onActionClick(stage, i)}>
{lang.t(stages[stage].options[key], lang.t('suspenduser.username'))}
</Button>
))}
</div>
</div>
</Dialog>;
}
}
export default SuspendUserDialog;
@@ -1,106 +0,0 @@
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../../../translations.json';
import React, {Component, PropTypes} from 'react';
import Modal from 'components/Modal';
import styles from './SuspendUserModal.css';
import {Button} from 'coral-ui';
const stages = [
{
title: 'suspenduser.title_0',
description: 'suspenduser.description_0',
options: {
'j': 'suspenduser.no_cancel',
'k': 'suspenduser.yes_suspend'
}
},
{
title: 'suspenduser.title_1',
description: 'suspenduser.description_1',
options: {
'j': 'bandialog.cancel',
'k': 'suspenduser.send'
}
}
];
class SuspendUserModal extends Component {
state = {email: '', stage: 0}
static propTypes = {
stage: PropTypes.number,
actionType: PropTypes.string,
onClose: PropTypes.func.isRequired,
suspendUser: PropTypes.func.isRequired
}
componentDidMount() {
const about = lang.t('suspenduser.username');
this.setState({email: lang.t('suspenduser.email', about)});
}
/*
* When an admin clicks to suspend a user a dialog is shown, this function
* handles the possible actions for that dialog.
*/
onActionClick = (stage, menuOption) => () => {
const {suspendUser, action} = this.props;
const {stage, email} = this.state;
const cancel = this.props.onClose;
const next = () => this.setState({stage: stage + 1});
const suspend = () => suspendUser(action.item_id, lang.t('suspenduser.email_subject'), email)
.then(this.props.onClose);
const suspendModalActions = [
[ cancel, next ],
[ cancel, suspend ]
];
return suspendModalActions[stage][menuOption]();
}
onEmailChange = (e) => this.setState({email: e.target.value})
render () {
const {action, onClose} = this.props;
if (!action) {
return null;
}
const {stage} = this.state;
const actionType = action.actionType;
const about = actionType === 'flag_bio' ? lang.t('suspenduser.bio') : lang.t('suspenduser.username');
return <Modal open={true} onClose={onClose}>
<div className={styles.title}>{lang.t(stages[stage].title, about)}</div>
<div className={styles.container}>
<div className={styles.description}>
{lang.t(stages[stage].description, about)}
</div>
{
stage === 1 &&
<div className={styles.writeContainer}>
<div className={styles.emailMessage}>{lang.t('suspenduser.write_message')}</div>
<div className={styles.emailContainer}>
<textarea
rows={5}
className={styles.emailInput}
value={this.state.email}
onChange={this.onEmailChange}/>
</div>
</div>
}
<div className={styles.modalButtons}>
{Object.keys(stages[stage].options).map((key, i) => (
<Button key={i} onClick={this.onActionClick(stage, i)}>
{lang.t(stages[stage].options[key], about)}
</Button>
))}
</div>
</div>
</Modal>;
}
}
export default SuspendUserModal;
const lang = new I18n(translations);
@@ -56,7 +56,7 @@ const User = props => {
key={i}
user={user}
approveUser={props.approveUser}
rejectUser={props.rejectUser}
showSuspendUserDialog={props.showSuspendUserDialog}
/>;
}
)}
@@ -26,11 +26,12 @@ export const setUserStatus = graphql(SET_USER_STATUS, {
refetchQueries: ['Users']
});
},
rejectUser: ({userId}) => {
suspendUser: ({userId}) => {
return mutate({
variables: {
userId,
status: 'BANNED'
status: 'BANNED',
canEditName: true
},
refetchQueries: ['Users']
});
+2 -1
View File
@@ -23,7 +23,8 @@ const initialState = Map({
totalPagesPeople: 0,
pagePeople: 0,
user: Map({}),
banDialog: false
banDialog: false,
suspendDialog: false
});
export default function community (state = initialState, action) {
+16 -1
View File
@@ -109,7 +109,8 @@
"yes_ban_user": "Yes, Ban User"
},
"suspenduser": {
"title_0": "We noticed you rejected a {0}",
"title": "Suspend a user",
"title_0": "We noticed you rejected a username",
"description_0": "Would you like to temporarily ban this user becuase of their {0}? Doing so will temporarily hide their comments until they rewrite their {0}.",
"title_1": "Notify the user of their temporary suspension",
"description_1": "Suspending this user will temporarily disable their account and hide all of their comments on the site.",
@@ -173,6 +174,20 @@
"cancel": "Cancelar",
"yes_ban_user": "Si, Suspendan el usuario"
},
"suspenduser": {
"title": "Suspendiendo un usuario",
"title_0": "Esta queriendo suspender un usuario?",
"description_0": "Le gustaria suspender a esta usuaria temporarianmente por su nombre de usuario? Si lo hace sus comentarios serán escondidos temporariamente hasta que puedan reescribir su nombre de usuario.",
"title_1": "Enviarle una nota al usuario sobre su cuenta suspendida",
"description_1": "Si suspende a este usuario, su cuenta va a ser deshabilitada y todos sus comentarios escondidos del sitio.",
"no_cancel": "No, cancelar",
"yes_suspend": "Si, suspender",
"send": "Enviar",
"username": "nombre de usuario",
"email_subject": "Su cuenta ha sido suspendida temporariamente",
"email": "Otra persona de la comunidad recientemente marcó su nombre de usuario para ser revisado. Por su contenido, el nombre de usuario ha sido rechazado. Esto quiere decir que no puede comentar, gustar o marcar contenido hasta que modifique su nombre de usuario. Por favor, envienos un correo a moderator@newsorg.com si tiene alguna pregunta o preocupación",
"write_message": "Escribir un mensaje"
},
"modqueue": {
"likes": "gustos",
"premod": "pre-mod",