diff --git a/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx b/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx index 434ddc28e4..e06716040b 100644 --- a/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx +++ b/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx @@ -1,31 +1,18 @@ -import React, { useMemo } from 'react'; -import { defineMessages, FormattedMessage, useIntl, MessageDescriptor } from 'react-intl'; +import React from 'react'; +import { FormattedMessage } from 'react-intl'; -import { setRole } from 'soapbox/actions/admin'; -import snackbar from 'soapbox/actions/snackbar'; import Account from 'soapbox/components/account'; import List, { ListItem } from 'soapbox/components/list'; import MissingIndicator from 'soapbox/components/missing_indicator'; import { Button, HStack, Modal, Stack } from 'soapbox/components/ui'; -import { SelectDropdown } from 'soapbox/features/forms'; -import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks'; +import { useAppSelector, useFeatures } from 'soapbox/hooks'; import { makeGetAccount } from 'soapbox/selectors'; import { isLocal } from 'soapbox/utils/accounts'; -import type { Account as AccountEntity } from 'soapbox/types/entities'; +import StaffRolePicker from './staff-role-picker'; const getAccount = makeGetAccount(); -const messages = defineMessages({ - roleUser: { id: 'account_moderation_modal.roles.user', defaultMessage: 'User' }, - roleModerator: { id: 'account_moderation_modal.roles.moderator', defaultMessage: 'Moderator' }, - roleAdmin: { id: 'account_moderation_modal.roles.admin', defaultMessage: 'Admin' }, - promotedToAdmin: { id: 'admin.users.actions.promote_to_admin_message', defaultMessage: '@{acct} was promoted to an admin' }, - promotedToModerator: { id: 'admin.users.actions.promote_to_moderator_message', defaultMessage: '@{acct} was promoted to a moderator' }, - demotedToModerator: { id: 'admin.users.actions.demote_to_moderator_message', defaultMessage: '@{acct} was demoted to a moderator' }, - demotedToUser: { id: 'admin.users.actions.demote_to_user_message', defaultMessage: '@{acct} was demoted to a regular user' }, -}); - interface IAccountModerationModal { /** Action to close the modal. */ onClose: (type: string) => void, @@ -33,34 +20,11 @@ interface IAccountModerationModal { accountId: string, } -/** Staff role. */ -type AccountRole = 'user' | 'moderator' | 'admin'; - -/** Get the highest staff role associated with the account. */ -const getRole = (account: AccountEntity): AccountRole => { - if (account.admin) { - return 'admin'; - } else if (account.moderator) { - return 'moderator'; - } else { - return 'user'; - } -}; - /** Moderator actions against accounts. */ const AccountModerationModal: React.FC = ({ onClose, accountId }) => { - const intl = useIntl(); - const dispatch = useAppDispatch(); - const features = useFeatures(); const account = useAppSelector(state => getAccount(state, accountId)); - const roles: Record = useMemo(() => ({ - user: intl.formatMessage(messages.roleUser), - moderator: intl.formatMessage(messages.roleModerator), - admin: intl.formatMessage(messages.roleAdmin), - }), []); - const handleClose = () => onClose('ACCOUNT_MODERATION'); if (!account) { @@ -75,32 +39,6 @@ const AccountModerationModal: React.FC = ({ onClose, ac window.open(`/pleroma/admin/#/users/${account.id}/`, '_blank'); }; - const handleRoleChange: React.ChangeEventHandler = (e) => { - const role = e.target.value as AccountRole; - - dispatch(setRole(account.id, role)) - .then(() => { - let message: MessageDescriptor | undefined; - - if (role === 'admin') { - message = messages.promotedToAdmin; - } else if (role === 'moderator' && account.admin) { - message = messages.demotedToModerator; - } else if (role === 'moderator') { - message = messages.promotedToModerator; - } else if (role === 'user') { - message = messages.demotedToUser; - } - - if (message) { - dispatch(snackbar.success(intl.formatMessage(message, { acct: account.acct }))); - } - }) - .catch(() => {}); - }; - - const accountRole = getRole(account); - return ( } @@ -119,11 +57,9 @@ const AccountModerationModal: React.FC = ({ onClose, ac {isLocal(account) && ( }> - +
+ +
)} diff --git a/app/soapbox/features/ui/components/modals/account-moderation-modal/staff-role-picker.tsx b/app/soapbox/features/ui/components/modals/account-moderation-modal/staff-role-picker.tsx new file mode 100644 index 0000000000..30502d427c --- /dev/null +++ b/app/soapbox/features/ui/components/modals/account-moderation-modal/staff-role-picker.tsx @@ -0,0 +1,86 @@ +import React, { useMemo } from 'react'; +import { defineMessages, MessageDescriptor, useIntl } from 'react-intl'; + +import { setRole } from 'soapbox/actions/admin'; +import snackbar from 'soapbox/actions/snackbar'; +import { SelectDropdown } from 'soapbox/features/forms'; +import { useAppDispatch } from 'soapbox/hooks'; + +import type { Account as AccountEntity } from 'soapbox/types/entities'; + +/** Staff role. */ +type AccountRole = 'user' | 'moderator' | 'admin'; + +/** Get the highest staff role associated with the account. */ +const getRole = (account: AccountEntity): AccountRole => { + if (account.admin) { + return 'admin'; + } else if (account.moderator) { + return 'moderator'; + } else { + return 'user'; + } +}; + +const messages = defineMessages({ + roleUser: { id: 'account_moderation_modal.roles.user', defaultMessage: 'User' }, + roleModerator: { id: 'account_moderation_modal.roles.moderator', defaultMessage: 'Moderator' }, + roleAdmin: { id: 'account_moderation_modal.roles.admin', defaultMessage: 'Admin' }, + promotedToAdmin: { id: 'admin.users.actions.promote_to_admin_message', defaultMessage: '@{acct} was promoted to an admin' }, + promotedToModerator: { id: 'admin.users.actions.promote_to_moderator_message', defaultMessage: '@{acct} was promoted to a moderator' }, + demotedToModerator: { id: 'admin.users.actions.demote_to_moderator_message', defaultMessage: '@{acct} was demoted to a moderator' }, + demotedToUser: { id: 'admin.users.actions.demote_to_user_message', defaultMessage: '@{acct} was demoted to a regular user' }, +}); + +interface IStaffRolePicker { + /** Account whose role to change. */ + account: AccountEntity, +} + +/** Picker for setting the staff role of an account. */ +const StaffRolePicker: React.FC = ({ account }) => { + const intl = useIntl(); + const dispatch = useAppDispatch(); + + const roles: Record = useMemo(() => ({ + user: intl.formatMessage(messages.roleUser), + moderator: intl.formatMessage(messages.roleModerator), + admin: intl.formatMessage(messages.roleAdmin), + }), []); + + const handleRoleChange: React.ChangeEventHandler = (e) => { + const role = e.target.value as AccountRole; + + dispatch(setRole(account.id, role)) + .then(() => { + let message: MessageDescriptor | undefined; + + if (role === 'admin') { + message = messages.promotedToAdmin; + } else if (role === 'moderator' && account.admin) { + message = messages.demotedToModerator; + } else if (role === 'moderator') { + message = messages.promotedToModerator; + } else if (role === 'user') { + message = messages.demotedToUser; + } + + if (message) { + dispatch(snackbar.success(intl.formatMessage(message, { acct: account.acct }))); + } + }) + .catch(() => {}); + }; + + const accountRole = getRole(account); + + return ( + + ); +}; + +export default StaffRolePicker; \ No newline at end of file