fe(fe): enrich dashboard Top Reacted Messages

Show relative time, always-on username with channel context, and
collapse top emojis to two; add VIEW ALL toggle to reveal all 20
fetched reactions instead of the top 4.
This commit is contained in:
asepharyana committed 2026-09-23 23:56:02 +07:00
1 parent b12eb0a038
commit 8583bcdf17
1 file changed
+28 -7
@@ -13,7 +13,7 @@ import {
Zap, Zap,
} from "lucide-react"; } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { useEffect } from "react"; import { useEffect, useState } from "react";
import { useAmbient } from "@/components/ambient/ambient-context"; import { useAmbient } from "@/components/ambient/ambient-context";
import { AreaActivity, RadialGauge } from "@/components/charts"; import { AreaActivity, RadialGauge } from "@/components/charts";
import { GlassPanel } from "@/components/primitives"; import { GlassPanel } from "@/components/primitives";
@@ -28,7 +28,7 @@ import {
} from "@/components/shared"; } from "@/components/shared";
import { useActivity, useStats, useTopReactions } from "@/hooks"; import { useActivity, useStats, useTopReactions } from "@/hooks";
import { useStaggerReveal } from "@/hooks/use-gsap-animation"; import { useStaggerReveal } from "@/hooks/use-gsap-animation";
import { formatNumber } from "@/lib/format"; import { formatNumber, formatRelativeTime } from "@/lib/format";
import type { DashboardStats } from "@/lib/types"; import type { DashboardStats } from "@/lib/types";
import { staggerDelay } from "@/lib/utils"; import { staggerDelay } from "@/lib/utils";
@@ -65,6 +65,7 @@ export function DashboardView({
} = useStats(initialStats); } = useStats(initialStats);
const { data: activity } = useActivity(14, initialActivity); const { data: activity } = useActivity(14, initialActivity);
const { data: reactions } = useTopReactions(); const { data: reactions } = useTopReactions();
const [showAllReactions, setShowAllReactions] = useState(false);
const ambient = useAmbient(); const ambient = useAmbient();
const hudRef = useStaggerReveal<HTMLDivElement>(".linear-tile", { const hudRef = useStaggerReveal<HTMLDivElement>(".linear-tile", {
@@ -359,9 +360,21 @@ export function DashboardView({
<SectionHeader <SectionHeader
eyebrow="Engagement" eyebrow="Engagement"
title="Top Reacted Messages" title="Top Reacted Messages"
action={
<button
type="button"
onClick={() => setShowAllReactions((v) => !v)}
className="font-mono text-[10px] text-ink-muted transition-colors hover:text-ink"
>
{showAllReactions
? "SHOW TOP 4"
: `VIEW ALL ${reactions.length}`}
</button>
}
/> />
<div className="mt-3 space-y-2"> <div className="mt-3 space-y-2">
{reactions.slice(0, 4).map((r) => ( {(showAllReactions ? reactions : reactions.slice(0, 4)).map(
(r) => (
<div <div
key={r.message_id} key={r.message_id}
className="hud-card flex items-start justify-between gap-2 p-2.5" className="hud-card flex items-start justify-between gap-2 p-2.5"
@@ -370,12 +383,19 @@ export function DashboardView({
<span className="line-clamp-1 block text-xs text-ink-soft"> <span className="line-clamp-1 block text-xs text-ink-soft">
{r.content || "[Media/Attachment]"} {r.content || "[Media/Attachment]"}
</span> </span>
{r.username && (
<span className="mt-0.5 block font-mono text-[10px] text-ink-muted"> <span className="mt-0.5 block font-mono text-[10px] text-ink-muted">
@{r.username} @{r.username || "unknown"}
{r.channel_name && ` in #${r.channel_name}`} {r.channel_name && ` in #${r.channel_name}`}
{r.created_at != null && (
<>
{" "}
·{" "}
<span suppressHydrationWarning>
{formatRelativeTime(r.created_at)}
</span> </span>
</>
)} )}
</span>
</div> </div>
<div className="shrink-0 text-right"> <div className="shrink-0 text-right">
<span className="font-mono text-xs font-semibold text-signal"> <span className="font-mono text-xs font-semibold text-signal">
@@ -383,7 +403,7 @@ export function DashboardView({
</span> </span>
{r.top_emojis && r.top_emojis.length > 0 && ( {r.top_emojis && r.top_emojis.length > 0 && (
<div className="mt-0.5 flex gap-0.5"> <div className="mt-0.5 flex gap-0.5">
{r.top_emojis.map((e) => ( {r.top_emojis.slice(0, 2).map((e) => (
<span <span
key={e.emoji} key={e.emoji}
className="text-[10px]" className="text-[10px]"
@@ -396,7 +416,8 @@ export function DashboardView({
)} )}
</div> </div>
</div> </div>
))} ),
)}
</div> </div>
</GlassPanel> </GlassPanel>
)} )}