import { useEffect, useState } from "react"; import { Link, useSearchParams } from "react-router"; import { getAuth } from "@clerk/react-router/server"; import { toast } from "sonner"; import { findLeagueById, findCurrentSeason, findTeamsBySeasonId, findCommissionersByLeagueId, isUserLeagueMember, isCommissioner, } from "~/models"; import type { Route } from "./+types/$leagueId"; import { Button } from "~/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card"; export async function loader(args: Route.LoaderArgs) { const { userId } = await getAuth(args); const { params } = args; const { leagueId } = params; // Fetch league const league = await findLeagueById(leagueId); if (!league) { throw new Response("League not found", { status: 404 }); } // Fetch current season const season = await findCurrentSeason(leagueId); // Fetch commissioners const commissioners = await findCommissionersByLeagueId(leagueId); // Check if current user is a commissioner const isUserCommissioner = userId ? await isCommissioner(leagueId, userId) : false; // Check if user is a member (has a team in current season) const isUserMember = userId ? await isUserLeagueMember(leagueId, userId) : false; // Check access: user must be a commissioner, a member, or an admin // If not logged in or not authorized, throw 403 if (!userId) { throw new Response("You must be logged in to view this league", { status: 401 }); } if (!isUserCommissioner && !isUserMember) { throw new Response("You do not have access to this league", { status: 403 }); } // Fetch teams for current season const teams = season ? await findTeamsBySeasonId(season.id) : []; return { league, season, teams, commissioners, currentUserId: userId, isUserCommissioner, }; } export default function LeagueHome({ loaderData }: Route.ComponentProps) { const { league, season, teams, commissioners, currentUserId, isUserCommissioner } = loaderData; const [searchParams, setSearchParams] = useSearchParams(); const [copied, setCopied] = useState(false); useEffect(() => { if (searchParams.get("updated") === "true") { toast.success("League updated successfully"); setSearchParams({}); } if (searchParams.get("joined") === "true") { toast.success("Welcome to the league! You've been assigned a team."); setSearchParams({}); } }, [searchParams, setSearchParams]); const handleCopyInviteLink = async () => { if (!season?.inviteCode) return; const inviteUrl = `${window.location.origin}/i/${season.inviteCode}`; try { await navigator.clipboard.writeText(inviteUrl); setCopied(true); toast.success("Invite link copied to clipboard!"); setTimeout(() => setCopied(false), 2000); } catch (err) { toast.error("Failed to copy invite link"); } }; return (
{season.year} Season • Status:{" "} {season.status.replace("_", " ")}
)}Created
{new Date(league.createdAt).toLocaleDateString()}
Season Status
{season.status.replace("_", " ")}
Anyone with this link can join your league
Commissioner {index + 1} {commissioner.userId === currentUserId && ( (You) )}
Since {new Date(commissioner.createdAt).toLocaleDateString()}