@@ -92,27 +92,60 @@ export default function AdminDashboard() {
<>
{/* Needs attention — the only stats that earn individual weight and
real color; color means "act on this", not "posts are orange". */}
-
-
-
+
- {/* Everything else — a flat overview, not a wall of identical cards */}
-
-
Overview
-
-
-
-
-
-
-
-
-
-
-
-
-
+ {/* Everything else, grouped by what kind of number it is — activity
+ (growth/usage), violations (moderation risk), info (context only).
+ Category color is a legend, not a wash: only violation values
+ that are actually > 0 pick up the color, same "act on this"
+ logic as AttentionStat above. */}
+
+
+ Overview
+
+
+
+
+
+
+
+
+
>
)}
@@ -227,8 +260,8 @@ function AttentionStat({
const needsAttention = value > 0;
return (
@@ -242,12 +275,51 @@ function AttentionStat({
);
}
-/** Everything else — a plain label/value pair, no per-item card chrome. */
-function OverviewStat({ label, value }: { label: string; value: number }) {
+const STAT_GROUP_COLORS = {
+ emerald: { text: "text-emerald-400", bg: "bg-emerald-500/5", ring: "ring-emerald-500/15" },
+ rose: { text: "text-rose-400", bg: "bg-rose-500/5", ring: "ring-rose-500/15" },
+ sky: { text: "text-sky-400", bg: "bg-sky-500/5", ring: "ring-sky-500/15" },
+} as const;
+
+/**
+ * One labeled, color-identified slice of the Overview card — Activity,
+ * Violations, or Info. The color lives on the group's icon/label (a legend)
+ * and, when `emphasizeNonZero` is set, on individual values that are actually
+ * non-zero — never as a flat wash across numbers that don't mean anything yet.
+ */
+function StatGroup({
+ icon: Icon,
+ label,
+ color,
+ items,
+ emphasizeNonZero = false,
+}: {
+ icon: React.ElementType;
+ label: string;
+ color: keyof typeof STAT_GROUP_COLORS;
+ items: { label: string; value: number }[];
+ emphasizeNonZero?: boolean;
+}) {
+ const c = STAT_GROUP_COLORS[color];
return (
-
-
{label}
-
{value.toLocaleString()}
+
+
+
+ {label}
+
+
+ {items.map((item) => {
+ const flagged = emphasizeNonZero && item.value > 0;
+ return (
+
+
- {item.label}
+ -
+ {item.value.toLocaleString()}
+
+
+ );
+ })}
+
);
}