diff --git a/app/soapbox/features/admin/awaiting_approval.js b/app/soapbox/features/admin/awaiting_approval.js
index 4070c8a35..0d95fa685 100644
--- a/app/soapbox/features/admin/awaiting_approval.js
+++ b/app/soapbox/features/admin/awaiting_approval.js
@@ -5,24 +5,18 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Column from '../ui/components/column';
-import IconButton from 'soapbox/components/icon_button';
import ScrollableList from 'soapbox/components/scrollable_list';
-import { fetchUsers, deleteUsers, approveUsers } from 'soapbox/actions/admin';
-import snackbar from 'soapbox/actions/snackbar';
+import UnapprovedAccount from './components/unapproved_account';
+import { fetchUsers } from 'soapbox/actions/admin';
const messages = defineMessages({
heading: { id: 'column.admin.awaiting_approval', defaultMessage: 'Awaiting Approval' },
emptyMessage: { id: 'admin.awaiting_approval.empty_message', defaultMessage: 'There is nobody waiting for approval. When a new user signs up, you can review them here.' },
- approved: { id: 'admin.awaiting_approval.approved_message', defaultMessage: '{acct} was approved!' },
- rejected: { id: 'admin.awaiting_approval.rejected_message', defaultMessage: '{acct} was rejected.' },
});
-const mapStateToProps = state => {
- const nicknames = state.getIn(['admin', 'awaitingApproval']);
- return {
- users: nicknames.toList().map(nickname => state.getIn(['admin', 'users', nickname])),
- };
-};
+const mapStateToProps = state => ({
+ accountIds: state.getIn(['admin', 'awaitingApproval']),
+});
export default @connect(mapStateToProps)
@injectIntl
@@ -30,7 +24,7 @@ class AwaitingApproval extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
- users: ImmutablePropTypes.list.isRequired,
+ accountIds: ImmutablePropTypes.orderedSet.isRequired,
};
state = {
@@ -44,45 +38,21 @@ class AwaitingApproval extends ImmutablePureComponent {
.catch(() => {});
}
- handleApprove = nickname => {
- const { dispatch, intl } = this.props;
- return e => {
- dispatch(approveUsers([nickname])).then(() => {
- const message = intl.formatMessage(messages.approved, { acct: `@${nickname}` });
- dispatch(snackbar.success(message));
- }).catch(() => {});
- };
- }
-
- handleReject = nickname => {
- const { dispatch, intl } = this.props;
- return e => {
- dispatch(deleteUsers([nickname])).then(() => {
- const message = intl.formatMessage(messages.rejected, { acct: `@${nickname}` });
- dispatch(snackbar.info(message));
- }).catch(() => {});
- };
- }
-
render() {
- const { intl, users } = this.props;
+ const { intl, accountIds } = this.props;
const { isLoading } = this.state;
- const showLoading = isLoading && users.count() === 0;
+ const showLoading = isLoading && accountIds.count() === 0;
return (
-
- {users.map((user, i) => (
-
-
-
@{user.get('nickname')}
-
{user.get('registration_reason')}
-
-
-
-
-
-
+
+ {accountIds.map(id => (
+
))}
diff --git a/app/soapbox/features/admin/components/unapproved_account.js b/app/soapbox/features/admin/components/unapproved_account.js
new file mode 100644
index 000000000..578a55c0c
--- /dev/null
+++ b/app/soapbox/features/admin/components/unapproved_account.js
@@ -0,0 +1,77 @@
+import React from 'react';
+import { defineMessages, injectIntl } from 'react-intl';
+import { connect } from 'react-redux';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import IconButton from 'soapbox/components/icon_button';
+import { deleteUsers, approveUsers } from 'soapbox/actions/admin';
+import { makeGetAccount } from 'soapbox/selectors';
+import snackbar from 'soapbox/actions/snackbar';
+
+const messages = defineMessages({
+ approved: { id: 'admin.awaiting_approval.approved_message', defaultMessage: '{acct} was approved!' },
+ rejected: { id: 'admin.awaiting_approval.rejected_message', defaultMessage: '{acct} was rejected.' },
+});
+
+const makeMapStateToProps = () => {
+ const getAccount = makeGetAccount();
+
+ const mapStateToProps = (state, { accountId }) => {
+ return {
+ account: getAccount(state, accountId),
+ };
+ };
+
+ return mapStateToProps;
+};
+
+export default @connect(makeMapStateToProps)
+@injectIntl
+class UnapprovedAccount extends ImmutablePureComponent {
+
+ static propTypes = {
+ intl: PropTypes.object.isRequired,
+ account: ImmutablePropTypes.map.isRequired,
+ };
+
+ handleApprove = () => {
+ const { dispatch, intl, account } = this.props;
+
+ dispatch(approveUsers([account.get('id')]))
+ .then(() => {
+ const message = intl.formatMessage(messages.approved, { acct: `@${account.get('acct')}` });
+ dispatch(snackbar.success(message));
+ })
+ .catch(() => {});
+ }
+
+ handleReject = () => {
+ const { dispatch, intl, account } = this.props;
+
+ dispatch(deleteUsers([account.get('id')]))
+ .then(() => {
+ const message = intl.formatMessage(messages.rejected, { acct: `@${account.get('acct')}` });
+ dispatch(snackbar.info(message));
+ })
+ .catch(() => {});
+ }
+
+ render() {
+ const { account } = this.props;
+
+ return (
+
+
+
@{account.get('acct')}
+
{account.getIn(['pleroma', 'admin', 'registration_reason'])}
+
+
+
+
+
+
+ );
+ }
+
+}
diff --git a/app/soapbox/features/admin/user_index.js b/app/soapbox/features/admin/user_index.js
index 7d8fc4d3d..4820ba815 100644
--- a/app/soapbox/features/admin/user_index.js
+++ b/app/soapbox/features/admin/user_index.js
@@ -33,8 +33,8 @@ class UserIndex extends ImmutablePureComponent {
}
fetchNextPage = () => {
- const nextPage = this.state.page + 1;
- const filters = this.state.filters.toJS();
+ const { filters, page } = this.state;
+ const nextPage = page + 1;
this.props.dispatch(fetchUsers(filters, nextPage))
.then(({ users, count }) => {
diff --git a/app/soapbox/reducers/admin.js b/app/soapbox/reducers/admin.js
index 58e8e354e..ebd009ed9 100644
--- a/app/soapbox/reducers/admin.js
+++ b/app/soapbox/reducers/admin.js
@@ -31,9 +31,12 @@ function importUsers(state, users) {
users.forEach(user => {
user = normalizePleromaUserFields(user);
if (!user.is_approved) {
- state.update('awaitingApproval', orderedSet => orderedSet.add(user.nickname));
+ state.update('awaitingApproval', orderedSet => orderedSet.add(user.id));
}
- state.setIn(['users', user.nickname], fromJS(user));
+ state.setIn(['users', user.id], ImmutableMap({
+ email: user.email,
+ registration_reason: user.registration_reason,
+ }));
});
});
}
diff --git a/app/soapbox/selectors/index.js b/app/soapbox/selectors/index.js
index 0615db229..9b222921e 100644
--- a/app/soapbox/selectors/index.js
+++ b/app/soapbox/selectors/index.js
@@ -5,6 +5,7 @@ const getAccountBase = (state, id) => state.getIn(['accounts', id], null
const getAccountCounters = (state, id) => state.getIn(['accounts_counters', id], null);
const getAccountRelationship = (state, id) => state.getIn(['relationships', id], null);
const getAccountMoved = (state, id) => state.getIn(['accounts', state.getIn(['accounts', id, 'moved'])]);
+const getAccountAdminData = (state, id) => state.getIn(['admin', 'users', id]);
const getAccountPatron = (state, id) => {
const url = state.getIn(['accounts', id, 'url']);
return state.getIn(['patron', 'accounts', url]);
@@ -16,8 +17,9 @@ export const makeGetAccount = () => {
getAccountCounters,
getAccountRelationship,
getAccountMoved,
+ getAccountAdminData,
getAccountPatron,
- ], (base, counters, relationship, moved, patron) => {
+ ], (base, counters, relationship, moved, admin, patron) => {
if (base === null) {
return null;
}
@@ -26,6 +28,7 @@ export const makeGetAccount = () => {
map.set('relationship', relationship);
map.set('moved', moved);
map.set('patron', patron);
+ map.setIn(['pleroma', 'admin'], admin);
});
});
};