diff --git a/app/soapbox/features/admin/awaiting_approval.js b/app/soapbox/features/admin/awaiting_approval.js index 6b67dd02e8..03a7d5a05e 100644 Binary files a/app/soapbox/features/admin/awaiting_approval.js and b/app/soapbox/features/admin/awaiting_approval.js differ diff --git a/app/soapbox/features/admin/index.tsx b/app/soapbox/features/admin/index.tsx index 0f8004e595..13e4d0cadf 100644 --- a/app/soapbox/features/admin/index.tsx +++ b/app/soapbox/features/admin/index.tsx @@ -1,154 +1,37 @@ import React from 'react'; -import { defineMessages, useIntl, FormattedMessage, FormattedNumber } from 'react-intl'; -import { Link } from 'react-router-dom'; +import { defineMessages, useIntl } from 'react-intl'; +import { Switch, Route } from 'react-router-dom'; -import { getSubscribersCsv, getUnsubscribersCsv, getCombinedCsv } from 'soapbox/actions/email_list'; -import { Text } from 'soapbox/components/ui'; -import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures } from 'soapbox/hooks'; -import sourceCode from 'soapbox/utils/code'; -import { parseVersion } from 'soapbox/utils/features'; -import { isNumber } from 'soapbox/utils/numbers'; +import { useOwnAccount } from 'soapbox/hooks'; import Column from '../ui/components/column'; +import Waitlist from './awaiting_approval'; import AdminTabs from './components/admin-tabs'; -import RegistrationModePicker from './components/registration_mode_picker'; - -import type { AxiosResponse } from 'axios'; - -/** Download the file from the response instead of opening it in a tab. */ -// https://stackoverflow.com/a/53230807 -const download = (response: AxiosResponse, filename: string) => { - const url = URL.createObjectURL(new Blob([response.data])); - const link = document.createElement('a'); - link.href = url; - link.setAttribute('download', filename); - document.body.appendChild(link); - link.click(); - link.remove(); -}; +import Reports from './reports'; +import Dashboard from './tabs/dashboard'; const messages = defineMessages({ heading: { id: 'column.admin.dashboard', defaultMessage: 'Dashboard' }, }); -const Dashboard: React.FC = () => { +const Admin: React.FC = () => { const intl = useIntl(); - const dispatch = useAppDispatch(); - const instance = useAppSelector(state => state.instance); - const features = useFeatures(); const account = useOwnAccount(); - const handleSubscribersClick: React.MouseEventHandler = e => { - dispatch(getSubscribersCsv()).then((response) => { - download(response, 'subscribers.csv'); - }).catch(() => {}); - e.preventDefault(); - }; - - const handleUnsubscribersClick: React.MouseEventHandler = e => { - dispatch(getUnsubscribersCsv()).then((response) => { - download(response, 'unsubscribers.csv'); - }).catch(() => {}); - e.preventDefault(); - }; - - const handleCombinedClick: React.MouseEventHandler = e => { - dispatch(getCombinedCsv()).then((response) => { - download(response, 'combined.csv'); - }).catch(() => {}); - e.preventDefault(); - }; - - const v = parseVersion(instance.version); - - const userCount = instance.stats.get('user_count'); - const statusCount = instance.stats.get('status_count'); - const domainCount = instance.stats.get('domain_count'); - - const mau = instance.pleroma.getIn(['stats', 'mau']) as number | undefined; - const retention = (userCount && mau) ? Math.round(mau / userCount * 100) : null; - if (!account) return null; return ( -
- {isNumber(mau) && ( -
- - - - - - -
- )} - {isNumber(userCount) && ( - - - - - - - - - )} - {isNumber(retention) && ( -
- - {retention}% - - - - -
- )} - {isNumber(statusCount) && ( - - - - - - - - - )} - {isNumber(domainCount) && ( -
- - - - - - -
- )} -
- - {account.admin && } - -
-
-

-
    -
  • {sourceCode.displayName} {sourceCode.version}
  • -
  • {v.software} {v.version}
  • -
