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
This commit is contained in:
parent
4aa3309e61
commit
7d7b2598c5
4 changed files with 47 additions and 47 deletions
|
|
@ -9,6 +9,7 @@ interface TeamsDraftedGridProps {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
|
ownerMap?: Record<string, string>;
|
||||||
picks: Array<{
|
picks: Array<{
|
||||||
id: string;
|
id: string;
|
||||||
team: {
|
team: {
|
||||||
|
|
@ -38,6 +39,7 @@ export function TeamsDraftedGrid({
|
||||||
picks,
|
picks,
|
||||||
sports,
|
sports,
|
||||||
season,
|
season,
|
||||||
|
ownerMap = {},
|
||||||
}: TeamsDraftedGridProps) {
|
}: TeamsDraftedGridProps) {
|
||||||
// Calculate picks by team and sport
|
// Calculate picks by team and sport
|
||||||
const picksByTeamAndSport = useMemo(() => {
|
const picksByTeamAndSport = useMemo(() => {
|
||||||
|
|
@ -97,7 +99,7 @@ export function TeamsDraftedGrid({
|
||||||
>
|
>
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<div className="font-semibold text-sm">
|
<div className="font-semibold text-sm">
|
||||||
{slot.team.name}
|
{ownerMap[slot.team.id] || slot.team.name}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-muted-foreground font-normal">
|
<div className="text-xs text-muted-foreground font-normal">
|
||||||
{flexUsed} of {season.numFlexPicks} flex
|
{flexUsed} of {season.numFlexPicks} flex
|
||||||
|
|
|
||||||
39
app/lib/owner-map.ts
Normal file
39
app/lib/owner-map.ts
Normal file
|
|
@ -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<Record<string, string>> {
|
||||||
|
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<typeof e> => e !== null)
|
||||||
|
.map((e) => [e.ownerId, e.name])
|
||||||
|
);
|
||||||
|
|
||||||
|
const ownerMap: Record<string, string> = {};
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@ import * as schema from "~/database/schema";
|
||||||
import { DraftGrid } from "~/components/DraftGrid";
|
import { DraftGrid } from "~/components/DraftGrid";
|
||||||
import { useDraftSocket } from "~/hooks/useDraftSocket";
|
import { useDraftSocket } from "~/hooks/useDraftSocket";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { findUserByClerkId } from "~/models/user";
|
import { buildOwnerMap } from "~/lib/owner-map";
|
||||||
|
|
||||||
export async function loader(args: any) {
|
export async function loader(args: any) {
|
||||||
const { params } = args;
|
const { params } = args;
|
||||||
|
|
@ -103,28 +103,7 @@ export async function loader(args: any) {
|
||||||
.where(eq(schema.draftPicks.seasonId, seasonId))
|
.where(eq(schema.draftPicks.seasonId, seasonId))
|
||||||
.orderBy(asc(schema.draftPicks.pickNumber));
|
.orderBy(asc(schema.draftPicks.pickNumber));
|
||||||
|
|
||||||
// Build ownerMap: teamId -> username/displayName
|
const ownerMap = await buildOwnerMap(draftSlots);
|
||||||
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<typeof e> => e !== null)
|
|
||||||
.map((e) => [e.ownerId, e.name])
|
|
||||||
);
|
|
||||||
const ownerMap: Record<string, string> = {};
|
|
||||||
for (const slot of draftSlots) {
|
|
||||||
if (slot.team.ownerId && ownerByClerkId.has(slot.team.ownerId)) {
|
|
||||||
ownerMap[slot.team.id] = ownerByClerkId.get(slot.team.ownerId)!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
season,
|
season,
|
||||||
|
|
|
||||||
|
|
@ -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 { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "~/components/ui/dialog";
|
||||||
import { getAuth } from "@clerk/react-router/server";
|
import { getAuth } from "@clerk/react-router/server";
|
||||||
import { getTeamQueue } from "~/models/draft-queue";
|
import { getTeamQueue } from "~/models/draft-queue";
|
||||||
import { findUserByClerkId } from "~/models/user";
|
import { buildOwnerMap } from "~/lib/owner-map";
|
||||||
import { DraftSidebar } from "~/components/DraftSidebar";
|
import { DraftSidebar } from "~/components/DraftSidebar";
|
||||||
import { TeamsDraftedGrid } from "~/components/draft/TeamsDraftedGrid";
|
import { TeamsDraftedGrid } from "~/components/draft/TeamsDraftedGrid";
|
||||||
import { QueueSection } from "~/components/draft/QueueSection";
|
import { QueueSection } from "~/components/draft/QueueSection";
|
||||||
|
|
@ -167,28 +167,7 @@ export async function loader(args: any) {
|
||||||
? (autodraftSettings.find((s) => s.teamId === userTeam.id) ?? null)
|
? (autodraftSettings.find((s) => s.teamId === userTeam.id) ?? null)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
// Build ownerMap: teamId -> username/displayName
|
const ownerMap = await buildOwnerMap(draftSlots);
|
||||||
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<typeof e> => e !== null)
|
|
||||||
.map((e) => [e.ownerId, e.name])
|
|
||||||
);
|
|
||||||
const ownerMap: Record<string, string> = {};
|
|
||||||
for (const slot of draftSlots) {
|
|
||||||
if (slot.team.ownerId && ownerByClerkId.has(slot.team.ownerId)) {
|
|
||||||
ownerMap[slot.team.id] = ownerByClerkId.get(slot.team.ownerId)!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
season,
|
season,
|
||||||
|
|
@ -1271,6 +1250,7 @@ export default function DraftRoom() {
|
||||||
picks={picks}
|
picks={picks}
|
||||||
sports={seasonSportsData}
|
sports={seasonSportsData}
|
||||||
season={{ numFlexPicks }}
|
season={{ numFlexPicks }}
|
||||||
|
ownerMap={ownerMap}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue