import { Fragment, useId, useState } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card"; import { Switch } from "~/components/ui/switch"; import { TrendingUp, TrendingDown, Minus, Flag, CheckCircle2 } from "lucide-react"; import { TeamOwnerBadge } from "~/components/ui/team-owner-badge"; interface SeasonStanding { id: string; championshipPoints: string; position: number; previousPosition?: number | null; participant: { id: string; name: string; }; } interface TeamOwnership { participantId: string; teamName: string; teamId: string; ownerName?: string; } interface SeasonStandingsProps { standings: SeasonStanding[]; teamOwnerships?: TeamOwnership[]; userParticipantIds?: string[]; showOwnership?: boolean; isFinalized?: boolean; title?: string; } function getMovementIndicator( currentPosition: number, previousPosition?: number | null ) { if (!previousPosition) return null; const change = previousPosition - currentPosition; if (change > 0) { return (
+{change}
); } else if (change < 0) { return (
{change}
); } else { return (
); } } export function SeasonStandings({ standings, teamOwnerships = [], userParticipantIds = [], showOwnership = true, isFinalized = false, title = "Championship Standings", }: SeasonStandingsProps) { const switchId = useId(); const [showStats, setShowStats] = useState(false); const userParticipantSet = new Set(userParticipantIds); const ownershipMap = new Map(); teamOwnerships.forEach((o) => ownershipMap.set(o.participantId, o)); const checkIfTied = (standing: SeasonStanding): boolean => standings.some((o) => o.id !== standing.id && o.position === standing.position); const hasChangeColumn = standings.some((s) => s.previousPosition); const sorted = [...standings].toSorted((a, b) => a.position - b.position); // Index of first row with position > 8; -1 when there is no cutoff. const firstOver8Idx = sorted.findIndex((s) => s.position > 8); return ( {title} {isFinalized && ( Season complete — fantasy points assigned to top 8 finishers )} {standings.length === 0 ? (

No standings data available yet.

Championship points will appear here once results are entered.

) : ( <> {/* Details toggle only shown when position-change data is available */} {hasChangeColumn && (
)}
{hasChangeColumn && showStats && ( )} {showOwnership && ( )} {sorted.map((standing, idx) => { const ownership = showOwnership ? ownershipMap.get(standing.participant.id) ?? null : null; const isTied = checkIfTied(standing); const isOwned = userParticipantSet.has(standing.participant.id); const isTop8 = standing.position <= 8; const showPointsLineBefore = firstOver8Idx !== -1 && idx === firstOver8Idx; const isLastBeforePointsLine = firstOver8Idx !== -1 && idx === firstOver8Idx - 1; return ( {showPointsLineBefore && ( )} {hasChangeColumn && showStats && ( )} {showOwnership && ( )} ); })}
#ChangeParticipant PointsDrafted By
Points Line
{isTied ? `T${standing.position}` : standing.position} {getMovementIndicator(standing.position, standing.previousPosition)} {standing.participant.name} {ownership && (
)}
{Math.round(parseFloat(standing.championshipPoints))} {ownership ? (
) : ( )}
)}
); }