diff --git a/app/components/events/Cs2MajorEventView.tsx b/app/components/events/Cs2MajorEventView.tsx index 9165388..474b80f 100644 --- a/app/components/events/Cs2MajorEventView.tsx +++ b/app/components/events/Cs2MajorEventView.tsx @@ -54,35 +54,6 @@ const STAGE_LABELS: Record = { champions: "Champions", }; -function StageStatusBadge({ result }: { result: Cs2StageResultWithName }) { - if (result.stageEliminated !== null) { - return ( - - - Eliminated - - ); - } - const winsNeeded = 3; - const wins = result.stageEliminatedWins ?? 0; - if (result.stageEliminated === null && result.stageEntry !== null) { - // Null stageEliminated = either in progress or advanced - // If their stageEntry is less than the current stage context, they advanced - return ( - - - Advanced - - ); - } - return ( - - - In Progress - - ); -} - function SwissStageTab({ stage, stageResults, @@ -99,7 +70,6 @@ function SwissStageTab({ const ownershipMap = new Map(teamOwnerships.map((o) => [o.participantId, o])); const userIds = new Set(userParticipantIds); - const teamsInStage = stageResults.filter((r) => r.stageEntry <= stage && (r.stageEliminated === null || r.stageEliminated >= stage)); const matchesInStage = matches.filter((m) => m.matchStage === stage); // Group teams by W-L record (approximated from stageEliminatedWins if eliminated, else unknown) @@ -154,7 +124,7 @@ function SwissStageTab({ Eliminated - ) : isAdvanced && r.stageEliminated === null ? ( + ) : isAdvanced ? ( Advanced @@ -218,8 +188,13 @@ export function Cs2MajorEventView({ teamOwnerships, userParticipantIds, }: Props) { - const hasChampions = playoffMatches.length > 0; - const [activeTab, setActiveTab] = useState(hasChampions ? "champions" : 3); + const hasChampionsActivity = playoffMatches.some((m) => m.winnerId !== null); + const highestActiveStage: 1 | 2 | 3 = + cs2StageResults.some((r) => r.stageEntry >= 3 || r.stageEliminated === 3) ? 3 : + cs2StageResults.some((r) => r.stageEntry >= 2 || r.stageEliminated === 2) ? 2 : 1; + const [activeTab, setActiveTab] = useState( + hasChampionsActivity ? "champions" : highestActiveStage + ); const tabs: StageTab[] = [1, 2, 3, "champions"]; const ownershipMap = new Map(teamOwnerships.map((o) => [o.participantId, o])); @@ -262,7 +237,7 @@ export function Cs2MajorEventView({ {/* Champions Stage bracket */} {activeTab === "champions" && ( - hasChampions ? ( + playoffMatches.length > 0 ? ( & { + createdAt: string; + updatedAt: string; participant1: { id: string; name: string } | null; participant2: { id: string; name: string } | null; winner: { id: string; name: string } | null; @@ -115,17 +117,20 @@ export async function loader({ params, request }: Route.LoaderArgs) { // CS2 Major — load Swiss stage data + bracket if (simulatorType === "cs2_major_qualifying_points") { - const [cs2StageResults, seasonMatches, playoffMatchRows, eventResultRows] = await Promise.all([ + const [cs2StageResults, seasonMatches, playoffMatchRows] = await Promise.all([ getCs2StageResultsForEvent(eventId), findSeasonMatchesByScoringEventId(eventId), db.query.playoffMatches.findMany({ where: eq(schema.playoffMatches.scoringEventId, eventId), with: { participant1: true, participant2: true, winner: true, loser: true }, }), - getEventResults(eventId), ]); - const playoffMatches = playoffMatchRows as PlayoffMatchWithRelations[]; + const playoffMatches: PlayoffMatchWithRelations[] = playoffMatchRows.map((m) => ({ + ...m, + createdAt: m.createdAt.toISOString(), + updatedAt: m.updatedAt.toISOString(), + })); const templateId = scoringEvent.bracketTemplateId ?? undefined; const template = templateId ? getBracketTemplate(templateId) : undefined; const playoffRounds = getOrderedRoundsFromMatches(playoffMatches, template); @@ -147,13 +152,6 @@ export async function loader({ params, request }: Route.LoaderArgs) { playoffMatches, playoffRounds, bracketTemplateId: templateId ?? null, - eventResults: eventResultRows.map((r) => ({ - id: r.id, - placement: r.placement, - qualifyingPointsAwarded: r.qualifyingPointsAwarded, - seasonParticipantId: r.seasonParticipantId, - participantName: r.seasonParticipant?.name ?? null, - })), }; } @@ -163,7 +161,11 @@ export async function loader({ params, request }: Route.LoaderArgs) { where: eq(schema.playoffMatches.scoringEventId, eventId), with: { participant1: true, participant2: true, winner: true, loser: true }, }); - const playoffMatches = playoffMatchRows as PlayoffMatchWithRelations[]; + const playoffMatches: PlayoffMatchWithRelations[] = playoffMatchRows.map((m) => ({ + ...m, + createdAt: m.createdAt.toISOString(), + updatedAt: m.updatedAt.toISOString(), + })); const templateId = scoringEvent.bracketTemplateId ?? undefined; const template = templateId ? getBracketTemplate(templateId) : undefined; const playoffRounds = getOrderedRoundsFromMatches(playoffMatches, template); diff --git a/app/routes/leagues/$leagueId.sports-seasons.$sportsSeasonId.events.$eventId.tsx b/app/routes/leagues/$leagueId.sports-seasons.$sportsSeasonId.events.$eventId.tsx index 67fa8ca..ba8b92e 100644 --- a/app/routes/leagues/$leagueId.sports-seasons.$sportsSeasonId.events.$eventId.tsx +++ b/app/routes/leagues/$leagueId.sports-seasons.$sportsSeasonId.events.$eventId.tsx @@ -1,8 +1,8 @@ import { Link } from "react-router"; import { ArrowLeft, Calendar } from "lucide-react"; -import { format } from "date-fns"; import type { Route } from "./+types/$leagueId.sports-seasons.$sportsSeasonId.events.$eventId"; import { loader } from "./$leagueId.sports-seasons.$sportsSeasonId.events.$eventId.server"; +import { formatEventDate } from "~/lib/date-utils"; import { Badge } from "~/components/ui/badge"; import { Card, @@ -30,13 +30,6 @@ export function meta({ data }: Route.MetaArgs) { export { loader }; -function formatEventDate(dateStr: string | null | Date | undefined): string { - if (!dateStr) return "Date TBD"; - const d = new Date(dateStr); - if (isNaN(d.getTime())) return String(dateStr); - return format(d, "MMM d, yyyy"); -} - export default function EventDetailPage({ loaderData }: Route.ComponentProps) { const { league, sportsSeason, scoringEvent } = loaderData; const leagueId = league.id; @@ -49,9 +42,10 @@ export default function EventDetailPage({ loaderData }: Route.ComponentProps) { ]) ); - const eventDate = scoringEvent.eventStartsAt - ? formatEventDate(scoringEvent.eventStartsAt) - : formatEventDate(scoringEvent.eventDate); + const eventDate = + formatEventDate(scoringEvent.eventStartsAt as string | null) ?? + formatEventDate(scoringEvent.eventDate) ?? + "Date TBD"; return (