diff --git a/src/components/TopicStats.jsx b/src/components/TopicStats.jsx
new file mode 100644
index 00000000..513a9cea
--- /dev/null
+++ b/src/components/TopicStats.jsx
@@ -0,0 +1,108 @@
+/* eslint react/prop-types: 0 */
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { useSelector } from 'react-redux';
+
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import { Icon, OverlayTrigger, Tooltip } from '@edx/paragon';
+import { HelpOutline, PostOutline, Report } from '@edx/paragon/icons';
+
+import {
+ selectUserHasModerationPrivileges,
+ selectUserIsGroupTa,
+} from '../discussions/data/selectors';
+import messages from '../discussions/in-context-topics/messages';
+
+function TopicStats({
+ threadCounts,
+ activeFlags,
+ inactiveFlags,
+ intl,
+}) {
+ const userHasModerationPrivileges = useSelector(selectUserHasModerationPrivileges);
+ const userIsGroupTa = useSelector(selectUserIsGroupTa);
+ const canSeeReportedStats = (activeFlags || inactiveFlags) && (userHasModerationPrivileges || userIsGroupTa);
+ return (
+
+
+
+ {intl.formatMessage(messages.discussions, {
+ count: threadCounts?.discussion || 0,
+ })}
+
+
+ )}
+ >
+
+
+ {threadCounts?.discussion || 0}
+
+
+
+
+ {intl.formatMessage(messages.questions, {
+ count: threadCounts?.question || 0,
+ })}
+
+
+ )}
+ >
+
+
+ {threadCounts?.question || 0}
+
+
+ {Boolean(canSeeReportedStats) && (
+
+
+ {Boolean(activeFlags) && (
+
+ {intl.formatMessage(messages.reported, { reported: activeFlags })}
+
+ )}
+ {Boolean(inactiveFlags) && (
+
+ {intl.formatMessage(messages.previouslyReported, { previouslyReported: inactiveFlags })}
+
+ )}
+
+
+ )}
+ >
+
+
+ {activeFlags}{Boolean(inactiveFlags) && `/${inactiveFlags}`}
+
+
+ )}
+
+ );
+}
+
+TopicStats.propTypes = {
+ threadCounts: PropTypes.shape({
+ discussions: PropTypes.number,
+ questions: PropTypes.number,
+ }),
+ activeFlags: PropTypes.number,
+ inactiveFlags: PropTypes.number,
+ intl: intlShape.isRequired,
+};
+
+TopicStats.defaultProps = {
+ threadCounts: {
+ discussions: 0,
+ questions: 0,
+ },
+ activeFlags: null,
+ inactiveFlags: null,
+};
+
+export default injectIntl(TopicStats);
diff --git a/src/components/index.js b/src/components/index.js
index 182f3620..10908904 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,3 +1,4 @@
export { default as PostActionsBar } from '../discussions/posts/post-actions-bar/PostActionsBar';
export { default as Search } from './Search';
export { default as TinyMCEEditor } from './TinyMCEEditor';
+export { default as TopicStats } from './TopicStats';
diff --git a/src/discussions/in-context-topics/topic/SectionBaseGroup.jsx b/src/discussions/in-context-topics/topic/SectionBaseGroup.jsx
index ae9fc61c..8e74c27f 100644
--- a/src/discussions/in-context-topics/topic/SectionBaseGroup.jsx
+++ b/src/discussions/in-context-topics/topic/SectionBaseGroup.jsx
@@ -7,6 +7,7 @@ import { Link } from 'react-router-dom';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import TopicStats from '../../../components/TopicStats';
import { Routes } from '../../../data/constants';
import { discussionsPath } from '../../utils';
import messages from '../messages';
@@ -55,6 +56,7 @@ function SectionBaseGroup({
{subsection?.displayName || intl.formatMessage(messages.unnamedSubsection)}
+
diff --git a/src/discussions/in-context-topics/topic/Topic.jsx b/src/discussions/in-context-topics/topic/Topic.jsx
index d316ebfc..927b1494 100644
--- a/src/discussions/in-context-topics/topic/Topic.jsx
+++ b/src/discussions/in-context-topics/topic/Topic.jsx
@@ -11,6 +11,7 @@ import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Icon, OverlayTrigger, Tooltip } from '@edx/paragon';
import { HelpOutline, PostOutline, Report } from '@edx/paragon/icons';
+import TopicStats from '../../../components/TopicStats';
import { Routes } from '../../../data/constants';
import { selectUserHasModerationPrivileges, selectUserIsGroupTa } from '../../data/selectors';
import { discussionsPath } from '../../utils';
@@ -53,65 +54,11 @@ function Topic({
{topic?.name || topic?.displayName || intl.formatMessage(messages.unnamedTopicSubCategories)}
-
-
-
- {intl.formatMessage(messages.discussions, {
- count: topic.threadCounts?.discussion || 0,
- })}
-
-
- )}
- >
-
-
- {topic.threadCounts?.discussion || 0}
-
-
-
-
- {intl.formatMessage(messages.questions, {
- count: topic.threadCounts?.question || 0,
- })}
-
-
- )}
- >
-
-
- {topic.threadCounts?.question || 0}
-
-
- {Boolean(canSeeReportedStats) && (
-
-
- {Boolean(activeFlags) && (
-
- {intl.formatMessage(messages.reported, { reported: activeFlags })}
-
- )}
- {Boolean(inactiveFlags) && (
-
- {intl.formatMessage(messages.previouslyReported, { previouslyReported: inactiveFlags })}
-
- )}
-
-
- )}
- >
-
-
- {activeFlags}{Boolean(inactiveFlags) && `/${inactiveFlags}`}
-
-
- )}
-
+