* Fix draft order showing only new team when league size increased before order was set When a commissioner increased the team count on a league that had teams but no draft order set yet, the server created draft slots only for the newly-added teams. This left the DB with N+K teams but only K slots, causing the drag-and-drop list to display only the K new teams. Two fixes: 1. Server: only append new draft slots when an order was already set (existingSlots.length > 0). If no order exists yet, skip slot creation so the page correctly treats the order as unset for all teams. 2. Frontend: buildDraftOrderTeams() appends any unslotted teams after the slotted ones, so a partially-corrupt DB state still shows all teams. https://claude.ai/code/session_01M3H55gnMxRztJK9KMXqqZo * Address code review feedback on draft order bug fix - Move buildDraftOrderTeams to app/lib/draft-order.ts so it is importable and testable; remove the local copy from the settings component - Add unit tests for buildDraftOrderTeams covering the empty, full, and partial-slot cases - Tighten the draft slot guard from existingSlots.length > 0 to existingSlots.length === currentTeamCount so partial legacy states are treated the same as "order not set" - Condense the 3-line server comment to a single line per project style - Rename getNumTeamsInSeason → getNumDraftSlotsBySeasonId to reflect what the function actually counts, and update its one call site - Add tests for the server-side slot-creation guard logic https://claude.ai/code/session_01M3H55gnMxRztJK9KMXqqZo * Fix lint: move shouldAppendDraftSlots to outer scope oxlint (consistent-function-scoping) requires functions that don't close over any variables to be defined at the outer scope rather than inside a describe block. https://claude.ai/code/session_01M3H55gnMxRztJK9KMXqqZo --------- Co-authored-by: Claude <noreply@anthropic.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { useLoaderData } from "react-router";
|
|
import type { Route } from "./+types/$leagueId.standings.$seasonId.teams.$teamId";
|
|
|
|
import { TeamScoreBreakdown } from "~/components/standings/TeamScoreBreakdown";
|
|
import { getTeamScoreBreakdown, getTeamStanding } from "~/models/standings";
|
|
import { getNumDraftSlotsBySeasonId } from "~/models/draft-slot";
|
|
|
|
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
|
|
return [{ title: `${data?.breakdown?.team?.name ?? "Team"} - Brackt` }];
|
|
}
|
|
|
|
/**
|
|
* Team score breakdown page
|
|
* Shows all drafted participants with their placements and points
|
|
* Phase 4.3: Team breakdown pages
|
|
*/
|
|
export async function loader({ params }: Route.LoaderArgs) {
|
|
const { leagueId, seasonId, teamId } = params;
|
|
|
|
// Get team breakdown with all picks
|
|
const [breakdown, standing, numTeams] = await Promise.all([
|
|
getTeamScoreBreakdown(teamId, seasonId),
|
|
getTeamStanding(teamId, seasonId),
|
|
getNumDraftSlotsBySeasonId(seasonId),
|
|
]);
|
|
|
|
if (!breakdown) {
|
|
throw new Response("Team not found", { status: 404 });
|
|
}
|
|
|
|
return {
|
|
leagueId,
|
|
seasonId,
|
|
teamId,
|
|
breakdown: {
|
|
...breakdown,
|
|
team: breakdown.team || null,
|
|
},
|
|
standing,
|
|
numTeams,
|
|
};
|
|
}
|
|
|
|
export default function TeamBreakdownPage() {
|
|
const { leagueId, seasonId, breakdown, standing, numTeams } = useLoaderData<typeof loader>();
|
|
|
|
return (
|
|
<div className="container mx-auto py-8 px-4">
|
|
<TeamScoreBreakdown
|
|
leagueId={leagueId}
|
|
seasonId={seasonId}
|
|
breakdown={breakdown}
|
|
standing={standing}
|
|
numTeams={numTeams}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|