match h2h
This commit is contained in:
195
src/features/matches/components/team-head-to-head-sheet.tsx
Normal file
195
src/features/matches/components/team-head-to-head-sheet.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
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 { CrownIcon, TrophyIcon } from "@phosphor-icons/react";
|
||||
import MatchList from "./match-list";
|
||||
|
||||
interface TeamHeadToHeadSheetProps {
|
||||
team1: TeamInfo;
|
||||
team2: TeamInfo;
|
||||
}
|
||||
|
||||
const TeamHeadToHeadSheet = ({ team1, team2 }: TeamHeadToHeadSheetProps) => {
|
||||
const { data: matches, isLoading } = useTeamHeadToHead(team1.id, team2.id);
|
||||
|
||||
const stats = useMemo(() => {
|
||||
if (!matches || matches.length === 0) {
|
||||
return {
|
||||
team1Wins: 0,
|
||||
team2Wins: 0,
|
||||
team1CupsFor: 0,
|
||||
team2CupsFor: 0,
|
||||
team1CupsAgainst: 0,
|
||||
team2CupsAgainst: 0,
|
||||
team1AvgMargin: 0,
|
||||
team2AvgMargin: 0,
|
||||
};
|
||||
}
|
||||
|
||||
let team1Wins = 0;
|
||||
let team2Wins = 0;
|
||||
let team1CupsFor = 0;
|
||||
let team2CupsFor = 0;
|
||||
let team1CupsAgainst = 0;
|
||||
let team2CupsAgainst = 0;
|
||||
|
||||
matches.forEach((match) => {
|
||||
const isTeam1Home = match.home?.id === team1.id;
|
||||
const team1Cups = isTeam1Home ? match.home_cups : match.away_cups;
|
||||
const team2Cups = isTeam1Home ? match.away_cups : match.home_cups;
|
||||
|
||||
if (team1Cups > team2Cups) {
|
||||
team1Wins++;
|
||||
} else if (team2Cups > team1Cups) {
|
||||
team2Wins++;
|
||||
}
|
||||
|
||||
team1CupsFor += team1Cups;
|
||||
team2CupsFor += team2Cups;
|
||||
team1CupsAgainst += team2Cups;
|
||||
team2CupsAgainst += team1Cups;
|
||||
});
|
||||
|
||||
const team1AvgMargin = team1Wins > 0
|
||||
? (team1CupsFor - team1CupsAgainst) / team1Wins
|
||||
: 0;
|
||||
const team2AvgMargin = team2Wins > 0
|
||||
? (team2CupsFor - team2CupsAgainst) / team2Wins
|
||||
: 0;
|
||||
|
||||
return {
|
||||
team1Wins,
|
||||
team2Wins,
|
||||
team1CupsFor,
|
||||
team2CupsFor,
|
||||
team1CupsAgainst,
|
||||
team2CupsAgainst,
|
||||
team1AvgMargin,
|
||||
team2AvgMargin,
|
||||
};
|
||||
}, [matches, team1.id]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Stack p="md" gap="md">
|
||||
<Text size="sm" c="dimmed" ta="center">Loading...</Text>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
if (!matches || matches.length === 0) {
|
||||
return (
|
||||
<Stack p="md" gap="md">
|
||||
<Text size="sm" c="dimmed" ta="center">
|
||||
These teams have not faced each other yet.
|
||||
</Text>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
const totalGames = stats.team1Wins + stats.team2Wins;
|
||||
const leader = stats.team1Wins > stats.team2Wins ? team1 : stats.team2Wins > stats.team1Wins ? team2 : null;
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Paper p="md" withBorder radius="md">
|
||||
<Stack gap="sm">
|
||||
<Group justify="center" gap="xs">
|
||||
<Text size="lg" fw={700}>{team1.name}</Text>
|
||||
<Text size="sm" c="dimmed">vs</Text>
|
||||
<Text size="lg" fw={700}>{team2.name}</Text>
|
||||
</Group>
|
||||
|
||||
<Group justify="center" gap="lg">
|
||||
<Stack gap={0} align="center">
|
||||
<Text size="xl" fw={700}>{stats.team1Wins}</Text>
|
||||
<Text size="xs" c="dimmed">{team1.name}</Text>
|
||||
</Stack>
|
||||
<Text size="md" c="dimmed">-</Text>
|
||||
<Stack gap={0} align="center">
|
||||
<Text size="xl" fw={700}>{stats.team2Wins}</Text>
|
||||
<Text size="xs" c="dimmed">{team2.name}</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
|
||||
{leader && (
|
||||
<Group justify="center" gap="xs">
|
||||
<CrownIcon size={16} weight="fill" color="gold" />
|
||||
<Text size="xs" c="dimmed">
|
||||
{leader.name} leads the series
|
||||
</Text>
|
||||
</Group>
|
||||
)}
|
||||
|
||||
{!leader && totalGames > 0 && (
|
||||
<Text size="xs" c="dimmed" ta="center">
|
||||
Series is tied
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
<Stack gap={0}>
|
||||
<Text size="sm" fw={600} px="md" mb="xs">Stats Comparison</Text>
|
||||
|
||||
<Paper withBorder>
|
||||
<Stack gap={0}>
|
||||
<Group justify="space-between" px="md" py="sm">
|
||||
<Group gap="xs">
|
||||
<Text size="sm" fw={600}>{stats.team1CupsFor}</Text>
|
||||
<Text size="xs" c="dimmed">cups</Text>
|
||||
</Group>
|
||||
<Text size="xs" fw={500}>Total Cups</Text>
|
||||
<Group gap="xs">
|
||||
<Text size="xs" c="dimmed">cups</Text>
|
||||
<Text size="sm" fw={600}>{stats.team2CupsFor}</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
<Divider />
|
||||
|
||||
<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'}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed">avg</Text>
|
||||
</Group>
|
||||
<Text size="xs" fw={500}>Avg Cups/Game</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'}
|
||||
</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
<Divider />
|
||||
|
||||
<Group justify="space-between" px="md" py="sm">
|
||||
<Group gap="xs">
|
||||
<Text size="sm" fw={600}>
|
||||
{!isNaN(stats.team1AvgMargin) ? stats.team1AvgMargin.toFixed(1) : '0.0'}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed">margin</Text>
|
||||
</Group>
|
||||
<Text size="xs" fw={500}>Avg Win Margin</Text>
|
||||
<Group gap="xs">
|
||||
<Text size="xs" c="dimmed">margin</Text>
|
||||
<Text size="sm" fw={600}>
|
||||
{!isNaN(stats.team2AvgMargin) ? stats.team2AvgMargin.toFixed(1) : '0.0'}
|
||||
</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
|
||||
<Stack gap="xs">
|
||||
<Text size="sm" fw={600} px="md">Match History ({totalGames} games)</Text>
|
||||
<MatchList matches={matches} hideH2H />
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default TeamHeadToHeadSheet;
|
||||
Reference in New Issue
Block a user