From 14b9a15a24c6e85521fe26f26c1185a08e9e914d Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 16 May 2026 01:28:26 +0000 Subject: [PATCH] Rename queue page to Set Pre-Draft Queue, remove VORP, fix re-add race condition - Rename page title, h1, button, error message, and tests from "Pre-Draft Rankings" to "Set Pre-Draft Queue" - Remove VORP values and "Sorted by VORP" labels from the all-players list - Fix bug where removing a player then immediately re-adding would fail with "already in queue": track in-flight removes in a ref and guard handleAdd against firing while a remove is still in-flight https://claude.ai/code/session_01TGAV9A2c72PNkL1ffY7Xeq --- app/components/league/DraftInfoCard.tsx | 2 +- .../$leagueId.draft-queue.$seasonId.tsx | 27 +++++++++---------- .../__tests__/draft-queue-access.test.ts | 4 +-- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/app/components/league/DraftInfoCard.tsx b/app/components/league/DraftInfoCard.tsx index e2b7d5b..a7d3bab 100644 --- a/app/components/league/DraftInfoCard.tsx +++ b/app/components/league/DraftInfoCard.tsx @@ -121,7 +121,7 @@ function DraftInfoCardVariant({ ) : queueBuilderHref ? ( ) : null} diff --git a/app/routes/leagues/$leagueId.draft-queue.$seasonId.tsx b/app/routes/leagues/$leagueId.draft-queue.$seasonId.tsx index 2899cc6..896222f 100644 --- a/app/routes/leagues/$leagueId.draft-queue.$seasonId.tsx +++ b/app/routes/leagues/$leagueId.draft-queue.$seasonId.tsx @@ -13,7 +13,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs"; import type { Route } from "./+types/$leagueId.draft-queue.$seasonId"; export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors { - return [{ title: `Pre-Draft Rankings — ${data?.season?.league?.name ?? "League"} - Brackt` }]; + return [{ title: `Set Pre-Draft Queue — ${data?.season?.league?.name ?? "League"} - Brackt` }]; } export async function loader(args: Route.LoaderArgs) { @@ -41,7 +41,7 @@ export async function loader(args: Route.LoaderArgs) { } if (!userId) { - throw new Response("You must be logged in to set pre-draft rankings", { status: 401 }); + throw new Response("You must be logged in to set pre-draft queue", { status: 401 }); } const userTeam = season.teams.find((t) => t.ownerId === userId); @@ -79,6 +79,8 @@ export default function PreDraftRankings() { // Always-current ref so reorder callback stays stable (no localQueue dependency) const queueRef = useRef(localQueue); + // Track in-flight removes to prevent add racing ahead of a pending remove + const pendingRemovesRef = useRef(new Set()); useEffect(() => { queueRef.current = localQueue; }, [localQueue]); @@ -90,7 +92,7 @@ export default function PreDraftRankings() { const handleAdd = useCallback( async (participantId: string) => { - if (queuedParticipantIds.has(participantId)) return; + if (queuedParticipantIds.has(participantId) || pendingRemovesRef.current.has(participantId)) return; const tempId = `temp-${Date.now()}-${participantId}`; setLocalQueue((prev) => [...prev, { id: tempId, participantId }]); @@ -118,7 +120,11 @@ export default function PreDraftRankings() { const handleRemove = useCallback( async (queueId: string) => { - setLocalQueue((prev) => prev.filter((item) => item.id !== queueId)); + const item = queueRef.current.find((q) => q.id === queueId); + const participantId = item?.participantId; + + setLocalQueue((prev) => prev.filter((q) => q.id !== queueId)); + if (participantId) pendingRemovesRef.current.add(participantId); const formData = new FormData(); formData.append("queueId", queueId); @@ -134,6 +140,8 @@ export default function PreDraftRankings() { } catch { toast.error("Network error — failed to remove from rankings"); revalidate(); + } finally { + if (participantId) pendingRemovesRef.current.delete(participantId); } }, [userTeam.id, revalidate] @@ -194,11 +202,6 @@ export default function PreDraftRankings() {

{p.name}

{p.sport.name}

- {p.vorpValue !== null && p.vorpValue !== undefined && ( - - {Number(p.vorpValue).toFixed(1)} - - )} {inQueue ? (