import { memo, useMemo, useState } from "react"; import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger, } from "~/components/ui/context-menu"; import { Sheet, SheetContent, SheetHeader, SheetTitle, } from "~/components/ui/sheet"; import { Button } from "~/components/ui/button"; import { MoreVertical } from "lucide-react"; import { formatClockTime, getTimerColorClass } from "~/lib/draft-timer"; type MobileSheetData = | { type: "team"; teamId: string } | { type: "current-cell"; pickNumber: number; teamId: string } | { type: "picked-cell"; pickNumber: number; teamId: string }; interface DraftGridSectionProps { draftSlots: Array<{ id: string; draftOrder: number; team: { id: string; name: string; }; }>; draftGrid: Array< Array<{ pickNumber: number; round: number; pickInRound: number; teamId: string; pick?: { participant: { name: string; }; sport: { name: string; }; }; }> >; currentPick: number; teamTimers: Record; autodraftStatus: Record; connectedTeams: Set; isCommissioner: boolean; onAdjustTimeBankOpen?: (teamId: string) => void; onSetAutodraftOpen?: (teamId: string) => void; onForceAutopick: (pickNumber: number, teamId: string) => void; onForceManualPickOpen: (pickNumber: number, teamId: string) => void; onReplacePick?: (pickNumber: number, teamId: string) => void; onRollbackToPick?: (pickNumber: number) => void; ownerMap?: Record; } export const DraftGridSection = memo(function DraftGridSection({ draftSlots, draftGrid, currentPick, teamTimers, autodraftStatus, connectedTeams, isCommissioner, onAdjustTimeBankOpen, onSetAutodraftOpen, onForceAutopick, onForceManualPickOpen, onReplacePick, onRollbackToPick, ownerMap = {}, }: DraftGridSectionProps) { const [mobileSheet, setMobileSheet] = useState(null); const currentTeamId = useMemo( () => draftGrid.flat().find((c) => c.pickNumber === currentPick)?.teamId ?? null, [draftGrid, currentPick] ); return (

Draft Grid

{/* Team Headers */}
{/* Spacer for round column — sticky so it covers the corner when scrolling both axes */}
{draftSlots.map((slot) => { const teamTime = teamTimers[slot.team.id]; const isAutodraft = autodraftStatus[slot.team.id]?.isEnabled || false; const isConnected = connectedTeams.has(slot.team.id); const headerInner = (
{ownerMap[slot.team.id] || slot.team.name}
{formatClockTime(teamTime)} {isAutodraft && ( (auto) )}
{isCommissioner && (onAdjustTimeBankOpen || onSetAutodraftOpen) && ( )}
); if (isCommissioner && (onAdjustTimeBankOpen || onSetAutodraftOpen)) { return (
{headerInner}
{onAdjustTimeBankOpen && ( onAdjustTimeBankOpen(slot.team.id)}> Adjust Time Bank... )} {onSetAutodraftOpen && ( onSetAutodraftOpen(slot.team.id)}> Set Autodraft... )}
); } return (
{headerInner}
); })}
{/* Draft Grid Rows */}
{draftGrid.map((roundPicks, roundIndex) => { const round = roundIndex + 1; const isEvenRound = round % 2 === 0; const displayPicks = isEvenRound ? [...roundPicks].reverse() : roundPicks; return (
{/* Round label */}
R{round}
{displayPicks.map((cell) => { const isCurrent = cell.pickNumber === currentPick; const isPicked = !!cell.pick; const cellClassName = `relative flex-1 min-w-32 h-20 border-2 rounded-lg p-2 transition-all ${ isCurrent ? "border-electric bg-electric/20 shadow-lg shadow-electric/25 ring-1 ring-electric/40" : isPicked ? "bg-emerald-500/10 border-emerald-500/30" : "border-border bg-card" }`; const cellInner = ( <>
{cell.round}. {String(cell.pickInRound).padStart(2, "0")}
{isPicked ? (
{cell.pick?.participant.name}
{cell.pick?.sport.name}
) : isCurrent ? (
On Clock
) : null} {/* Mobile commissioner button */} {isCommissioner && !isPicked && isCurrent && ( )} {isCommissioner && isPicked && (onReplacePick || onRollbackToPick) && ( )} ); // Commissioner context menu on the current unpicked cell if (isCommissioner && !isPicked && isCurrent) { return (
{cellInner}
onForceAutopick(cell.pickNumber, cell.teamId) } > Force Auto Pick onForceManualPickOpen( cell.pickNumber, cell.teamId ) } > Force Manual Pick
); } // Commissioner context menu on already-picked cells if (isCommissioner && isPicked && (onReplacePick || onRollbackToPick)) { return (
{cellInner}
{onReplacePick && ( onReplacePick(cell.pickNumber, cell.teamId) } > Replace Pick )} {onRollbackToPick && ( onRollbackToPick(cell.pickNumber)} className="text-destructive focus:text-destructive" > Roll Back to This Pick )}
); } return (
{cellInner}
); })}
); })}
{/* Mobile Commissioner Sheet */} !open && setMobileSheet(null)}> Commissioner Actions
{mobileSheet?.type === "team" && ( <> {onAdjustTimeBankOpen && ( )} {onSetAutodraftOpen && ( )} )} {mobileSheet?.type === "current-cell" && ( <> )} {mobileSheet?.type === "picked-cell" && ( <> {onReplacePick && ( )} {onRollbackToPick && ( )} )}
); });