import { memo, useEffect, useMemo, useState } from "react"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "~/components/ui/select"; import { DraftPickCell } from "./DraftPickCell"; import { type DraftPick, groupPicksByTeamAndSport } from "./picks-utils"; interface TeamRosterViewProps { draftSlots: Array<{ id: string; team: { id: string; name: string } }>; ownerMap?: Record; picks: DraftPick[]; sports: Array<{ id: string; name: string }>; totalRounds: number; } export const TeamRosterView = memo(function TeamRosterView({ draftSlots, ownerMap = {}, picks, sports, totalRounds, }: TeamRosterViewProps) { const [selectedTeamId, setSelectedTeamId] = useState( draftSlots[0]?.team.id ?? "" ); useEffect(() => { if ( draftSlots.length > 0 && !draftSlots.some((s) => s.team.id === selectedTeamId) ) { setSelectedTeamId(draftSlots[0].team.id); } }, [draftSlots, selectedTeamId]); const picksByTeamAndSport = useMemo( () => groupPicksByTeamAndSport(picks), [picks] ); const teamPicks = useMemo( () => picksByTeamAndSport.get(selectedTeamId), [picksByTeamAndSport, selectedTeamId] ); const flexPicksAvailable = useMemo( () => Math.max(0, totalRounds - sports.length), [totalRounds, sports.length] ); const flexPicksUsed = useMemo(() => { let used = 0; teamPicks?.forEach((sportPicks) => { if (sportPicks.length > 1) used += sportPicks.length - 1; }); return used; }, [teamPicks]); const flexPicksRemaining = useMemo( () => flexPicksAvailable - flexPicksUsed, [flexPicksAvailable, flexPicksUsed] ); const missingSports = useMemo( () => sports.filter((s) => (teamPicks?.get(s.id)?.length ?? 0) === 0), [sports, teamPicks] ); const draftedSports = useMemo( () => sports.filter((s) => (teamPicks?.get(s.id)?.length ?? 0) > 0), [sports, teamPicks] ); const flexColor = flexPicksAvailable === 0 ? "text-muted-foreground" : flexPicksRemaining <= 0 ? "text-destructive" : flexPicksRemaining <= Math.ceil(flexPicksAvailable * 0.25) ? "text-amber-500 dark:text-amber-400" : "text-emerald-500 dark:text-emerald-400"; if (draftSlots.length === 0) { return (

No teams in this draft.

); } return (
{/* Team selector */}
{/* Mini dashboard */}

Flex Picks

{flexPicksAvailable === 0 ? (

N/A

) : ( <>

{flexPicksRemaining} / {flexPicksAvailable}

remaining

)}

Sports Remaining

0 ? "text-foreground" : "text-emerald-500 dark:text-emerald-400"}`}> {missingSports.length} / {sports.length}

to draft

{/* Missing sports list */} {missingSports.length > 0 && (

Still Needed

{missingSports.map((s) => s.name).join(" ยท ")}

)} {/* Per-sport pick cells */} {draftedSports.length === 0 ? (

No picks yet

) : (
{draftedSports.map((sport) => { const sportPicks = teamPicks?.get(sport.id) ?? []; return (

{sport.name}

{sportPicks.map((pick) => ( ))}
); })}
)}
); });