From ee443158b643a10d33e2221e42b59d796b24db77 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 17 Dec 2022 13:49:45 -0600 Subject: [PATCH] Admin: refactor counters with DashCounter component --- .../features/admin/components/dashcounter.tsx | 57 +++++++++++++ app/soapbox/features/admin/tabs/dashboard.tsx | 85 ++++++------------- app/styles/components/admin.scss | 8 -- 3 files changed, 85 insertions(+), 65 deletions(-) create mode 100644 app/soapbox/features/admin/components/dashcounter.tsx diff --git a/app/soapbox/features/admin/components/dashcounter.tsx b/app/soapbox/features/admin/components/dashcounter.tsx new file mode 100644 index 000000000..1ad43b5e0 --- /dev/null +++ b/app/soapbox/features/admin/components/dashcounter.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { FormattedNumber } from 'react-intl'; +import { Link } from 'react-router-dom'; + +import { Text } from 'soapbox/components/ui'; +import { isNumber } from 'soapbox/utils/numbers'; + +interface IDashCounter { + count: number | undefined + label: React.ReactNode + to?: string + percent?: boolean +} + +/** Displays a (potentially clickable) dashboard statistic. */ +const DashCounter: React.FC = ({ count, label, to = '#', percent = false }) => { + + if (!isNumber(count)) { + return null; + } + + return ( + + + + + + {label} + + + ); +}; + +interface IDashCounters { + children: React.ReactNode +} + +/** Wrapper container for dash counters. */ +const DashCounters: React.FC = ({ children }) => { + return ( +
+ {children} +
+ ); +}; + +export { + DashCounter, + DashCounters, +}; \ No newline at end of file diff --git a/app/soapbox/features/admin/tabs/dashboard.tsx b/app/soapbox/features/admin/tabs/dashboard.tsx index a43bd8d83..6bd77bad2 100644 --- a/app/soapbox/features/admin/tabs/dashboard.tsx +++ b/app/soapbox/features/admin/tabs/dashboard.tsx @@ -1,15 +1,13 @@ import React from 'react'; -import { FormattedMessage, FormattedNumber } from 'react-intl'; -import { Link } from 'react-router-dom'; +import { FormattedMessage } from 'react-intl'; import { getSubscribersCsv, getUnsubscribersCsv, getCombinedCsv } from 'soapbox/actions/email-list'; -import { Text } 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 { isNumber } from 'soapbox/utils/numbers'; +import { DashCounter, DashCounters } from '../components/dashcounter'; import RegistrationModePicker from '../components/registration-mode-picker'; const Dashboard: React.FC = () => { @@ -46,64 +44,37 @@ const Dashboard: React.FC = () => { 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; + const retention = (userCount && mau) ? Math.round(mau / userCount * 100) : undefined; if (!account) return null; return ( <> -
- {isNumber(mau) && ( -
- - - - - - -
- )} - {isNumber(userCount) && ( - - - - - - - - - )} - {isNumber(retention) && ( -
- - {retention}% - - - - -
- )} - {isNumber(statusCount) && ( - - - - - - - - - )} - {isNumber(domainCount) && ( -
- - - - - - -
- )} -
+ + } + /> + } + /> + } + percent + /> + } + /> + } + /> + {account.admin && } diff --git a/app/styles/components/admin.scss b/app/styles/components/admin.scss index bba02ffe8..5749909b4 100644 --- a/app/styles/components/admin.scss +++ b/app/styles/components/admin.scss @@ -1,11 +1,3 @@ -.dashcounters { - @apply grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2 mb-4; -} - -.dashcounter { - @apply bg-gray-200 dark:bg-gray-800 p-4 rounded flex flex-col items-center space-y-2 hover:-translate-y-1 transition-transform cursor-pointer; -} - .dashwidgets { display: flex; flex-wrap: wrap;