Skip to content

Commit a2d8cca

Browse files
fix(web): show user names instead of IDs in activity feed
- Fetch group members for all groups in activity page - Build userId-to-name lookup map and pass to ActivityFeed - labelFor() now resolves actorUserId to display name - Falls back to truncated UUID if name not found
1 parent 4c6026b commit a2d8cca

2 files changed

Lines changed: 25 additions & 5 deletions

File tree

apps/web/app/dashboard/activity/page.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ActivityDto, GroupDto } from '@fairshare/shared-types';
1+
import { ActivityDto, GroupDto, GroupMemberSummaryDto } from '@fairshare/shared-types';
22
import { DashboardLayout } from '../../../src/components/layout';
33
import { ActivityFeed } from '../../../src/components/activity/ActivityFeed';
44
import { backendFetch } from '../../../src/lib/backend';
@@ -21,6 +21,23 @@ export default async function ActivityPage() {
2121
activity = { items: [], nextCursor: null };
2222
}
2323

24+
// Build a userId → name lookup from all group members
25+
const userNameMap: Record<string, string> = {};
26+
await Promise.all(
27+
groups.map(async (group) => {
28+
try {
29+
const members = await backendFetch<GroupMemberSummaryDto[]>(`/groups/${group.id}/members`);
30+
for (const member of members) {
31+
if (!userNameMap[member.userId]) {
32+
userNameMap[member.userId] = member.name;
33+
}
34+
}
35+
} catch {
36+
// skip if members can't be fetched
37+
}
38+
}),
39+
);
40+
2441
return (
2542
<DashboardLayout>
2643
<div className="space-y-10">
@@ -32,8 +49,9 @@ export default async function ActivityPage() {
3249
</p>
3350
</div>
3451

35-
<ActivityFeed groups={groups} initialItems={activity.items} initialCursor={activity.nextCursor} />
52+
<ActivityFeed groups={groups} initialItems={activity.items} initialCursor={activity.nextCursor} userNameMap={userNameMap} />
3653
</div>
3754
</DashboardLayout>
3855
);
3956
}
57+

apps/web/src/components/activity/ActivityFeed.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ const accentByType: Record<ActivityDto['type'], string> = {
2626
member_invited: '#EC4899',
2727
};
2828

29-
function labelFor(activity: ActivityDto): string {
30-
const actor = activity.actorUserId;
29+
function labelFor(activity: ActivityDto, userNameMap: Record<string, string>): string {
30+
const actor = userNameMap[activity.actorUserId] ?? activity.actorUserId.slice(0, 8);
3131
switch (activity.type) {
3232
case 'expense_created':
3333
return `${actor} created an expense`;
@@ -69,10 +69,12 @@ export function ActivityFeed({
6969
groups,
7070
initialItems,
7171
initialCursor,
72+
userNameMap = {},
7273
}: {
7374
groups: GroupDto[];
7475
initialItems: ActivityDto[];
7576
initialCursor: number | null;
77+
userNameMap?: Record<string, string>;
7678
}) {
7779
const { toast } = useToast();
7880
const [items, setItems] = useState<ActivityDto[]>(initialItems);
@@ -188,7 +190,7 @@ export function ActivityFeed({
188190
</div>
189191
<div className="flex-1 min-w-0">
190192
<p className="text-sm font-semibold text-[var(--fs-text-primary)] truncate">
191-
{labelFor(item)}
193+
{labelFor(item, userNameMap)}
192194
</p>
193195
<div className="flex flex-wrap items-center gap-2 text-[11px] font-medium text-[var(--fs-text-muted)]">
194196
<span className="flex items-center gap-1">

0 commit comments

Comments
 (0)