sendou.ink/app/features/tournament-bracket/loaders/to.$id.matches.$mid.server.ts
2025-10-13 18:46:56 +03:00

60 lines
1.9 KiB
TypeScript

import type { LoaderFunctionArgs } from "@remix-run/node";
import * as TournamentRepository from "~/features/tournament/TournamentRepository.server";
import * as TournamentTeamRepository from "~/features/tournament/TournamentTeamRepository.server";
import { logger } from "~/utils/logger";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { resolveMapList } from "../core/mapList.server";
import { findMatchById } from "../queries/findMatchById.server";
import { findResultsByMatchId } from "../queries/findResultsByMatchId.server";
import { matchPageParamsSchema } from "../tournament-bracket-schemas.server";
export type TournamentMatchLoaderData = typeof loader;
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { mid: matchId, id: tournamentId } = parseParams({
params,
schema: matchPageParamsSchema,
});
const match = notFoundIfFalsy(findMatchById(matchId));
const isBye = !match.opponentOne || !match.opponentTwo;
if (isBye) {
throw new Response(null, { status: 404 });
}
const pickBanEvents = match.roundMaps?.pickBan
? await TournamentRepository.pickBanEventsByMatchId(match.id)
: [];
const mapList =
match.opponentOne?.id && match.opponentTwo?.id
? resolveMapList({
tournamentId,
matchId,
teams: [match.opponentOne.id, match.opponentTwo.id],
mapPickingStyle: match.mapPickingStyle,
maps: match.roundMaps,
pickBanEvents,
recentlyPlayedMaps:
match.mapPickingStyle !== "TO"
? await TournamentTeamRepository.findRecentlyPlayedMapsByIds({
teamIds: [match.opponentOne.id, match.opponentTwo.id],
}).catch((error) => {
logger.error("Failed to fetch recently played maps", error);
return [];
})
: undefined,
})
: null;
return {
match,
results: findResultsByMatchId(matchId),
mapList,
matchIsOver:
match.opponentOne?.result === "win" ||
match.opponentTwo?.result === "win",
};
};