From 4c5414166e457508e44880556f24e4dbfa9db0e2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Feb 2026 20:58:48 +0000 Subject: [PATCH] Fix public draft board access not working when setting is enabled Two bugs were causing the isPublicDraftBoard setting to fail: 1. Draft board loader called getAuth() before checking isPublicDraftBoard. Restructured to skip auth entirely for public boards - only call getAuth when the board is private and we need to verify member/commissioner access. 2. Settings action saved the league (name + isPublicDraftBoard) AFTER fetching the current season. If the season fetch had any issue, updateLeague was never reached. Moved the league-level save to happen unconditionally before the season fetch, so isPublicDraftBoard is always persisted on form submit. https://claude.ai/code/session_01Jp2tE3YXhx2jdb6CgCnvZy --- .../$leagueId.draft-board.$seasonId.tsx | 22 +++++----- app/routes/leagues/$leagueId.settings.tsx | 44 +++++++++++-------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/app/routes/leagues/$leagueId.draft-board.$seasonId.tsx b/app/routes/leagues/$leagueId.draft-board.$seasonId.tsx index 80f284e..16e7357 100644 --- a/app/routes/leagues/$leagueId.draft-board.$seasonId.tsx +++ b/app/routes/leagues/$leagueId.draft-board.$seasonId.tsx @@ -10,8 +10,6 @@ import { useState, useEffect } from "react"; export async function loader(args: any) { const { params } = args; const { seasonId } = params; - const auth = await getAuth(args); - const userId = (auth as any).userId as string | null; if (!seasonId) { throw new Response("Season ID is required", { status: 400 }); @@ -31,10 +29,16 @@ export async function loader(args: any) { throw new Response("Season not found", { status: 404 }); } - // Check access: allow if public OR user is a league member/commissioner - let hasAccess = season.league.isPublicDraftBoard; + // Check access: public boards are accessible to everyone without auth + if (!season.league.isPublicDraftBoard) { + // Not public - check if the user is a league member or commissioner + const auth = await getAuth(args); + const userId = (auth as any).userId as string | null; + + if (!userId) { + throw new Response("This draft board is not public", { status: 403 }); + } - if (!hasAccess && userId) { // Check if user is a commissioner const isCommissioner = await db.query.commissioners.findFirst({ where: and( @@ -51,11 +55,9 @@ export async function loader(args: any) { ), }); - hasAccess = !!(isCommissioner || hasTeam); - } - - if (!hasAccess) { - throw new Response("This draft board is not public", { status: 403 }); + if (!isCommissioner && !hasTeam) { + throw new Response("This draft board is not public", { status: 403 }); + } } // Get draft slots (draft order) diff --git a/app/routes/leagues/$leagueId.settings.tsx b/app/routes/leagues/$leagueId.settings.tsx index f77db8d..e825986 100644 --- a/app/routes/leagues/$leagueId.settings.tsx +++ b/app/routes/leagues/$leagueId.settings.tsx @@ -178,9 +178,31 @@ export async function action(args: Route.ActionArgs) { const formData = await request.formData(); const intent = formData.get("intent"); + // For league-level settings (name, public draft board), save immediately + // before checking season, so they work even if no season exists + if (intent === "update") { + const name = formData.get("name"); + const isPublicDraftBoard = formData.get("isPublicDraftBoard") === "on"; + + if (typeof name !== "string" || !name.trim()) { + return { error: "League name is required" }; + } + if (name.trim().length < 3 || name.trim().length > 50) { + return { error: "League name must be between 3 and 50 characters" }; + } + + await updateLeague(leagueId, { + name: name.trim(), + isPublicDraftBoard, + }); + } + // Get current season to check status const season = await findCurrentSeasonWithSports(leagueId); if (!season) { + if (intent === "update") { + return redirect(`/leagues/${leagueId}?updated=true`); + } return { error: "No active season found" }; } @@ -345,17 +367,15 @@ export async function action(args: Route.ActionArgs) { } if (intent === "update") { - const name = formData.get("name"); const teamCount = formData.get("teamCount"); const draftDateTime = formData.get("draftDateTime"); const draftRounds = formData.get("draftRounds"); const draftSpeed = formData.get("draftSpeed"); - const isPublicDraftBoard = formData.get("isPublicDraftBoard") === "on"; - + // Map draft speed to time values let draftInitialTime: number; let draftIncrementTime: number; - + switch (draftSpeed) { case "fast": draftInitialTime = 60; @@ -378,21 +398,9 @@ export async function action(args: Route.ActionArgs) { draftIncrementTime = 15; } - // Validation - if (typeof name !== "string" || !name.trim()) { - return { error: "League name is required" }; - } - - if (name.trim().length < 3 || name.trim().length > 50) { - return { error: "League name must be between 3 and 50 characters" }; - } - + // League-level fields (name, isPublicDraftBoard) are already saved above. + // Now handle season-specific updates. try { - await updateLeague(leagueId, { - name: name.trim(), - isPublicDraftBoard, - }); - // Update season settings const seasonUpdates: any = {};