predictions

This commit is contained in:
yohlo
2026-07-14 14:15:34 -07:00
parent e6c72a5789
commit 1783f0e6bc
28 changed files with 2085 additions and 89 deletions
@@ -5,6 +5,10 @@ import { Box, Divider, Stack, Text, Card, Center } from "@mantine/core";
import { Carousel } from "@mantine/carousel";
import ListLink from "@/components/list-link";
import { TreeStructureIcon, UsersIcon, ClockIcon, ListDashes } from "@phosphor-icons/react";
import WizardOrbIcon from "@/components/wizard-orb-icon";
import { isPredictionLocked, isTournamentPredictable } from "@/features/predictions/utils";
import { predictionQueries } from "@/features/predictions/queries";
import { useServerQuery } from "@/lib/tanstack-query/hooks";
import TeamListButton from "../upcoming-tournament/team-list-button";
import RulesListButton from "../upcoming-tournament/rules-list-button";
import MatchCard from "@/features/matches/components/match-card";
@@ -41,6 +45,22 @@ const StartedTournament: React.FC<{ tournament: Tournament }> = ({
return tournament.matches?.some((match) => match.round === -1) || false;
}, [tournament.matches]);
const isPredictable = useMemo(
() => isTournamentPredictable(tournament),
[tournament]
);
const predictionsLocked = useMemo(
() => isPredictionLocked(tournament.matches || []),
[tournament.matches]
);
const { data: myPrediction } = useServerQuery({
...predictionQueries.mine(tournament.id),
options: { enabled: isPredictable && !predictionsLocked },
});
const hasSubmitted = !!myPrediction?.prediction;
return (
<Stack gap="lg">
<Header tournament={tournament} />
@@ -99,6 +119,20 @@ const StartedTournament: React.FC<{ tournament: Tournament }> = ({
to={`/tournaments/${tournament.id}/bracket`}
Icon={TreeStructureIcon}
/>
{isPredictable && !predictionsLocked && (
<ListLink
label={hasSubmitted ? `Edit Your Prediction` : `Make Your Prediction`}
to={`/tournaments/${tournament.id}/predictions/make`}
Icon={WizardOrbIcon}
/>
)}
{isPredictable && (predictionsLocked || hasSubmitted) && (
<ListLink
label={`View Predictions`}
to={`/tournaments/${tournament.id}/predictions`}
Icon={WizardOrbIcon}
/>
)}
<TeamListButton teams={tournament.teams || []} isRegional={tournament.regional} />
<RulesListButton tournamentId={tournament.id} />
</Box>
@@ -13,8 +13,10 @@ import {
} from "@mantine/core";
import { Tournament } from "@/features/tournaments/types";
import { CrownIcon, TreeStructureIcon, InfoIcon, ListDashes } from "@phosphor-icons/react";
import WizardOrbIcon from "@/components/wizard-orb-icon";
import TeamAvatar from "@/components/team-avatar";
import ListLink from "@/components/list-link";
import { isTournamentPredictable } from "@/features/predictions/utils";
import { Podium } from "./podium";
interface TournamentStatsProps {
@@ -185,6 +187,13 @@ export const TournamentStats = memo(({ tournament }: TournamentStatsProps) => {
to={`/tournaments/${tournament.id}/bracket`}
Icon={TreeStructureIcon}
/>
{isTournamentPredictable(tournament) && (
<ListLink
label={`View Predictions`}
to={`/tournaments/${tournament.id}/predictions`}
Icon={WizardOrbIcon}
/>
)}
{renderTeamStatsTable()}
</Stack>
</Container>