From 47b69ce9cf2621cd4ac4a9c505ea9bf05bc121fd Mon Sep 17 00:00:00 2001 From: Chris Parsons <438676+chrisparsons83@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:28:37 -0800 Subject: [PATCH] Include commissioner leagues in user's active leagues (#8) * Show leagues where user is a member regardless of team assignment The homepage now uses a union query to show leagues where the user either has a team in the current season OR is a commissioner. Previously, commissioners without a team could not see their leagues on the homepage. https://claude.ai/code/session_01E3ugKTfatkEc5TcDGXvHiW * Fix stale empty state card title in home route Update 'No Active Leagues' to 'No Leagues' to match the updated description which is now about membership rather than active seasons. https://claude.ai/code/session_01E3ugKTfatkEc5TcDGXvHiW * Fix union import: use two queries with JS deduplication drizzle-orm 0.36.x does not export a standalone union() function. Replace with two awaited queries merged via a Map (dedup by id), then sorted by createdAt descending in JS. https://claude.ai/code/session_01E3ugKTfatkEc5TcDGXvHiW --------- Co-authored-by: Claude --- app/models/league.ts | 43 +++++++++++++++++++++++++++++-------------- app/routes/home.tsx | 4 ++-- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/app/models/league.ts b/app/models/league.ts index 7f92e8b..50537e0 100644 --- a/app/models/league.ts +++ b/app/models/league.ts @@ -71,23 +71,38 @@ export async function findLeaguesWithActiveSeasonsByUserId( ): Promise { const db = database(); - // Query to find all leagues where user has a team in the current season - const leagues = await db - .selectDistinct({ - id: schema.leagues.id, - name: schema.leagues.name, - createdBy: schema.leagues.createdBy, - currentSeasonId: schema.leagues.currentSeasonId, - isPublicDraftBoard: schema.leagues.isPublicDraftBoard, - createdAt: schema.leagues.createdAt, - updatedAt: schema.leagues.updatedAt, - }) + const leagueFields = { + id: schema.leagues.id, + name: schema.leagues.name, + createdBy: schema.leagues.createdBy, + currentSeasonId: schema.leagues.currentSeasonId, + isPublicDraftBoard: schema.leagues.isPublicDraftBoard, + createdAt: schema.leagues.createdAt, + updatedAt: schema.leagues.updatedAt, + }; + + // Leagues where user has a team in the current season + const leaguesWithTeam = await db + .select(leagueFields) .from(schema.leagues) .innerJoin(schema.teams, eq(schema.teams.seasonId, schema.leagues.currentSeasonId)) - .where(eq(schema.teams.ownerId, userId)) - .orderBy(desc(schema.leagues.createdAt)); + .where(eq(schema.teams.ownerId, userId)); - return leagues; + // Leagues where user is a commissioner (with or without a team) + const leaguesAsCommissioner = await db + .select(leagueFields) + .from(schema.leagues) + .innerJoin(schema.commissioners, eq(schema.commissioners.leagueId, schema.leagues.id)) + .where(eq(schema.commissioners.userId, userId)); + + // Deduplicate by id in case user is both a commissioner and has a team, then sort + const leagueMap = new Map(); + for (const league of [...leaguesWithTeam, ...leaguesAsCommissioner]) { + leagueMap.set(league.id, league); + } + return [...leagueMap.values()].sort( + (a, b) => b.createdAt.getTime() - a.createdAt.getTime() + ); } /** diff --git a/app/routes/home.tsx b/app/routes/home.tsx index e2dac3b..4674a79 100644 --- a/app/routes/home.tsx +++ b/app/routes/home.tsx @@ -92,9 +92,9 @@ export default function Home({ loaderData }: Route.ComponentProps) { {leagues.length === 0 ? ( - No Active Leagues + No Leagues - You don't have any teams in leagues with active seasons yet + You aren't a member of any leagues yet