diff --git a/app/soapbox/features/admin/reports.js b/app/soapbox/features/admin/reports.js
deleted file mode 100644
index 1c9d921cd..000000000
--- a/app/soapbox/features/admin/reports.js
+++ /dev/null
@@ -1,76 +0,0 @@
-import PropTypes from 'prop-types';
-import React from 'react';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-import { defineMessages, injectIntl } from 'react-intl';
-import { connect } from 'react-redux';
-
-import { fetchReports } from 'soapbox/actions/admin';
-import ScrollableList from 'soapbox/components/scrollable_list';
-import { makeGetReport } from 'soapbox/selectors';
-
-import Report from './components/report';
-
-const messages = defineMessages({
- heading: { id: 'column.admin.reports', defaultMessage: 'Reports' },
- modlog: { id: 'column.admin.reports.menu.moderation_log', defaultMessage: 'Moderation Log' },
- emptyMessage: { id: 'admin.reports.empty_message', defaultMessage: 'There are no open reports. If a user gets reported, they will show up here.' },
-});
-
-const mapStateToProps = state => {
- const getReport = makeGetReport();
- const ids = state.getIn(['admin', 'openReports']);
-
- return {
- reports: ids.toList().map(id => getReport(state, id)),
- };
-};
-
-export default @connect(mapStateToProps)
-@injectIntl
-class Reports extends ImmutablePureComponent {
-
- static propTypes = {
- intl: PropTypes.object.isRequired,
- reports: ImmutablePropTypes.list.isRequired,
- };
-
- state = {
- isLoading: true,
- }
-
- makeColumnMenu = () => {
- const { intl } = this.props;
-
- return [{
- text: intl.formatMessage(messages.modlog),
- to: '/admin/log',
- icon: require('@tabler/icons/icons/list.svg'),
- }];
- }
-
- componentDidMount() {
- const { dispatch } = this.props;
- dispatch(fetchReports())
- .then(() => this.setState({ isLoading: false }))
- .catch(() => {});
- }
-
- render() {
- const { intl, reports } = this.props;
- const { isLoading } = this.state;
- const showLoading = isLoading && reports.count() === 0;
-
- return (
-
- {reports.map(report => )}
-
- );
- }
-
-}
diff --git a/app/soapbox/features/admin/reports.tsx b/app/soapbox/features/admin/reports.tsx
new file mode 100644
index 000000000..4c6e851d6
--- /dev/null
+++ b/app/soapbox/features/admin/reports.tsx
@@ -0,0 +1,50 @@
+import React, { useState, useEffect } from 'react';
+import { defineMessages, useIntl } from 'react-intl';
+
+import { fetchReports } from 'soapbox/actions/admin';
+import ScrollableList from 'soapbox/components/scrollable_list';
+import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
+import { makeGetReport } from 'soapbox/selectors';
+
+import Report from './components/report';
+
+const messages = defineMessages({
+ heading: { id: 'column.admin.reports', defaultMessage: 'Reports' },
+ modlog: { id: 'column.admin.reports.menu.moderation_log', defaultMessage: 'Moderation Log' },
+ emptyMessage: { id: 'admin.reports.empty_message', defaultMessage: 'There are no open reports. If a user gets reported, they will show up here.' },
+});
+
+const getReport = makeGetReport();
+
+const Reports: React.FC = () => {
+ const intl = useIntl();
+ const dispatch = useAppDispatch();
+
+ const [isLoading, setLoading] = useState(true);
+
+ const reports = useAppSelector(state => {
+ const ids = state.admin.openReports;
+ return ids.toList().map(id => getReport(state, id));
+ });
+
+ useEffect(() => {
+ dispatch(fetchReports())
+ .then(() => setLoading(false))
+ .catch(() => {});
+ }, []);
+
+ const showLoading = isLoading && reports.count() === 0;
+
+ return (
+
+ {reports.map(report => )}
+
+ );
+};
+
+export default Reports;