From 8aa61a6d0ee935347b4ea64db5ab76070863c734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 1 Aug 2025 07:25:47 +0200 Subject: [PATCH] pl-fe: account moderation interface updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- .../src/components/status-action-bar.tsx | 7 +- .../features/account/components/header.tsx | 6 +- .../src/features/admin/components/report.tsx | 4 +- .../event/components/event-header.tsx | 8 +- .../src/features/ui/components/modal-root.tsx | 1 - packages/pl-fe/src/features/ui/index.tsx | 2 + .../src/features/ui/util/async-components.ts | 3 +- packages/pl-fe/src/locales/en.json | 4 +- .../account-moderation-modal/badge-input.tsx | 37 ----- .../staff-role-picker.tsx | 86 ---------- .../index.tsx => pages/dashboard/account.tsx} | 149 +++++++++++++++--- packages/pl-fe/src/pages/dashboard/report.tsx | 40 ++--- .../pl-fe/src/queries/admin/use-accounts.ts | 113 ++++++++++++- .../pl-fe/src/queries/utils/minify-list.ts | 12 +- packages/pl-fe/src/stores/modals.ts | 2 - 15 files changed, 276 insertions(+), 198 deletions(-) delete mode 100644 packages/pl-fe/src/modals/account-moderation-modal/badge-input.tsx delete mode 100644 packages/pl-fe/src/modals/account-moderation-modal/staff-role-picker.tsx rename packages/pl-fe/src/{modals/account-moderation-modal/index.tsx => pages/dashboard/account.tsx} (57%) diff --git a/packages/pl-fe/src/components/status-action-bar.tsx b/packages/pl-fe/src/components/status-action-bar.tsx index a16ff6f77..2f39f2c3b 100644 --- a/packages/pl-fe/src/components/status-action-bar.tsx +++ b/packages/pl-fe/src/components/status-action-bar.tsx @@ -777,11 +777,6 @@ const MenuButton: React.FC = ({ copy(uri); }; - const onModerate: React.MouseEventHandler = (e) => { - const account = status.account; - openModal('ACCOUNT_MODERATION', { accountId: account.id }); - }; - const handleDeleteStatus: React.EventHandler = (e) => { dispatch(deleteStatusModal(intl, status.id)); }; @@ -1073,7 +1068,7 @@ const MenuButton: React.FC = ({ menu.push({ text: intl.formatMessage(messages.adminAccount, { name: username }), - action: onModerate, + to: `/pl-fe/admin/accounts/${status.account_id}`, icon: require('@tabler/icons/outline/gavel.svg'), }); diff --git a/packages/pl-fe/src/features/account/components/header.tsx b/packages/pl-fe/src/features/account/components/header.tsx index 991530576..fda946db7 100644 --- a/packages/pl-fe/src/features/account/components/header.tsx +++ b/packages/pl-fe/src/features/account/components/header.tsx @@ -272,10 +272,6 @@ const Header: React.FC = ({ account }) => { }); }; - const onModerate = () => { - openModal('ACCOUNT_MODERATION', { accountId: account.id }); - }; - const onRemoveFromFollowers = () => { const unfollowModal = settings.unfollowModal; if (unfollowModal) { @@ -549,7 +545,7 @@ const Header: React.FC = ({ account }) => { menu.push({ text: intl.formatMessage(messages.adminAccount, { name: account.username }), - action: onModerate, + to: `/pl-fe/admin/accounts/${account.id}`, icon: require('@tabler/icons/outline/gavel.svg'), }); } diff --git a/packages/pl-fe/src/features/admin/components/report.tsx b/packages/pl-fe/src/features/admin/components/report.tsx index a4fdd005c..c90818df7 100644 --- a/packages/pl-fe/src/features/admin/components/report.tsx +++ b/packages/pl-fe/src/features/admin/components/report.tsx @@ -64,7 +64,9 @@ const Report: React.FC = ({ id }) => { /> - @{reporterAcct} + + @{reporterAcct} + )} diff --git a/packages/pl-fe/src/features/event/components/event-header.tsx b/packages/pl-fe/src/features/event/components/event-header.tsx index 25cb56f09..65310c3c4 100644 --- a/packages/pl-fe/src/features/event/components/event-header.tsx +++ b/packages/pl-fe/src/features/event/components/event-header.tsx @@ -204,10 +204,6 @@ const EventHeader: React.FC = ({ status }) => { dispatch(initReport(ReportableEntities.STATUS, account, { status })); }; - const handleModerate = () => { - openModal('ACCOUNT_MODERATION', { accountId: account.id }); - }; - const handleModerateStatus = () => { window.open(`/pleroma/admin/#/statuses/${status.id}/`, '_blank'); }; @@ -357,8 +353,8 @@ const EventHeader: React.FC = ({ status }) => { menu.push(null); menu.push({ - text: intl.formatMessage(messages.adminAccount, { name: account.username }), - action: handleModerate, + text: intl.formatMessage(messages.adminAccount, { name: username }), + to: `/pl-fe/admin/accounts/${account.id}`, icon: require('@tabler/icons/outline/gavel.svg'), }); diff --git a/packages/pl-fe/src/features/ui/components/modal-root.tsx b/packages/pl-fe/src/features/ui/components/modal-root.tsx index 564ac001a..fd6b010f8 100644 --- a/packages/pl-fe/src/features/ui/components/modal-root.tsx +++ b/packages/pl-fe/src/features/ui/components/modal-root.tsx @@ -9,7 +9,6 @@ import ModalLoading from './modal-loading'; /* eslint sort-keys: "error" */ const MODAL_COMPONENTS = { - ACCOUNT_MODERATION: lazy(() => import('pl-fe/modals/account-moderation-modal')), ALT_TEXT: lazy(() => import('pl-fe/modals/alt-text-modal')), BIRTHDAYS: lazy(() => import('pl-fe/modals/birthdays-modal')), BOOST: lazy(() => import('pl-fe/modals/boost-modal')), diff --git a/packages/pl-fe/src/features/ui/index.tsx b/packages/pl-fe/src/features/ui/index.tsx index 653059127..46fc1ccc6 100644 --- a/packages/pl-fe/src/features/ui/index.tsx +++ b/packages/pl-fe/src/features/ui/index.tsx @@ -56,6 +56,7 @@ import { AccountGallery, AccountHoverCard, AccountTimeline, + AdminAccount, Aliases, Announcements, AuthTokenList, @@ -329,6 +330,7 @@ const SwitchingColumnsArea: React.FC = React.memo(({ chil + diff --git a/packages/pl-fe/src/features/ui/util/async-components.ts b/packages/pl-fe/src/features/ui/util/async-components.ts index c14c938f2..d287e7290 100644 --- a/packages/pl-fe/src/features/ui/util/async-components.ts +++ b/packages/pl-fe/src/features/ui/util/async-components.ts @@ -1,9 +1,10 @@ import { lazy } from 'react'; // Pages +export const AboutPage = lazy(() => import('pl-fe/pages/utils/about')); export const AccountGallery = lazy(() => import('pl-fe/pages/accounts/account-gallery')); export const AccountTimeline = lazy(() => import('pl-fe/pages/accounts/account-timeline')); -export const AboutPage = lazy(() => import('pl-fe/pages/utils/about')); +export const AdminAccount = lazy(() => import('pl-fe/pages/dashboard/account')); export const Aliases = lazy(() => import('pl-fe/pages/settings/aliases')); export const Announcements = lazy(() => import('pl-fe/pages/dashboard/announcements')); export const AuthTokenList = lazy(() => import('pl-fe/pages/settings/auth-token-list')); diff --git a/packages/pl-fe/src/locales/en.json b/packages/pl-fe/src/locales/en.json index eef866b4f..fbe55c3b7 100644 --- a/packages/pl-fe/src/locales/en.json +++ b/packages/pl-fe/src/locales/en.json @@ -97,7 +97,6 @@ "account_moderation_modal.roles.admin": "Admin", "account_moderation_modal.roles.moderator": "Moderator", "account_moderation_modal.roles.user": "User", - "account_moderation_modal.title": "Moderate @{acct}", "account_note.header": "Note", "account_note.placeholder": "Click to add a note", "account_search.placeholder": "Search for an account", @@ -193,7 +192,7 @@ "admin.report.action_taken.true": "Resolved", "admin.report.assigned_account": "Assigned moderator", "admin.report.created_at": "Reported", - "admin.report.moderate": "Open account in moderation interface", + "admin.report.moderate": "Moderate account", "admin.report.reopen": "Reopen report", "admin.report.reported_by": "Reported by", "admin.report.resolve": "Mark as resolved", @@ -358,6 +357,7 @@ "circles.new.create_title": "Add circle", "circles.new.title_placeholder": "New circle title", "circles.subheading": "Your circles", + "column.admin.account": "Moderate @{acct}", "column.admin.announcements": "Announcements", "column.admin.awaiting_approval": "Awaiting Approval", "column.admin.create_announcement": "Create announcement", diff --git a/packages/pl-fe/src/modals/account-moderation-modal/badge-input.tsx b/packages/pl-fe/src/modals/account-moderation-modal/badge-input.tsx deleted file mode 100644 index 7d9218c7d..000000000 --- a/packages/pl-fe/src/modals/account-moderation-modal/badge-input.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import { useIntl, defineMessages } from 'react-intl'; - -import TagInput from 'pl-fe/components/ui/tag-input'; -import { badgeToTag, tagToBadge } from 'pl-fe/utils/badges'; - -const messages = defineMessages({ - placeholder: { id: 'badge_input.placeholder', defaultMessage: 'Enter a badge…' }, -}); - -interface IBadgeInput { - /** A badge is a tag that begins with `badge:` */ - badges: string[]; - /** Callback when badges change. */ - onChange: (badges: string[]) => void; -} - -/** Manages user badges. */ -const BadgeInput: React.FC = ({ badges, onChange }) => { - const intl = useIntl(); - const tags = badges.map(badgeToTag); - - const handleTagsChange = (tags: string[]) => { - const badges = tags.map(tagToBadge); - onChange(badges); - }; - - return ( - - ); -}; - -export { BadgeInput as default }; diff --git a/packages/pl-fe/src/modals/account-moderation-modal/staff-role-picker.tsx b/packages/pl-fe/src/modals/account-moderation-modal/staff-role-picker.tsx deleted file mode 100644 index 181315860..000000000 --- a/packages/pl-fe/src/modals/account-moderation-modal/staff-role-picker.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React, { useMemo } from 'react'; -import { defineMessages, MessageDescriptor, useIntl } from 'react-intl'; - -import { setRole } from 'pl-fe/actions/admin'; -import { SelectDropdown } from 'pl-fe/features/forms'; -import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; -import toast from 'pl-fe/toast'; - -import type { Account as AccountEntity } from 'pl-fe/normalizers/account'; - -/** Staff role. */ -type AccountRole = 'user' | 'moderator' | 'admin'; - -/** Get the highest staff role associated with the account. */ -const getRole = (account: Pick): AccountRole => { - if (account.is_admin) { - return 'admin'; - } else if (account.is_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: Pick; -} - -/** 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.is_admin) { - message = messages.demotedToModerator; - } else if (role === 'moderator') { - message = messages.promotedToModerator; - } else if (role === 'user') { - message = messages.demotedToUser; - } - - if (message) { - toast.success(intl.formatMessage(message, { acct: account.acct })); - } - }) - .catch(() => {}); - }; - - const accountRole = getRole(account); - - return ( - - ); -}; - -export { StaffRolePicker as default }; diff --git a/packages/pl-fe/src/modals/account-moderation-modal/index.tsx b/packages/pl-fe/src/pages/dashboard/account.tsx similarity index 57% rename from packages/pl-fe/src/modals/account-moderation-modal/index.tsx rename to packages/pl-fe/src/pages/dashboard/account.tsx index f37e8216c..9c178cbbc 100644 --- a/packages/pl-fe/src/modals/account-moderation-modal/index.tsx +++ b/packages/pl-fe/src/pages/dashboard/account.tsx @@ -1,8 +1,8 @@ import { PLEROMA } from 'pl-api'; -import React, { ChangeEventHandler, useState } from 'react'; -import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; +import React, { ChangeEventHandler, useMemo, useState } from 'react'; +import { defineMessages, FormattedMessage, type MessageDescriptor, useIntl } from 'react-intl'; -import { setBadges as saveBadges } from 'pl-fe/actions/admin'; +import { setBadges as saveBadges, setRole } from 'pl-fe/actions/admin'; import { deactivateUserModal, deleteUserModal } from 'pl-fe/actions/moderation'; import { useAccount } from 'pl-fe/api/hooks/accounts/use-account'; import { useSuggest } from 'pl-fe/api/hooks/admin/use-suggest'; @@ -12,37 +12,139 @@ import List, { ListItem } from 'pl-fe/components/list'; import MissingIndicator from 'pl-fe/components/missing-indicator'; import OutlineBox from 'pl-fe/components/outline-box'; import Button from 'pl-fe/components/ui/button'; +import Column from 'pl-fe/components/ui/column'; import HStack from 'pl-fe/components/ui/hstack'; -import Modal from 'pl-fe/components/ui/modal'; import Stack from 'pl-fe/components/ui/stack'; +import TagInput from 'pl-fe/components/ui/tag-input'; import Text from 'pl-fe/components/ui/text'; import Toggle from 'pl-fe/components/ui/toggle'; +import { SelectDropdown } from 'pl-fe/features/forms'; +import ColumnLoading from 'pl-fe/features/ui/components/column-loading'; import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; import { useFeatures } from 'pl-fe/hooks/use-features'; import { useOwnAccount } from 'pl-fe/hooks/use-own-account'; import toast from 'pl-fe/toast'; -import { getBadges } from 'pl-fe/utils/badges'; +import { badgeToTag, tagToBadge, getBadges } from 'pl-fe/utils/badges'; -import BadgeInput from './badge-input'; -import StaffRolePicker from './staff-role-picker'; - -import type { BaseModalProps } from 'pl-fe/features/ui/components/modal-root'; +import type { Account as AccountEntity } from 'pl-fe/normalizers/account'; const messages = defineMessages({ + columnHeading: { id: 'column.admin.account', defaultMessage: 'Moderate @{acct}' }, userVerified: { id: 'admin.users.user_verified_message', defaultMessage: '@{acct} was verified' }, userUnverified: { id: 'admin.users.user_unverified_message', defaultMessage: '@{acct} was unverified' }, userSuggested: { id: 'admin.users.user_suggested_message', defaultMessage: '@{acct} was suggested' }, userUnsuggested: { id: 'admin.users.user_unsuggested_message', defaultMessage: '@{acct} was unsuggested' }, badgesSaved: { id: 'admin.users.badges_saved_message', defaultMessage: 'Custom badges updated.' }, + badgePlaceholder: { id: 'badge_input.placeholder', defaultMessage: 'Enter a badge…' }, + 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 AccountModerationModalProps { - /** ID of the account to moderate. */ - accountId: string; +/** Staff role. */ +type AccountRole = 'user' | 'moderator' | 'admin'; + +/** Get the highest staff role associated with the account. */ +const getRole = (account: Pick): AccountRole => { + if (account.is_admin) { + return 'admin'; + } else if (account.is_moderator) { + return 'moderator'; + } else { + return 'user'; + } +}; + +interface IStaffRolePicker { + /** Account whose role to change. */ + account: Pick; } -/** Moderator actions against accounts. */ -const AccountModerationModal: React.FC = ({ onClose, accountId }) => { +/** 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.is_admin) { + message = messages.demotedToModerator; + } else if (role === 'moderator') { + message = messages.promotedToModerator; + } else if (role === 'user') { + message = messages.demotedToUser; + } + + if (message) { + toast.success(intl.formatMessage(message, { acct: account.acct })); + } + }) + .catch(() => {}); + }; + + const accountRole = getRole(account); + + return ( + + ); +}; + +interface IBadgeInput { + /** A badge is a tag that begins with `badge:` */ + badges: string[]; + /** Callback when badges change. */ + onChange: (badges: string[]) => void; +} + +/** Manages user badges. */ +const BadgeInput: React.FC = ({ badges, onChange }) => { + const intl = useIntl(); + const tags = badges.map(badgeToTag); + + const handleTagsChange = (tags: string[]) => { + const badges = tags.map(tagToBadge); + onChange(badges); + }; + + return ( + + ); +}; + +type RouteParams = { accountId: string }; + +interface IAdminAccountPage { + params: RouteParams; +} + +const AdminAccountPage: React.FC = (props) => { + const { accountId } = props.params; + const intl = useIntl(); const dispatch = useAppDispatch(); @@ -50,18 +152,20 @@ const AccountModerationModal: React.FC(accountBadges); - const handleClose = () => onClose('ACCOUNT_MODERATION'); + if (isLoading) { + return ; + } if (!account || !ownAccount) { return ( - + - + ); } @@ -106,10 +210,7 @@ const AccountModerationModal: React.FC} - onClose={handleClose} - > + )} - + ); }; -export { type AccountModerationModalProps, AccountModerationModal as default }; +export { AdminAccountPage as default }; diff --git a/packages/pl-fe/src/pages/dashboard/report.tsx b/packages/pl-fe/src/pages/dashboard/report.tsx index 030c73b25..0e94b1765 100644 --- a/packages/pl-fe/src/pages/dashboard/report.tsx +++ b/packages/pl-fe/src/pages/dashboard/report.tsx @@ -34,8 +34,6 @@ const messages = defineMessages({ reportCommentConfirm: { id: 'report.resolve.comment.confirm', defaultMessage: 'Resolve report' }, }); -type RouteParams = { reportId: string }; - interface IReportStatuses { statusIds: Array; } @@ -76,6 +74,8 @@ const ReportStatuses: React.FC = ({ statusIds }) => { ); }; +type RouteParams = { reportId: string }; + interface IReportPage { params: RouteParams; } @@ -175,19 +175,23 @@ const ReportPage: React.FC = (props) => { - - - - - - + {report.account && ( + + + + + + - - - {report.account?.acct} - - - + + + + @{report.account.acct} + + + + + )} @@ -212,8 +216,8 @@ const ReportPage: React.FC = (props) => { {report.assigned_account ? ( - - + + @{report.assigned_account.acct} @@ -263,8 +267,8 @@ const ReportPage: React.FC = (props) => { /> )} } - onClick={() => openModal('ACCOUNT_MODERATION', { accountId: report.target_account_id })} + label={} + to={`/pl-fe/admin/accounts/${report.target_account_id}`} /> diff --git a/packages/pl-fe/src/queries/admin/use-accounts.ts b/packages/pl-fe/src/queries/admin/use-accounts.ts index 0feed6713..89e54fa18 100644 --- a/packages/pl-fe/src/queries/admin/use-accounts.ts +++ b/packages/pl-fe/src/queries/admin/use-accounts.ts @@ -1,5 +1,5 @@ import { InfiniteData, useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { PaginatedResponse, type AdminAccount, type AdminGetAccountsParams, type PaginationParams } from 'pl-api'; + import { importEntities } from 'pl-fe/actions/importer'; import { useAccount } from 'pl-fe/api/hooks/accounts/use-account'; @@ -10,7 +10,9 @@ import { useOwnAccount } from 'pl-fe/hooks/use-own-account'; import { filterById } from '../utils/filter-id'; import { makePaginatedResponseQuery } from '../utils/make-paginated-response-query'; import { makePaginatedResponseQueryOptions } from '../utils/make-paginated-response-query-options'; -import { minifyAdminAccountList } from '../utils/minify-list'; +import { minifyAdminAccount, minifyAdminAccountList } from '../utils/minify-list'; + +import type { AdminPerformAccountActionParams, PaginatedResponse, AdminAccount, AdminGetAccountsParams, PaginationParams, AdminAccountAction } from 'pl-api'; const useAdminAccounts = makePaginatedResponseQuery( @@ -93,4 +95,109 @@ const useAdminRejectAccountMutation = (accountId: string) => { }); }; -export { useAdminAccount, useAdminAccounts, pendingUsersQuery, usePendingUsersCount, useAdminApproveAccountMutation, useAdminRejectAccountMutation }; +const useAdminDeleteAccountMutation = (accountId: string) => { + const client = useClient(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationKey: ['admin', 'acounts', accountId], + mutationFn: () => client.admin.accounts.deleteAccount(accountId), + onSuccess: () => { + queryClient.setQueriesData>>({ + queryKey: ['admin', 'accountLists'], + exact: false, + }, filterById(accountId)); + }, + }); +}; + +const useAdminPerformAccountActionMutation = (accountId: string, type: AdminAccountAction) => { + const client = useClient(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationKey: ['admin', 'acounts', accountId], + mutationFn: (params?: AdminPerformAccountActionParams) => client.admin.accounts.performAccountAction(accountId, type, params), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['admin', 'accountLists'], exact: false }); + }, + }); +}; + +const useAdminEnableAccountMutation = (accountId: string) => { + const client = useClient(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationKey: ['admin', 'acounts', accountId], + mutationFn: () => client.admin.accounts.enableAccount(accountId), + onSuccess: (account) => { + queryClient.setQueriesData>>({ + queryKey: ['admin', 'accountLists', { status: 'disabled' }], + exact: false, + }, filterById(accountId)); + minifyAdminAccount(account); + }, + }); +}; + +const useAdminUnsilenceAccountMutation = (accountId: string) => { + const client = useClient(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationKey: ['admin', 'acounts', accountId], + mutationFn: () => client.admin.accounts.unsilenceAccount(accountId), + onSuccess: (account) => { + queryClient.setQueriesData>>({ + queryKey: ['admin', 'accountLists', { status: 'silenced' }], + exact: false, + }, filterById(accountId)); + minifyAdminAccount(account); + }, + }); +}; + +const useAdminUnsuspendAccountMutation = (accountId: string) => { + const client = useClient(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationKey: ['admin', 'acounts', accountId], + mutationFn: () => client.admin.accounts.unsuspendAccount(accountId), + onSuccess: (account) => { + queryClient.setQueriesData>>({ + queryKey: ['admin', 'accountLists', { status: 'suspended' }], + exact: false, + }, filterById(accountId)); + minifyAdminAccount(account); + }, + }); +}; + +const useAdminUnsensitiveAccountMutation = (accountId: string) => { + const client = useClient(); + + return useMutation({ + mutationKey: ['admin', 'acounts', accountId], + mutationFn: () => client.admin.accounts.unsensitiveAccount(accountId), + onSuccess: (account) => { + minifyAdminAccount(account); + }, + }); +}; + +export { + useAdminAccount, + useAdminAccounts, + pendingUsersQuery, + usePendingUsersCount, + useAdminApproveAccountMutation, + useAdminRejectAccountMutation, + useAdminDeleteAccountMutation, + useAdminPerformAccountActionMutation, + useAdminEnableAccountMutation, + useAdminUnsilenceAccountMutation, + useAdminUnsuspendAccountMutation, + useAdminUnsensitiveAccountMutation, +}; diff --git a/packages/pl-fe/src/queries/utils/minify-list.ts b/packages/pl-fe/src/queries/utils/minify-list.ts index 9ede3a86a..760e89059 100644 --- a/packages/pl-fe/src/queries/utils/minify-list.ts +++ b/packages/pl-fe/src/queries/utils/minify-list.ts @@ -26,12 +26,12 @@ const minifyAccountList = (response: PaginatedResponse): PaginatedRespo store.dispatch(importEntities({ accounts }) as any); }); -// const minifyAdminAccount = ({ account, ...adminAccount }: AdminAccount) => { -// store.dispatch(importEntities({ accounts: [account] }) as any); -// queryClient.setQueryData(['admin', 'accounts', adminAccount.id], adminAccount); +const minifyAdminAccount = ({ account, ...adminAccount }: AdminAccount) => { + store.dispatch(importEntities({ accounts: [account] }) as any); + queryClient.setQueryData(['admin', 'accounts', adminAccount.id], adminAccount); -// return adminAccount; -// }; + return adminAccount; +}; const minifyAdminAccountList = (response: PaginatedResponse) => minifyList(response, (account) => account.id, (accounts) => { @@ -63,4 +63,4 @@ const minifyAdminReportList = (response: PaginatedResponse) => } }); -export { minifyList, minifyAccountList, minifyStatusList, minifyAdminAccountList, minifyAdminReport, minifyAdminReportList }; +export { minifyList, minifyAccountList, minifyStatusList, minifyAdminAccount, minifyAdminAccountList, minifyAdminReport, minifyAdminReportList }; diff --git a/packages/pl-fe/src/stores/modals.ts b/packages/pl-fe/src/stores/modals.ts index e88997803..2f8bd4560 100644 --- a/packages/pl-fe/src/stores/modals.ts +++ b/packages/pl-fe/src/stores/modals.ts @@ -5,7 +5,6 @@ import { MuteModalProps } from 'pl-fe/modals/mute-modal'; import type { ICryptoAddress } from 'pl-fe/features/crypto-donate/components/crypto-address'; import type { ModalType } from 'pl-fe/features/ui/components/modal-root'; -import type { AccountModerationModalProps } from 'pl-fe/modals/account-moderation-modal'; import type { AltTextModalProps } from 'pl-fe/modals/alt-text-modal'; import type { BoostModalProps } from 'pl-fe/modals/boost-modal'; import type { CompareHistoryModalProps } from 'pl-fe/modals/compare-history-modal'; @@ -41,7 +40,6 @@ import type { UnauthorizedModalProps } from 'pl-fe/modals/unauthorized-modal'; import type { VideoModalProps } from 'pl-fe/modals/video-modal'; type OpenModalProps = - | [type: 'ACCOUNT_MODERATION', props: AccountModerationModalProps] | [type: 'ALT_TEXT', props: AltTextModalProps] | [type: 'BIRTHDAYS' | 'CREATE_GROUP' | 'HOTKEYS'] | [type: 'BOOST', props: BoostModalProps]