diff --git a/app/components/draft/DraftSummaryView.tsx b/app/components/draft/DraftSummaryView.tsx index 844df3c..45eaf50 100644 --- a/app/components/draft/DraftSummaryView.tsx +++ b/app/components/draft/DraftSummaryView.tsx @@ -1,8 +1,9 @@ -import { memo, useMemo } from "react"; +import { memo, useMemo, Fragment } from "react"; +import { TeamAvatar } from "~/components/TeamAvatar"; import { type DraftPick, groupPicksByTeamAndSport } from "./picks-utils"; interface DraftSummaryViewProps { - draftSlots: Array<{ id: string; team: { id: string; name: string } }>; + draftSlots: Array<{ id: string; team: { id: string; name: string; logoUrl?: string | null } }>; ownerMap?: Record; picks: DraftPick[]; sports: Array<{ id: string; name: string }>; @@ -58,90 +59,93 @@ export const DraftSummaryView = memo(function DraftSummaryView({ ); } + const gridCols = `140px 96px repeat(${draftSlots.length}, minmax(80px, 1fr))`; + return (
- - - - - - {draftSlots.map((slot, index) => { - const displayName = ownerMap[slot.team.id] || slot.team.name; - const isLast = index === draftSlots.length - 1; - const used = flexPicksUsedByTeam.get(slot.team.id) ?? 0; - const flexesExhausted = flexPicksAvailable > 0 && used >= flexPicksAvailable; - return ( - - ); - })} - - - - {sports.map((sport, sportIndex) => { - const isLastRow = sportIndex === sports.length - 1; - const { total: sportTotal, teams: sportTeamCount } = sportStats.get(sport.id) ?? { total: 0, teams: 0 }; - return ( - - - - {draftSlots.map((slot, slotIndex) => { - const count = - picksByTeamAndSport.get(slot.team.id)?.get(sport.id) - ?.length ?? 0; - const isLast = slotIndex === draftSlots.length - 1; - return ( - - ); - })} - - ); - })} - -
+ + {/* Header row */} +
+ Sport +
+
+ Total +
+ {draftSlots.map((slot, index) => { + const ownerName = ownerMap[slot.team.id]; + const isLast = index === draftSlots.length - 1; + const used = flexPicksUsedByTeam.get(slot.team.id) ?? 0; + const flexesExhausted = flexPicksAvailable > 0 && used >= flexPicksAvailable; + return ( +
- Sport -
- Total - - {displayName} - {flexPicksAvailable > 0 && ( -
- {used} of {flexPicksAvailable} flexes -
- )} -
- {sport.name} - - {sportTotal > 0 ? ( - <> -
{sportTotal}
-
- {sportTeamCount} team{sportTeamCount !== 1 ? "s" : ""} -
- - ) : null} -
= 2 ? "bg-accent/30 font-semibold" : "bg-background" - } ${!isLastRow ? "border-b" : ""} ${!isLast ? "border-r" : ""}`} - > - {count > 0 ? count : null} -
+
+ +
+ {ownerName || slot.team.name} +
+ {flexPicksAvailable > 0 && ( + + {used}/{flexPicksAvailable} flex picks + + )} +
+
+ ); + })} + + {/* Data rows */} + {sports.map((sport, sportIndex) => { + const isLastRow = sportIndex === sports.length - 1; + const { total: sportTotal, teams: sportTeamCount } = + sportStats.get(sport.id) ?? { total: 0, teams: 0 }; + return ( + +
+ {sport.name} +
+
+ {sportTotal > 0 ? ( + <> +
{sportTotal}
+
{sportTeamCount}/{draftSlots.length} teams
+ + ) : ( + + )} +
+ {draftSlots.map((slot, slotIndex) => { + const count = picksByTeamAndSport.get(slot.team.id)?.get(sport.id)?.length ?? 0; + const isLast = slotIndex === draftSlots.length - 1; + const isFlex = count >= 2; + return ( +
+ {count > 0 ? ( + + {count} + + ) : ( + + )} +
+ ); + })} +
+ ); + })} + + ); }); diff --git a/app/components/ui/team-owner-badge.tsx b/app/components/ui/team-owner-badge.tsx index 51639ab..66fb950 100644 --- a/app/components/ui/team-owner-badge.tsx +++ b/app/components/ui/team-owner-badge.tsx @@ -1,9 +1,24 @@ -import { getAvatarColor } from "~/lib/color-hash"; +const AVATAR_COLORS = [ + "#adf661", + "#2ce1c1", + "#8b5cf6", + "#f59e0b", + "#ef4444", + "#3b82f6", +]; + +function hashName(name: string): number { + let hash = 0; + for (let i = 0; i < name.length; i++) { + hash = (hash * 31 + name.charCodeAt(i)) & 0xffff; + } + return hash; +} interface TeamOwnerBadgeProps { teamName: string; ownerName?: string; - align?: "left" | "right"; // right = avatar on the right side for the right column + align?: "left" | "right"; } export function TeamOwnerBadge({ @@ -11,14 +26,23 @@ export function TeamOwnerBadge({ ownerName, align = "left", }: TeamOwnerBadgeProps) { - const initial = teamName.charAt(0).toUpperCase(); - const colorClass = getAvatarColor(teamName); + const initials = + teamName + .split(/\s+/) + .filter(Boolean) + .slice(0, 2) + .map((w) => w[0].toUpperCase()) + .join("") || "?"; + const color = AVATAR_COLORS[hashName(teamName) % AVATAR_COLORS.length]; const avatar = (
- {initial} + {initials}
);