import React from 'react'; import { FormattedMessage } from 'react-intl'; import { useHistory } from 'react-router-dom'; import { getSubscribersCsv, getUnsubscribersCsv, getCombinedCsv } from 'soapbox/actions/email-list'; import List, { ListItem } from 'soapbox/components/list'; import { CardTitle, Icon, IconButton, Stack } from 'soapbox/components/ui'; import { useAppDispatch, useOwnAccount, useFeatures, useInstance } from 'soapbox/hooks'; import sourceCode from 'soapbox/utils/code'; import { download } from 'soapbox/utils/download'; import { parseVersion } from 'soapbox/utils/features'; import { DashCounter, DashCounters } from '../components/dashcounter'; import RegistrationModePicker from '../components/registration-mode-picker'; const Dashboard: React.FC = () => { const dispatch = useAppDispatch(); const history = useHistory(); const instance = useInstance(); const features = useFeatures(); const account = useOwnAccount(); const handleSubscribersClick: React.MouseEventHandler = e => { dispatch(getSubscribersCsv()).then(({ data }) => { download(data, 'subscribers.csv'); }).catch(() => {}); e.preventDefault(); }; const handleUnsubscribersClick: React.MouseEventHandler = e => { dispatch(getUnsubscribersCsv()).then(({ data }) => { download(data, 'unsubscribers.csv'); }).catch(() => {}); e.preventDefault(); }; const handleCombinedClick: React.MouseEventHandler = e => { dispatch(getCombinedCsv()).then(({ data }) => { download(data, 'combined.csv'); }).catch(() => {}); e.preventDefault(); }; const navigateToSoapboxConfig = () => history.push('/soapbox/config'); const navigateToModerationLog = () => history.push('/soapbox/admin/log'); 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) : undefined; if (!account) return null; return ( <Stack space={6} className='mt-4'> <DashCounters> <DashCounter count={mau} label={<FormattedMessage id='admin.dashcounters.mau_label' defaultMessage='monthly active users' />} /> <DashCounter to='/soapbox/admin/users' count={userCount} label={<FormattedMessage id='admin.dashcounters.user_count_label' defaultMessage='total users' />} /> <DashCounter count={retention} label={<FormattedMessage id='admin.dashcounters.retention_label' defaultMessage='user retention' />} percent /> <DashCounter to='/timeline/local' count={statusCount} label={<FormattedMessage id='admin.dashcounters.status_count_label' defaultMessage='posts' />} /> <DashCounter count={domainCount} label={<FormattedMessage id='admin.dashcounters.domain_count_label' defaultMessage='peers' />} /> </DashCounters> <List> {account.admin && ( <ListItem onClick={navigateToSoapboxConfig} label={<FormattedMessage id='navigation_bar.soapbox_config' defaultMessage='Soapbox config' />} /> )} <ListItem onClick={navigateToModerationLog} label={<FormattedMessage id='column.admin.moderation_log' defaultMessage='Moderation Log' />} /> </List> {account.admin && ( <> <CardTitle title={<FormattedMessage id='admin.dashboard.registration_mode_label' defaultMessage='Registrations' />} /> <RegistrationModePicker /> </> )} <CardTitle title={<FormattedMessage id='admin.dashwidgets.software_header' defaultMessage='Software' />} /> <List> <ListItem label={<FormattedMessage id='admin.software.frontend' defaultMessage='Frontend' />}> <a href={sourceCode.ref ? `${sourceCode.url}/tree/${sourceCode.ref}` : sourceCode.url} className='flex space-x-1 items-center truncate' target='_blank' > <span>{sourceCode.displayName} {sourceCode.version}</span> <Icon className='w-4 h-4' src={require('@tabler/icons/external-link.svg')} /> </a> </ListItem> <ListItem label={<FormattedMessage id='admin.software.backend' defaultMessage='Backend' />}> <span>{v.software + (v.build ? `+${v.build}` : '')} {v.version}</span> </ListItem> </List> {(features.emailList && account.admin) && ( <> <CardTitle title={<FormattedMessage id='admin.dashwidgets.email_list_header' defaultMessage='Email list' />} /> <List> <ListItem label='subscribers.csv'> <IconButton src={require('@tabler/icons/download.svg')} onClick={handleSubscribersClick} iconClassName='w-5 h-5' /> </ListItem> <ListItem label='unsubscribers.csv'> <IconButton src={require('@tabler/icons/download.svg')} onClick={handleUnsubscribersClick} iconClassName='w-5 h-5' /> </ListItem> <ListItem label='combined.csv'> <IconButton src={require('@tabler/icons/download.svg')} onClick={handleCombinedClick} iconClassName='w-5 h-5' /> </ListItem> </List> </> )} </Stack> ); }; export default Dashboard;