brackt/app/lib/draft-order.ts
Chris Parsons 3566a97a1e
feat: add projected pick dividers to draft participant list (fixes #82) (#322)
Show visual dividers in the available participants list indicating where
your future draft picks fall relative to the current pick position.
Dividers are suppressed when any filter is active (search, sport filter,
hide drafted, etc.) since positional references are meaningless in a
filtered view.

- Add getProjectedPicks() to draft-order.ts for computing future pick
  positions in a snake draft
- Interleave divider items into the virtualized list in
  AvailableParticipantsSection
- Extract ListItem type to module scope
- Add tests for getProjectedPicks, divider rendering, and filter
  suppression
2026-04-24 09:32:11 -07:00

67 lines
1.9 KiB
TypeScript

/**
* Returns the draft slot for a given pick number in a snake draft.
*/
export function getTeamForPick<T extends { draftOrder: number }>(
pickNumber: number,
draftSlots: T[]
): T | undefined {
const totalTeams = draftSlots.length;
if (totalTeams === 0) return undefined;
const round = Math.ceil(pickNumber / totalTeams);
const isEvenRound = round % 2 === 0;
let pickInRound = ((pickNumber - 1) % totalTeams) + 1;
if (isEvenRound) {
pickInRound = totalTeams - pickInRound + 1;
}
return draftSlots.find((slot) => slot.draftOrder === pickInRound);
}
export interface ProjectedPick {
round: number;
pickNumber: number;
picksFromNow: number;
}
export function getProjectedPicks(options: {
draftSlots: Array<{ draftOrder: number; teamId: string }>;
userTeamId: string;
currentPick: number;
totalRounds: number;
existingPicks: Array<{ pickNumber: number; teamId: string }>;
}): ProjectedPick[] {
const { draftSlots, userTeamId, currentPick, totalRounds, existingPicks } = options;
const totalTeams = draftSlots.length;
if (totalTeams === 0) return [];
const userSlot = draftSlots.find((slot) => slot.teamId === userTeamId);
if (!userSlot) return [];
const userDraftOrder = userSlot.draftOrder;
const pickedNumbersForTeam = new Set(
existingPicks
.filter((p) => p.teamId === userTeamId)
.map((p) => p.pickNumber)
);
const result: ProjectedPick[] = [];
for (let round = 1; round <= totalRounds; round++) {
const isEvenRound = round % 2 === 0;
const pickInRound = isEvenRound
? totalTeams - userDraftOrder + 1
: userDraftOrder;
const pickNumber = (round - 1) * totalTeams + pickInRound;
if (pickNumber < currentPick) continue;
if (pickedNumbersForTeam.has(pickNumber)) continue;
result.push({
round,
pickNumber,
picksFromNow: pickNumber - currentPick,
});
}
return result;
}