player h2h

This commit is contained in:
yohlo
2025-10-11 14:47:03 -05:00
parent 43972b6a06
commit d3379e54a4
11 changed files with 671 additions and 36 deletions

View File

@@ -257,7 +257,7 @@ const MatchCard = ({ match, hideH2H = false }: MatchCardProps) => {
title="Head to Head"
{...h2hSheet.props}
>
<TeamHeadToHeadSheet team1={match.home} team2={match.away} />
<TeamHeadToHeadSheet team1={match.home} team2={match.away} isOpen={h2hSheet.props.opened} />
</Sheet>
)}
</>

View File

@@ -1,17 +1,26 @@
import { Stack, Text, Group, Box, Divider, Paper } from "@mantine/core";
import { TeamInfo } from "@/features/teams/types";
import { useTeamHeadToHead } from "../queries";
import { useMemo } from "react";
import { useMemo, useEffect, useState } from "react";
import { CrownIcon, TrophyIcon } from "@phosphor-icons/react";
import MatchList from "./match-list";
interface TeamHeadToHeadSheetProps {
team1: TeamInfo;
team2: TeamInfo;
isOpen?: boolean;
}
const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
const { data: matches, isLoading } = useTeamHeadToHead(team1.id, team2.id);
const TeamHeadToHeadSheet = ({ team1, team2, isOpen = true }: TeamHeadToHeadSheetProps) => {
const [shouldFetch, setShouldFetch] = useState(false);
useEffect(() => {
if (isOpen && !shouldFetch) {
setShouldFetch(true);
}
}, [isOpen, shouldFetch]);
const { data: matches, isLoading } = useTeamHeadToHead(team1.id, team2.id, shouldFetch);
const stats = useMemo(() => {
if (!matches || matches.length === 0) {
@@ -33,6 +42,8 @@ const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
let team2CupsFor = 0;
let team1CupsAgainst = 0;
let team2CupsAgainst = 0;
let team1TotalWinMargin = 0;
let team2TotalWinMargin = 0;
matches.forEach((match) => {
const isTeam1Home = match.home?.id === team1.id;
@@ -41,8 +52,10 @@ const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
if (team1Cups > team2Cups) {
team1Wins++;
team1TotalWinMargin += (team1Cups - team2Cups);
} else if (team2Cups > team1Cups) {
team2Wins++;
team2TotalWinMargin += (team2Cups - team1Cups);
}
team1CupsFor += team1Cups;
@@ -52,10 +65,10 @@ const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
});
const team1AvgMargin = team1Wins > 0
? (team1CupsFor - team1CupsAgainst) / team1Wins
? team1TotalWinMargin / team1Wins
: 0;
const team2AvgMargin = team2Wins > 0
? (team2CupsFor - team2CupsAgainst) / team2Wins
? team2TotalWinMargin / team2Wins
: 0;
return {
@@ -88,7 +101,7 @@ const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
);
}
const totalGames = stats.team1Wins + stats.team2Wins;
const totalMatches = stats.team1Wins + stats.team2Wins;
const leader = stats.team1Wins > stats.team2Wins ? team1 : stats.team2Wins > stats.team1Wins ? team2 : null;
return (
@@ -122,7 +135,7 @@ const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
</Group>
)}
{!leader && totalGames > 0 && (
{!leader && totalMatches > 0 && (
<Text size="xs" c="dimmed" ta="center">
Series is tied
</Text>
@@ -151,15 +164,15 @@ const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
<Group justify="space-between" px="md" py="sm">
<Group gap="xs">
<Text size="sm" fw={600}>
{totalGames > 0 ? (stats.team1CupsFor / totalGames).toFixed(1) : '0.0'}
{totalMatches > 0 ? (stats.team1CupsFor / totalMatches).toFixed(1) : '0.0'}
</Text>
<Text size="xs" c="dimmed">avg</Text>
</Group>
<Text size="xs" fw={500}>Avg Cups/Game</Text>
<Text size="xs" fw={500}>Avg Cups/Match</Text>
<Group gap="xs">
<Text size="xs" c="dimmed">avg</Text>
<Text size="sm" fw={600}>
{totalGames > 0 ? (stats.team2CupsFor / totalGames).toFixed(1) : '0.0'}
{totalMatches > 0 ? (stats.team2CupsFor / totalMatches).toFixed(1) : '0.0'}
</Text>
</Group>
</Group>
@@ -185,7 +198,7 @@ const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
</Stack>
<Stack gap="xs">
<Text size="sm" fw={600} px="md">Match History ({totalGames} games)</Text>
<Text size="sm" fw={600} px="md">Match History ({totalMatches} match{totalMatches !== 1 ? 'es' : ''})</Text>
<MatchList matches={matches} hideH2H />
</Stack>
</Stack>

View File

@@ -17,8 +17,14 @@ export const matchQueries = {
}),
};
export const useTeamHeadToHead = (team1Id: string, team2Id: string) =>
useServerQuery(matchQueries.headToHeadTeams(team1Id, team2Id));
export const useTeamHeadToHead = (team1Id: string, team2Id: string, enabled = true) =>
useServerQuery({
...matchQueries.headToHeadTeams(team1Id, team2Id),
enabled,
});
export const usePlayerHeadToHead = (player1Id: string, player2Id: string) =>
useServerQuery(matchQueries.headToHeadPlayers(player1Id, player2Id));
export const usePlayerHeadToHead = (player1Id: string, player2Id: string, enabled = true) =>
useServerQuery({
...matchQueries.headToHeadPlayers(player1Id, player2Id),
enabled,
});