import { auth } from "~/lib/auth.server"; import { addDays, subDays } from "date-fns"; import { ArrowLeft } from "lucide-react"; import { Link } from "react-router"; import type { Route } from "./+types/$leagueId.upcoming-events"; import { findLeagueById, isCommissioner, isUserLeagueMember, } from "~/models"; import { findCurrentSeasonWithSports } from "~/models/season"; import { findTeamByOwnerAndSeason } from "~/models/team"; import { getDraftedParticipantsBySportsSeason } from "~/models/draft-pick"; import { getUpcomingEventsForDraftedParticipants } from "~/models/scoring-event"; import type { CalendarPanelEvent } from "~/components/sport-season/UpcomingCalendarPanel"; import { UpcomingCalendarPanel } from "~/components/sport-season/UpcomingCalendarPanel"; import { toEventSortKey } from "~/lib/date-utils"; export function meta({ data }: Route.MetaArgs) { const leagueName = data?.leagueName ?? "League"; return [{ title: `${leagueName} — Upcoming Events — Brackt` }]; } export async function loader(args: Route.LoaderArgs) { const session = await auth.api.getSession({ headers: args.request.headers }); const userId = session?.user.id ?? null; const { leagueId } = args.params; const league = await findLeagueById(leagueId); if (!league) { throw new Response("League not found", { status: 404 }); } if (!userId) { throw new Response("You must be logged in to view this league", { status: 401 }); } const [isUserCommissioner, isUserMember] = await Promise.all([ isCommissioner(leagueId, userId), isUserLeagueMember(leagueId, userId), ]); if (!isUserCommissioner && !isUserMember) { throw new Response("You do not have access to this league", { status: 403 }); } const seasonWithSports = await findCurrentSeasonWithSports(leagueId); const today = new Date(); const dateFromStr = subDays(today, 1).toISOString().split("T")[0]; const dateToStr = addDays(today, 60).toISOString().split("T")[0]; const calendarEvents: CalendarPanelEvent[] = []; if (seasonWithSports?.seasonSports && seasonWithSports.id) { const myTeam = await findTeamByOwnerAndSeason(userId, seasonWithSports.id); if (myTeam) { const participantsBySportsSeason = await getDraftedParticipantsBySportsSeason( myTeam.id, seasonWithSports.id ); const perSeasonEvents = await Promise.all( seasonWithSports.seasonSports.map(async ({ sportsSeason: ss }) => { const draftedParticipants = participantsBySportsSeason.get(ss.id) ?? []; if (draftedParticipants.length === 0) return []; const events = await getUpcomingEventsForDraftedParticipants( ss.id, ss.scoringPattern ?? "", draftedParticipants, dateFromStr, dateToStr ); return events.map((event) => ({ ...event, sportName: ss.sport.name, sportSeasonName: ss.name, sportsSeasonPageUrl: `/leagues/${leagueId}/sports-seasons/${ss.id}`, })); }) ); calendarEvents.push(...perSeasonEvents.flat()); } } const upcomingCalendarEvents = calendarEvents.toSorted((a, b) => toEventSortKey(a).localeCompare(toEventSortKey(b)) ); return { leagueName: league.name, leagueId, upcomingCalendarEvents, }; } export default function LeagueUpcomingEventsPage({ loaderData }: Route.ComponentProps) { const { leagueName, leagueId, upcomingCalendarEvents } = loaderData; return (
{leagueName}

Upcoming Events

Next 60 days · {leagueName}

); }