-
- {features.emailList && account.admin &&
-

- -
} -
+ + + + +
); }; -export default Dashboard; +export default Admin; diff --git a/app/soapbox/features/admin/reports.js b/app/soapbox/features/admin/reports.js index 3f377ba701..1c9d921cd3 100644 Binary files a/app/soapbox/features/admin/reports.js and b/app/soapbox/features/admin/reports.js differ diff --git a/app/soapbox/features/admin/tabs/dashboard.tsx b/app/soapbox/features/admin/tabs/dashboard.tsx new file mode 100644 index 0000000000..248885b21f --- /dev/null +++ b/app/soapbox/features/admin/tabs/dashboard.tsx @@ -0,0 +1,146 @@ +import React from 'react'; +import { FormattedMessage, FormattedNumber } from 'react-intl'; +import { Link } from 'react-router-dom'; + +import { getSubscribersCsv, getUnsubscribersCsv, getCombinedCsv } from 'soapbox/actions/email_list'; +import { Text } from 'soapbox/components/ui'; +import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures } from 'soapbox/hooks'; +import sourceCode from 'soapbox/utils/code'; +import { parseVersion } from 'soapbox/utils/features'; +import { isNumber } from 'soapbox/utils/numbers'; + +import RegistrationModePicker from '../components/registration_mode_picker'; + +import type { AxiosResponse } from 'axios'; + +/** Download the file from the response instead of opening it in a tab. */ +// https://stackoverflow.com/a/53230807 +const download = (response: AxiosResponse, filename: string) => { + const url = URL.createObjectURL(new Blob([response.data])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', filename); + document.body.appendChild(link); + link.click(); + link.remove(); +}; + +const Dashboard: React.FC = () => { + const dispatch = useAppDispatch(); + const instance = useAppSelector(state => state.instance); + const features = useFeatures(); + const account = useOwnAccount(); + + const handleSubscribersClick: React.MouseEventHandler = e => { + dispatch(getSubscribersCsv()).then((response) => { + download(response, 'subscribers.csv'); + }).catch(() => {}); + e.preventDefault(); + }; + + const handleUnsubscribersClick: React.MouseEventHandler = e => { + dispatch(getUnsubscribersCsv()).then((response) => { + download(response, 'unsubscribers.csv'); + }).catch(() => {}); + e.preventDefault(); + }; + + const handleCombinedClick: React.MouseEventHandler = e => { + dispatch(getCombinedCsv()).then((response) => { + download(response, 'combined.csv'); + }).catch(() => {}); + e.preventDefault(); + }; + + const v = parseVersion(instance.version); + + const userCount = instance.stats.get('user_count'); + const statusCount = instance.stats.get('status_count'); + const domainCount = instance.stats.get('domain_count'); + + const mau = instance.pleroma.getIn(['stats', 'mau']) as number | undefined; + const retention = (userCount && mau) ? Math.round(mau / userCount * 100) : null; + + if (!account) return null; + + return ( + <> +
+ {isNumber(mau) && ( +
+ + + + + + +
+ )} + {isNumber(userCount) && ( + + + + + + + + + )} + {isNumber(retention) && ( +
+ + {retention}% + + + + +
+ )} + {isNumber(statusCount) && ( + + + + + + + + + )} + {isNumber(domainCount) && ( +
+ + + + + + +
+ )} +
+ + {account.admin && } + +
+
+

+
    +
  • {sourceCode.displayName} {sourceCode.version}
  • +
  • {v.software} {v.version}
  • +
+
+ {features.emailList && account.admin && ( +
+

+ +
+ )} +
+ + ); +}; + +export default Dashboard; diff --git a/app/soapbox/features/ui/index.tsx b/app/soapbox/features/ui/index.tsx index 25c060bfeb..9217a77d78 100644 --- a/app/soapbox/features/ui/index.tsx +++ b/app/soapbox/features/ui/index.tsx @@ -302,8 +302,8 @@ const SwitchingColumnsArea: React.FC = ({ children }) => { - - + +