From 4aa3309e617b6a47376e03a4938db925e8f90eab Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 23 Feb 2026 00:42:11 +0000 Subject: [PATCH] Show manager username instead of team name on draft board Both the read-only draft board and the active draft room now display the manager's username (falling back to displayName if no username is set, and to team name if the team is unassigned) in the column headers of the draft grid. https://claude.ai/code/session_01C97GauJaAB83NVWxdpNVh1 --- app/components/DraftGrid.tsx | 4 ++- app/components/draft/DraftGridSection.tsx | 4 ++- .../$leagueId.draft-board.$seasonId.tsx | 28 ++++++++++++++++++- .../leagues/$leagueId.draft.$seasonId.tsx | 27 ++++++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/app/components/DraftGrid.tsx b/app/components/DraftGrid.tsx index bf98a3c..d0acfd8 100644 --- a/app/components/DraftGrid.tsx +++ b/app/components/DraftGrid.tsx @@ -25,6 +25,7 @@ interface DraftGridProps { onForceManualPick?: (pickNumber: number, teamId: string) => void; autodraftStatus?: Record; connectedTeams?: Set; + ownerMap?: Record; } export function DraftGrid({ @@ -39,6 +40,7 @@ export function DraftGrid({ onForceManualPick, autodraftStatus = {}, connectedTeams = new Set(), + ownerMap = {}, }: DraftGridProps) { const totalTeams = draftSlots.length; @@ -58,7 +60,7 @@ export function DraftGrid({
- {slot.team.name} + {ownerMap[slot.team.id] || slot.team.name}
{teamTimers && formatTime && (
void; onReplacePick?: (pickNumber: number, teamId: string) => void; onRollbackToPick?: (pickNumber: number) => void; + ownerMap?: Record; } export function DraftGridSection({ @@ -57,6 +58,7 @@ export function DraftGridSection({ onForceManualPickOpen, onReplacePick, onRollbackToPick, + ownerMap = {}, }: DraftGridSectionProps) { const currentTeamId = useMemo( () => draftGrid.flat().find((c) => c.pickNumber === currentPick)?.teamId ?? null, @@ -86,7 +88,7 @@ export function DraftGridSection({ : "" }`} > - {slot.team.name} + {ownerMap[slot.team.id] || slot.team.name}
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)!; + } + } + return { season, draftSlots, draftPicks, + ownerMap, }; } export default function DraftBoard() { - const { season, draftSlots, draftPicks: initialPicks } = useLoaderData(); + const { season, draftSlots, draftPicks: initialPicks, ownerMap } = useLoaderData(); const { isConnected, on, off } = useDraftSocket(season.id); const [picks, setPicks] = useState(initialPicks); const [currentPick, setCurrentPick] = useState(season.currentPickNumber || 1); @@ -186,6 +211,7 @@ export default function DraftBoard() { draftSlots={draftSlots} draftGrid={draftGrid} currentPick={currentPick} + ownerMap={ownerMap} />
diff --git a/app/routes/leagues/$leagueId.draft.$seasonId.tsx b/app/routes/leagues/$leagueId.draft.$seasonId.tsx index 1c75430..3c9b99c 100644 --- a/app/routes/leagues/$leagueId.draft.$seasonId.tsx +++ b/app/routes/leagues/$leagueId.draft.$seasonId.tsx @@ -11,6 +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 { DraftSidebar } from "~/components/DraftSidebar"; import { TeamsDraftedGrid } from "~/components/draft/TeamsDraftedGrid"; import { QueueSection } from "~/components/draft/QueueSection"; @@ -166,6 +167,29 @@ 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)!; + } + } + return { season, draftSlots, @@ -179,6 +203,7 @@ export async function loader(args: any) { isCommissioner: !!isCommissioner, currentUserId: userId, numFlexPicks: Math.max(0, season.draftRounds - seasonSports.length), + ownerMap, }; } @@ -196,6 +221,7 @@ export default function DraftRoom() { isCommissioner, currentUserId, numFlexPicks, + ownerMap, } = useLoaderData(); const { revalidate } = useRevalidator(); const { isConnected, connectionError, isReconnecting, on, off } = useDraftSocket(season.id, userTeam?.id); @@ -1224,6 +1250,7 @@ export default function DraftRoom() { autodraftStatus={autodraftStatus} connectedTeams={connectedTeams} isCommissioner={isCommissioner} + ownerMap={ownerMap} onAdjustTimeBankOpen={isCommissioner ? handleAdjustTimeBankOpen : undefined} onForceAutopick={handleForceAutopick} onForceManualPickOpen={(pickNumber, teamId) => {