From 7d7b2598c5699de8d6bd834d3b80b7bfb5021663 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 23 Feb 2026 00:53:58 +0000 Subject: [PATCH] Address code review: extract ownerMap helper, fix TeamsDraftedGrid - Extract ownerMap building into app/lib/owner-map.ts to eliminate duplication across the two loaders - Guard against null username AND displayName so the map only contains real string values - Apply username display to TeamsDraftedGrid (the "Teams" tab in the active draft room), which was missed in the initial change https://claude.ai/code/session_01C97GauJaAB83NVWxdpNVh1 --- app/components/draft/TeamsDraftedGrid.tsx | 4 +- app/lib/owner-map.ts | 39 +++++++++++++++++++ .../$leagueId.draft-board.$seasonId.tsx | 25 +----------- .../leagues/$leagueId.draft.$seasonId.tsx | 26 ++----------- 4 files changed, 47 insertions(+), 47 deletions(-) create mode 100644 app/lib/owner-map.ts diff --git a/app/components/draft/TeamsDraftedGrid.tsx b/app/components/draft/TeamsDraftedGrid.tsx index c699569..cde08c2 100644 --- a/app/components/draft/TeamsDraftedGrid.tsx +++ b/app/components/draft/TeamsDraftedGrid.tsx @@ -9,6 +9,7 @@ interface TeamsDraftedGridProps { name: string; }; }>; + ownerMap?: Record; picks: Array<{ id: string; team: { @@ -38,6 +39,7 @@ export function TeamsDraftedGrid({ picks, sports, season, + ownerMap = {}, }: TeamsDraftedGridProps) { // Calculate picks by team and sport const picksByTeamAndSport = useMemo(() => { @@ -97,7 +99,7 @@ export function TeamsDraftedGrid({ >
- {slot.team.name} + {ownerMap[slot.team.id] || slot.team.name}
{flexUsed} of {season.numFlexPicks} flex diff --git a/app/lib/owner-map.ts b/app/lib/owner-map.ts new file mode 100644 index 0000000..70e118e --- /dev/null +++ b/app/lib/owner-map.ts @@ -0,0 +1,39 @@ +import { findUserByClerkId } from "~/models/user"; + +/** + * Builds a map of teamId -> manager username (or displayName fallback). + * Accepts any array of objects that have a `team` with `id` and `ownerId`. + */ +export async function buildOwnerMap( + slots: Array<{ team: { id: string; ownerId: string | null } }> +): Promise> { + const ownerIds = slots + .map((s) => s.team.ownerId) + .filter((id): id is string => id !== null); + const uniqueOwnerIds = [...new Set(ownerIds)]; + + const ownerEntries = await Promise.all( + uniqueOwnerIds.map(async (ownerId) => { + const user = await findUserByClerkId(ownerId); + const name = user?.username || user?.displayName || null; + return name ? { ownerId, name } : null; + }) + ); + + const ownerByClerkId = new Map( + ownerEntries + .filter((e): e is NonNullable => e !== null) + .map((e) => [e.ownerId, e.name]) + ); + + const ownerMap: Record = {}; + for (const slot of slots) { + const name = slot.team.ownerId + ? ownerByClerkId.get(slot.team.ownerId) + : undefined; + if (name) { + ownerMap[slot.team.id] = name; + } + } + return ownerMap; +} diff --git a/app/routes/leagues/$leagueId.draft-board.$seasonId.tsx b/app/routes/leagues/$leagueId.draft-board.$seasonId.tsx index e858d09..2fa61e2 100644 --- a/app/routes/leagues/$leagueId.draft-board.$seasonId.tsx +++ b/app/routes/leagues/$leagueId.draft-board.$seasonId.tsx @@ -6,7 +6,7 @@ import * as schema from "~/database/schema"; import { DraftGrid } from "~/components/DraftGrid"; import { useDraftSocket } from "~/hooks/useDraftSocket"; import { useState, useEffect } from "react"; -import { findUserByClerkId } from "~/models/user"; +import { buildOwnerMap } from "~/lib/owner-map"; export async function loader(args: any) { const { params } = args; @@ -103,28 +103,7 @@ export async function loader(args: any) { .where(eq(schema.draftPicks.seasonId, seasonId)) .orderBy(asc(schema.draftPicks.pickNumber)); - // Build ownerMap: teamId -> username/displayName - const ownerIds = draftSlots - .map((s) => s.team.ownerId) - .filter((id): id is string => id !== null); - const uniqueOwnerIds = [...new Set(ownerIds)]; - const ownerEntries = await Promise.all( - uniqueOwnerIds.map(async (ownerId) => { - const user = await findUserByClerkId(ownerId); - return user ? { ownerId, name: user.username || user.displayName } : null; - }) - ); - const ownerByClerkId = new Map( - ownerEntries - .filter((e): e is NonNullable => e !== null) - .map((e) => [e.ownerId, e.name]) - ); - const ownerMap: Record = {}; - for (const slot of draftSlots) { - if (slot.team.ownerId && ownerByClerkId.has(slot.team.ownerId)) { - ownerMap[slot.team.id] = ownerByClerkId.get(slot.team.ownerId)!; - } - } + const ownerMap = await buildOwnerMap(draftSlots); return { season, diff --git a/app/routes/leagues/$leagueId.draft.$seasonId.tsx b/app/routes/leagues/$leagueId.draft.$seasonId.tsx index 3c9b99c..db207e2 100644 --- a/app/routes/leagues/$leagueId.draft.$seasonId.tsx +++ b/app/routes/leagues/$leagueId.draft.$seasonId.tsx @@ -11,7 +11,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "~/components/ui/dialog"; import { getAuth } from "@clerk/react-router/server"; import { getTeamQueue } from "~/models/draft-queue"; -import { findUserByClerkId } from "~/models/user"; +import { buildOwnerMap } from "~/lib/owner-map"; import { DraftSidebar } from "~/components/DraftSidebar"; import { TeamsDraftedGrid } from "~/components/draft/TeamsDraftedGrid"; import { QueueSection } from "~/components/draft/QueueSection"; @@ -167,28 +167,7 @@ export async function loader(args: any) { ? (autodraftSettings.find((s) => s.teamId === userTeam.id) ?? null) : null; - // Build ownerMap: teamId -> username/displayName - const ownerIds = draftSlots - .map((s) => s.team.ownerId) - .filter((id): id is string => id !== null); - const uniqueOwnerIds = [...new Set(ownerIds)]; - const ownerEntries = await Promise.all( - uniqueOwnerIds.map(async (ownerId) => { - const user = await findUserByClerkId(ownerId); - return user ? { ownerId, name: user.username || user.displayName } : null; - }) - ); - const ownerByClerkId = new Map( - ownerEntries - .filter((e): e is NonNullable => e !== null) - .map((e) => [e.ownerId, e.name]) - ); - const ownerMap: Record = {}; - for (const slot of draftSlots) { - if (slot.team.ownerId && ownerByClerkId.has(slot.team.ownerId)) { - ownerMap[slot.team.id] = ownerByClerkId.get(slot.team.ownerId)!; - } - } + const ownerMap = await buildOwnerMap(draftSlots); return { season, @@ -1271,6 +1250,7 @@ export default function DraftRoom() { picks={picks} sports={seasonSportsData} season={{ numFlexPicks }} + ownerMap={ownerMap} />