diff --git a/app/soapbox/actions/admin.js b/app/soapbox/actions/admin.js
index cf3a5d0e7..118f26992 100644
--- a/app/soapbox/actions/admin.js
+++ b/app/soapbox/actions/admin.js
@@ -8,6 +8,10 @@ export const ADMIN_REPORTS_FETCH_REQUEST = 'ADMIN_REPORTS_FETCH_REQUEST';
export const ADMIN_REPORTS_FETCH_SUCCESS = 'ADMIN_REPORTS_FETCH_SUCCESS';
export const ADMIN_REPORTS_FETCH_FAIL = 'ADMIN_REPORTS_FETCH_FAIL';
+export const ADMIN_USERS_FETCH_REQUEST = 'ADMIN_USERS_FETCH_REQUEST';
+export const ADMIN_USERS_FETCH_SUCCESS = 'ADMIN_USERS_FETCH_SUCCESS';
+export const ADMIN_USERS_FETCH_FAIL = 'ADMIN_USERS_FETCH_FAIL';
+
export function updateAdminConfig(params) {
return (dispatch, getState) => {
dispatch({ type: ADMIN_CONFIG_UPDATE_REQUEST });
@@ -33,3 +37,16 @@ export function fetchReports(params) {
});
};
}
+
+export function fetchUsers(params) {
+ return (dispatch, getState) => {
+ dispatch({ type: ADMIN_USERS_FETCH_REQUEST, params });
+ return api(getState)
+ .get('/api/pleroma/admin/users', { params })
+ .then(({ data }) => {
+ dispatch({ type: ADMIN_USERS_FETCH_SUCCESS, data, params });
+ }).catch(error => {
+ dispatch({ type: ADMIN_USERS_FETCH_FAIL, error, params });
+ });
+ };
+}
diff --git a/app/soapbox/features/admin/awaiting_approval.js b/app/soapbox/features/admin/awaiting_approval.js
new file mode 100644
index 000000000..8e716d644
--- /dev/null
+++ b/app/soapbox/features/admin/awaiting_approval.js
@@ -0,0 +1,46 @@
+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 Column from '../ui/components/column';
+import { fetchUsers } from 'soapbox/actions/admin';
+
+const messages = defineMessages({
+ heading: { id: 'column.admin.awaiting_approval', defaultMessage: 'Awaiting Approval' },
+});
+
+const mapStateToProps = state => {
+ const userIds = state.getIn(['admin', 'awaitingApproval']);
+ return {
+ users: userIds.map(id => state.getIn(['admin', 'users', id])),
+ };
+};
+
+export default @connect(mapStateToProps)
+@injectIntl
+class AwaitingApproval extends ImmutablePureComponent {
+
+ static propTypes = {
+ intl: PropTypes.object.isRequired,
+ users: ImmutablePropTypes.list.isRequired,
+ };
+
+ componentDidMount() {
+ this.props.dispatch(fetchUsers({ page: 1, filters: 'local,need_approval' }));
+ }
+
+ render() {
+ const { intl, users } = this.props;
+
+ return (
+
+ {users.map((user, i) => (
+ {user.get('nickname')}
+ ))}
+
+ );
+ }
+
+}
diff --git a/app/soapbox/features/admin/components/admin_nav.js b/app/soapbox/features/admin/components/admin_nav.js
index d27bbfb80..12a53b3fd 100644
--- a/app/soapbox/features/admin/components/admin_nav.js
+++ b/app/soapbox/features/admin/components/admin_nav.js
@@ -32,10 +32,10 @@ class AdminNav extends React.PureComponent {
{instance.get('approval_required') && (
-
+
-
+
)}
{!instance.get('registrations') && (
diff --git a/app/soapbox/features/ui/index.js b/app/soapbox/features/ui/index.js
index 6d6080ef7..969aadc79 100644
--- a/app/soapbox/features/ui/index.js
+++ b/app/soapbox/features/ui/index.js
@@ -88,6 +88,7 @@ import {
ChatRoom,
ServerInfo,
Dashboard,
+ AwaitingApproval,
} from './util/async-components';
// Dummy import, to make sure that ends up in the application bundle.
@@ -286,6 +287,7 @@ class SwitchingColumnsArea extends React.PureComponent {
+
diff --git a/app/soapbox/features/ui/util/async-components.js b/app/soapbox/features/ui/util/async-components.js
index 3421f2d9e..6e313b4d8 100644
--- a/app/soapbox/features/ui/util/async-components.js
+++ b/app/soapbox/features/ui/util/async-components.js
@@ -221,3 +221,7 @@ export function ServerInfo() {
export function Dashboard() {
return import(/* webpackChunkName: "features/admin" */'../../admin');
}
+
+export function AwaitingApproval() {
+ return import(/* webpackChunkName: "features/admin/awaiting_approval" */'../../admin/awaiting_approval');
+}
diff --git a/app/soapbox/reducers/admin.js b/app/soapbox/reducers/admin.js
index 2a41666f6..f120d8794 100644
--- a/app/soapbox/reducers/admin.js
+++ b/app/soapbox/reducers/admin.js
@@ -1,11 +1,32 @@
-import { ADMIN_REPORTS_FETCH_SUCCESS } from '../actions/admin';
-import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
+import {
+ ADMIN_REPORTS_FETCH_SUCCESS,
+ ADMIN_USERS_FETCH_SUCCESS,
+} from '../actions/admin';
+import {
+ Map as ImmutableMap,
+ List as ImmutableList,
+ OrderedSet as ImmutableOrderedSet,
+ fromJS,
+} from 'immutable';
const initialState = ImmutableMap({
reports: ImmutableList(),
+ users: ImmutableMap(),
open_report_count: 0,
+ awaitingApproval: ImmutableOrderedSet(),
});
+function importUsers(state, users) {
+ return state.withMutations(state => {
+ users.forEach(user => {
+ if (user.approval_pending) {
+ state.update('awaitingApproval', orderedSet => orderedSet.add(user.id));
+ }
+ state.setIn(['users', user.id], fromJS(user));
+ });
+ });
+}
+
export default function admin(state = initialState, action) {
switch(action.type) {
case ADMIN_REPORTS_FETCH_SUCCESS:
@@ -16,6 +37,8 @@ export default function admin(state = initialState, action) {
} else {
return state.set('reports', fromJS(action.data.reports));
}
+ case ADMIN_USERS_FETCH_SUCCESS:
+ return importUsers(state, action.data.users);
default:
return state;
}