brackt/app/components/draft/MiniDraftGrid.tsx
2026-04-17 23:06:45 -07:00

197 lines
7.1 KiB
TypeScript

import { memo, useMemo } from "react";
import { DraftPickCell } from "~/components/draft/DraftPickCell";
import type { SeasonStatus } from "~/models/season";
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuTrigger,
} from "~/components/ui/context-menu";
interface MiniDraftGridProps {
draftSlots: Array<{
id: string;
draftOrder: number;
team: {
id: string;
name: string;
logoUrl?: string | null;
};
}>;
draftGrid: Array<
Array<{
pickNumber: number;
round: number;
pickInRound: number;
teamId: string;
pick?: {
participant: {
name: string;
};
sport: {
name: string;
};
};
}>
>;
currentPick: number;
currentRound: number;
ownerMap?: Record<string, string>;
seasonStatus?: SeasonStatus;
draftPaused?: boolean;
onForceAutopick?: (pickNumber: number, teamId: string) => void;
onForceManualPickOpen?: (pickNumber: number, teamId: string) => void;
onReplacePick?: (pickNumber: number, teamId: string) => void;
onRollbackToPick?: (pickNumber: number) => void;
}
export const MiniDraftGrid = memo(function MiniDraftGrid({
draftSlots,
draftGrid,
currentPick,
currentRound,
ownerMap = {},
seasonStatus,
draftPaused,
onForceAutopick,
onForceManualPickOpen,
onReplacePick,
onRollbackToPick,
}: MiniDraftGridProps) {
const roundsToShow = useMemo(() => {
if (currentRound <= 1) return [0, 1];
return [currentRound - 2, currentRound - 1];
}, [currentRound]);
if (draftGrid.length === 0) return null;
return (
<div className="overflow-x-auto">
<div className="inline-block min-w-full">
<div className="flex gap-1.5 mb-1.5">
<div className="w-7 flex-shrink-0" />
{draftSlots.map((slot) => (
<div key={slot.id} className="flex-1 min-w-20 text-center">
<div className="text-xs font-medium truncate px-1 text-muted-foreground">
{ownerMap[slot.team.id] || slot.team.name}
</div>
</div>
))}
</div>
<div className="space-y-1.5">
{roundsToShow.map((roundIndex) => {
if (roundIndex >= draftGrid.length) return null;
const roundPicks = draftGrid[roundIndex];
const round = roundIndex + 1;
const isEvenRound = round % 2 === 0;
const displayPicks = isEvenRound
? [...roundPicks].toReversed()
: roundPicks;
return (
<div key={round} className="flex gap-1.5 items-stretch">
<div className="w-7 flex-shrink-0 flex items-center justify-center">
<span className="text-xs font-mono text-muted-foreground">R{round}</span>
</div>
{displayPicks.map((cell) => {
const isCurrent = cell.pickNumber === currentPick;
const isPicked = !!cell.pick;
const cellState = isPicked
? "picked"
: isCurrent
? "current"
: "upcoming";
const pickData = cell.pick
? {
participant: { name: cell.pick.participant.name },
sport: { name: cell.pick.sport.name },
}
: undefined;
if (!isPicked && isCurrent && (onForceAutopick || onForceManualPickOpen)) {
return (
<ContextMenu key={cell.pickNumber}>
<ContextMenuTrigger asChild>
<DraftPickCell
pickNumber={cell.pickNumber}
round={cell.round}
pickInRound={cell.pickInRound}
state={cellState}
pick={pickData}
seasonStatus={seasonStatus}
draftPaused={draftPaused}
className="[&>div]:h-10 cursor-context-menu"
/>
</ContextMenuTrigger>
<ContextMenuContent>
{onForceAutopick && (
<ContextMenuItem onClick={() => onForceAutopick(cell.pickNumber, cell.teamId)}>
Force Auto Pick
</ContextMenuItem>
)}
{onForceManualPickOpen && (
<ContextMenuItem onClick={() => onForceManualPickOpen(cell.pickNumber, cell.teamId)}>
Force Manual Pick
</ContextMenuItem>
)}
</ContextMenuContent>
</ContextMenu>
);
}
if (isPicked && (onReplacePick || onRollbackToPick)) {
return (
<ContextMenu key={cell.pickNumber}>
<ContextMenuTrigger asChild>
<DraftPickCell
pickNumber={cell.pickNumber}
round={cell.round}
pickInRound={cell.pickInRound}
state={cellState}
pick={pickData}
seasonStatus={seasonStatus}
draftPaused={draftPaused}
className="[&>div]:h-10 cursor-context-menu"
/>
</ContextMenuTrigger>
<ContextMenuContent>
{onReplacePick && (
<ContextMenuItem onClick={() => onReplacePick(cell.pickNumber, cell.teamId)}>
Replace Pick
</ContextMenuItem>
)}
{onRollbackToPick && (
<ContextMenuItem
onClick={() => onRollbackToPick(cell.pickNumber)}
className="text-destructive focus:text-destructive"
>
Roll Back to This Pick
</ContextMenuItem>
)}
</ContextMenuContent>
</ContextMenu>
);
}
return (
<DraftPickCell
key={cell.pickNumber}
pickNumber={cell.pickNumber}
round={cell.round}
pickInRound={cell.pickInRound}
state={cellState}
pick={pickData}
seasonStatus={seasonStatus}
draftPaused={draftPaused}
className="[&>div]:h-10"
/>
);
})}
</div>
);
})}
</div>
</div>
</div>
);
});