dark mode default, basic tournament stats/podium
This commit is contained in:
@@ -9,16 +9,24 @@ import type { Team } from "@/features/teams/types";
|
||||
import PocketBase from "pocketbase";
|
||||
import { transformFreeAgent, transformTournament, transformTournamentInfo } from "@/lib/pocketbase/util/transform-types";
|
||||
import { transformTeam } from "@/lib/pocketbase/util/transform-types";
|
||||
import { getFreeAgents } from "@/features/tournaments/server";
|
||||
import { PlayerInfo } from "@/features/players/types";
|
||||
|
||||
export function createTournamentsService(pb: PocketBase) {
|
||||
return {
|
||||
async getTournament(id: string, isAdmin: boolean = false): Promise<Tournament> {
|
||||
const result = await pb.collection("tournaments").getOne(id, {
|
||||
expand: "teams, teams.players, matches, matches.tournament, matches.home, matches.away, matches.home.players, matches.away.players",
|
||||
});
|
||||
return transformTournament(result, isAdmin);
|
||||
const [tournamentResult, teamStatsResult] = await Promise.all([
|
||||
pb.collection("tournaments").getOne(id, {
|
||||
expand: "teams, teams.players, matches, matches.tournament, matches.home, matches.away, matches.home.players, matches.away.players",
|
||||
}),
|
||||
pb.collection("team_stats_per_tournament").getFullList({
|
||||
filter: `tournament_id = "${id}"`,
|
||||
sort: "-wins,-total_cups_made"
|
||||
})
|
||||
]);
|
||||
|
||||
tournamentResult.team_stats = teamStatsResult;
|
||||
|
||||
return transformTournament(tournamentResult, isAdmin);
|
||||
},
|
||||
async getMostRecentTournament(): Promise<Tournament> {
|
||||
const result = await pb
|
||||
@@ -29,17 +37,35 @@ export function createTournamentsService(pb: PocketBase) {
|
||||
sort: "-created",
|
||||
}
|
||||
);
|
||||
|
||||
const teamStatsResult = await pb.collection("team_stats_per_tournament").getFullList({
|
||||
filter: `tournament_id = "${result.id}"`,
|
||||
sort: "-wins,-total_cups_made"
|
||||
});
|
||||
|
||||
result.team_stats = teamStatsResult;
|
||||
|
||||
return transformTournament(result);
|
||||
},
|
||||
async listTournaments(): Promise<TournamentInfo[]> {
|
||||
const result = await pb
|
||||
.collection("tournaments")
|
||||
.getFullList({
|
||||
fields: "id,name,location,start_time,end_time,logo",
|
||||
expand: "teams,teams.players,matches",
|
||||
sort: "-created",
|
||||
});
|
||||
|
||||
return result.map(transformTournamentInfo);
|
||||
const tournamentsWithStats = await Promise.all(result.map(async (tournament) => {
|
||||
const teamStats = await pb.collection("team_stats_per_tournament").getFullList({
|
||||
filter: `tournament_id = "${tournament.id}"`,
|
||||
sort: "-wins,-total_cups_made"
|
||||
});
|
||||
|
||||
tournament.team_stats = teamStats;
|
||||
return tournament;
|
||||
}));
|
||||
|
||||
return tournamentsWithStats.map(transformTournamentInfo);
|
||||
},
|
||||
async createTournament(data: TournamentInput): Promise<Tournament> {
|
||||
const result = await pb
|
||||
|
||||
@@ -57,12 +57,58 @@ export const transformMatch = (record: any, isAdmin: boolean = false): Match =>
|
||||
}
|
||||
|
||||
export const transformTournamentInfo = (record: any): TournamentInfo => {
|
||||
// Check if tournament is complete by looking at matches
|
||||
const matches = record.expand?.matches || [];
|
||||
// Filter out bye matches (tbd status with bye=true) when checking completion
|
||||
const nonByeMatches = matches.filter((match: any) => !(match.status === 'tbd' && match.bye === true));
|
||||
const isComplete = nonByeMatches.length > 0 && nonByeMatches.every((match: any) => match.status === 'ended');
|
||||
|
||||
let first_place: TeamInfo | undefined = undefined;
|
||||
let second_place: TeamInfo | undefined = undefined;
|
||||
let third_place: TeamInfo | undefined = undefined;
|
||||
|
||||
if (isComplete) {
|
||||
const teams = record.expand?.teams || [];
|
||||
const teamMap = new Map<string, TeamInfo>(teams.map((team: any) => [team.id, transformTeamInfo(team)]));
|
||||
|
||||
const winnersMatches = matches.filter((match: any) => !match.is_losers_bracket);
|
||||
const finalsMatch = winnersMatches.reduce((highest: any, current: any) =>
|
||||
(!highest || current.lid > highest.lid) ? current : highest, null);
|
||||
|
||||
const losersMatches = matches.filter((match: any) => match.is_losers_bracket);
|
||||
const losersFinale = losersMatches.reduce((highest: any, current: any) =>
|
||||
(!highest || current.lid > highest.lid) ? current : highest, null);
|
||||
|
||||
if (finalsMatch && finalsMatch.status === 'ended') {
|
||||
const finalsWinner = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.home : finalsMatch.away;
|
||||
const finalsLoser = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.away : finalsMatch.home;
|
||||
|
||||
const finalsWinnerId = typeof finalsWinner === 'string' ? finalsWinner : finalsWinner?.id;
|
||||
const finalsLoserId = typeof finalsLoser === 'string' ? finalsLoser : finalsLoser?.id;
|
||||
|
||||
first_place = finalsWinnerId ? teamMap.get(finalsWinnerId) || undefined : undefined;
|
||||
second_place = finalsLoserId ? teamMap.get(finalsLoserId) || undefined : undefined;
|
||||
|
||||
}
|
||||
|
||||
if (losersFinale && losersFinale.status === 'ended') {
|
||||
const losersFinaleLoser = (losersFinale.home_cups > losersFinale.away_cups) ? losersFinale.away : losersFinale.home;
|
||||
|
||||
const losersFinaleloserId = typeof losersFinaleLoser === 'string' ? losersFinaleLoser : losersFinaleLoser?.id;
|
||||
third_place = losersFinaleloserId ? teamMap.get(losersFinaleloserId) || undefined : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: record.id,
|
||||
name: record.name,
|
||||
location: record.location,
|
||||
start_time: record.start_time,
|
||||
end_time: record.end_time,
|
||||
logo: record.logo,
|
||||
first_place,
|
||||
second_place,
|
||||
third_place,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -149,7 +195,60 @@ export function transformTournament(record: any, isAdmin: boolean = false): Tour
|
||||
a.lid - b.lid ? -1 : 0
|
||||
)
|
||||
?.map((match: any) => transformMatch(match, isAdmin)) ?? [];
|
||||
|
||||
|
||||
const team_stats = record.team_stats?.map((stat: any) => ({
|
||||
id: stat.id,
|
||||
team_id: stat.team_id,
|
||||
tournament_id: stat.tournament_id,
|
||||
team_name: stat.team_name,
|
||||
matches: stat.matches,
|
||||
wins: stat.wins,
|
||||
losses: stat.losses,
|
||||
total_cups_made: stat.total_cups_made,
|
||||
total_cups_against: stat.total_cups_against,
|
||||
margin_of_victory: stat.margin_of_victory,
|
||||
margin_of_loss: stat.margin_of_loss,
|
||||
win_percentage: (stat.wins / stat.matches) * 100,
|
||||
avg_cups_per_match: stat.total_cups_made / stat.matches,
|
||||
})) ?? [];
|
||||
|
||||
const nonByeMatches = matches.filter((match: any) => !(match.status === 'tbd' && match.bye === true));
|
||||
const isComplete = nonByeMatches.length > 0 && nonByeMatches.every((match: any) => match.status === 'ended');
|
||||
|
||||
let first_place: TeamInfo | undefined = undefined;
|
||||
let second_place: TeamInfo | undefined = undefined;
|
||||
let third_place: TeamInfo | undefined = undefined;
|
||||
|
||||
if (isComplete) {
|
||||
const teamMap = new Map<string, TeamInfo>(teams.map((team: any) => [team.id, team]));
|
||||
|
||||
const winnersMatches = matches.filter((match: any) => !match.is_losers_bracket);
|
||||
const finalsMatch = winnersMatches.reduce((highest: any, current: any) =>
|
||||
(!highest || current.lid > highest.lid) ? current : highest, null);
|
||||
|
||||
const losersMatches = matches.filter((match: any) => match.is_losers_bracket);
|
||||
const losersFinale = losersMatches.reduce((highest: any, current: any) =>
|
||||
(!highest || current.lid > highest.lid) ? current : highest, null);
|
||||
|
||||
if (finalsMatch && finalsMatch.status === 'ended') {
|
||||
const finalsWinner = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.home : finalsMatch.away;
|
||||
const finalsLoser = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.away : finalsMatch.home;
|
||||
|
||||
const finalsWinnerId = typeof finalsWinner === 'string' ? finalsWinner : finalsWinner?.id;
|
||||
const finalsLoserId = typeof finalsLoser === 'string' ? finalsLoser : finalsLoser?.id;
|
||||
|
||||
first_place = finalsWinnerId ? teamMap.get(finalsWinnerId) || undefined : undefined;
|
||||
second_place = finalsLoserId ? teamMap.get(finalsLoserId) || undefined : undefined;
|
||||
}
|
||||
|
||||
if (losersFinale && losersFinale.status === 'ended') {
|
||||
const losersFinaleLoser = (losersFinale.home_cups > losersFinale.away_cups) ? losersFinale.away : losersFinale.home;
|
||||
|
||||
const losersFinaleloserId = typeof losersFinaleLoser === 'string' ? losersFinaleLoser : losersFinaleLoser?.id;
|
||||
third_place = losersFinaleloserId ? teamMap.get(losersFinaleloserId) || undefined : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: record.id,
|
||||
name: record.name,
|
||||
@@ -163,7 +262,11 @@ export function transformTournament(record: any, isAdmin: boolean = false): Tour
|
||||
created: record.created,
|
||||
updated: record.updated,
|
||||
teams,
|
||||
matches
|
||||
matches,
|
||||
first_place,
|
||||
second_place,
|
||||
third_place,
|
||||
team_stats,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user