From 5fd9c6410b5efe2d0ddcbebaf9cdc25f3db2d4e9 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 03:11:34 +0000 Subject: [PATCH] Show team name + username in standings, extract TeamNameDisplay component - Add TeamNameDisplay component that renders team name (as link) with owner username below, matching the league homepage style - Update StandingsTable to use TeamNameDisplay with owner username shown below team name - Update league homepage standings section to use TeamNameDisplay - Add ownerName/teamOwnerId fields to TeamStanding type - Extend getSeasonStandings to include teamOwnerId from team relation - Fetch and attach owner display names in the full standings page loader https://claude.ai/code/session_01EYgGnuTBaRVdBDapJRTxDZ --- app/components/standings/StandingsTable.tsx | 15 +++++---- app/components/ui/team-name-display.tsx | 31 +++++++++++++++++++ app/models/standings.ts | 1 + .../leagues/$leagueId.standings.$seasonId.tsx | 24 +++++++++++--- app/routes/leagues/$leagueId.tsx | 17 ++++------ app/types/standings.ts | 2 ++ 6 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 app/components/ui/team-name-display.tsx diff --git a/app/components/standings/StandingsTable.tsx b/app/components/standings/StandingsTable.tsx index 82c4c17..d981151 100644 --- a/app/components/standings/StandingsTable.tsx +++ b/app/components/standings/StandingsTable.tsx @@ -1,6 +1,6 @@ -import { Link } from "react-router"; import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "~/components/ui/table"; import { Badge } from "~/components/ui/badge"; +import { TeamNameDisplay } from "~/components/ui/team-name-display"; import { type TeamStanding } from "~/types/standings"; interface StandingsTableProps { @@ -54,13 +54,12 @@ export function StandingsTable({ )} - - - {standing.teamName} - + + {standing.actualPoints !== null && standing.actualPoints !== undefined diff --git a/app/components/ui/team-name-display.tsx b/app/components/ui/team-name-display.tsx new file mode 100644 index 0000000..b7b924a --- /dev/null +++ b/app/components/ui/team-name-display.tsx @@ -0,0 +1,31 @@ +import { Link } from "react-router"; + +interface TeamNameDisplayProps { + teamName: string; + ownerName?: string | null; + href?: string; +} + +/** + * Displays a team name with optional owner username below it. + * If href is provided, the team name is rendered as a link. + */ +export function TeamNameDisplay({ teamName, ownerName, href }: TeamNameDisplayProps) { + return ( +
+ {href ? ( + + {teamName} + + ) : ( +

{teamName}

+ )} + {ownerName && ( +

{ownerName}

+ )} +
+ ); +} diff --git a/app/models/standings.ts b/app/models/standings.ts index dce08b4..0391dcd 100644 --- a/app/models/standings.ts +++ b/app/models/standings.ts @@ -29,6 +29,7 @@ export async function getSeasonStandings( return sorted.map((standing) => ({ teamId: standing.teamId, teamName: standing.team.name, + teamOwnerId: standing.team.ownerId, totalPoints: parseFloat(standing.totalPoints), currentRank: standing.currentRank, previousRank: standing.previousRank, diff --git a/app/routes/leagues/$leagueId.standings.$seasonId.tsx b/app/routes/leagues/$leagueId.standings.$seasonId.tsx index 6851e75..57b3187 100644 --- a/app/routes/leagues/$leagueId.standings.$seasonId.tsx +++ b/app/routes/leagues/$leagueId.standings.$seasonId.tsx @@ -9,6 +9,7 @@ import { StandingsTable } from "~/components/standings/StandingsTable"; import { getSevenDayStandingsChange, getSeasonPointProgression } from "~/models/standings"; import { isSeasonComplete, getSeasonCompletionPercentage } from "~/lib/season-helpers.server"; import { PointProgressionChart } from "~/components/standings/PointProgressionChart"; +import { findUsersByClerkIds, getUserDisplayName } from "~/models/user"; import type { Route } from "./+types/$leagueId.standings.$seasonId"; export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors { @@ -73,11 +74,26 @@ export async function loader(args: Route.LoaderArgs) { // Fetch standings with 7-day comparison const standingsWithComparison = await getSevenDayStandingsChange(seasonId, db); + // Fetch owner display names for all teams in standings + const ownerIds = [ + ...new Set( + standingsWithComparison + .map((s) => s.teamOwnerId) + .filter((id): id is string => id != null) + ), + ]; + const userRows = await findUsersByClerkIds(ownerIds); + const userByClerkId = new Map(userRows.map((u) => [u.clerkId, u])); + // Map to format expected by component (use sevenDayRankChange instead of previousRank) - const formattedStandings = standingsWithComparison.map((standing) => ({ - ...standing, - rankChange: standing.sevenDayRankChange, - })); + const formattedStandings = standingsWithComparison.map((standing) => { + const user = standing.teamOwnerId ? userByClerkId.get(standing.teamOwnerId) : undefined; + return { + ...standing, + rankChange: standing.sevenDayRankChange, + ownerName: user ? getUserDisplayName(user) : null, + }; + }); // Fetch historical progression data const progressionData = await getSeasonPointProgression(seasonId, db); diff --git a/app/routes/leagues/$leagueId.tsx b/app/routes/leagues/$leagueId.tsx index f6c72c4..b85f1f5 100644 --- a/app/routes/leagues/$leagueId.tsx +++ b/app/routes/leagues/$leagueId.tsx @@ -14,6 +14,7 @@ import { } from "~/components/ui/card"; import { SportSeasonCard } from "~/components/sports/SportSeasonCard"; import { UpcomingCalendarPanel } from "~/components/sport-season/UpcomingCalendarPanel"; +import { TeamNameDisplay } from "~/components/ui/team-name-display"; import { getDisplayRank } from "~/lib/standings-display"; export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors { @@ -196,17 +197,11 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) { {getDisplayRank(standing, standings.length)}
- - {team.name} - - {ownerName && ( -

- {ownerName} -

- )} +
{standing ? standing.totalPoints : 0} pts diff --git a/app/types/standings.ts b/app/types/standings.ts index 97697a5..9db236d 100644 --- a/app/types/standings.ts +++ b/app/types/standings.ts @@ -5,6 +5,8 @@ export interface TeamStanding { teamId: string; teamName: string; + teamOwnerId?: string | null; + ownerName?: string | null; totalPoints: number; currentRank: number; previousRank: number | null;